Backed out changeset 7272b7396c78 (bug 1932758) for causing fenix debug failures...
[gecko.git] / dom / canvas / test / webgl-conf / checkout / deqp / functional / gles3 / es3fTextureSpecificationTests.js
blob5ff5edc550e2eed712b80527462948b0c4da23d9
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES Utilities
3  * ------------------------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the 'License');
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an 'AS IS' BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
21 'use strict';
22 goog.provide('functional.gles3.es3fTextureSpecificationTests');
23 goog.require('framework.common.tcuImageCompare');
24 goog.require('framework.common.tcuLogImage');
25 goog.require('framework.common.tcuPixelFormat');
26 goog.require('framework.common.tcuSurface');
27 goog.require('framework.common.tcuTestCase');
28 goog.require('framework.common.tcuTexture');
29 goog.require('framework.common.tcuTextureUtil');
30 goog.require('framework.delibs.debase.deMath');
31 goog.require('framework.delibs.debase.deRandom');
32 goog.require('framework.delibs.debase.deString');
33 goog.require('framework.opengl.gluShaderUtil');
34 goog.require('framework.opengl.gluTextureUtil');
35 goog.require('framework.opengl.simplereference.sglrGLContext');
36 goog.require('framework.opengl.simplereference.sglrReferenceContext');
37 goog.require('framework.referencerenderer.rrUtil');
38 goog.require('functional.gles3.es3fFboTestUtil');
40 goog.scope(function() {
41     var es3fTextureSpecificationTests =
42         functional.gles3.es3fTextureSpecificationTests;
43     var tcuPixelFormat = framework.common.tcuPixelFormat;
44     var tcuImageCompare = framework.common.tcuImageCompare;
45     var tcuSurface = framework.common.tcuSurface;
46     var tcuTestCase = framework.common.tcuTestCase;
47     var tcuTexture = framework.common.tcuTexture;
48     var tcuTextureUtil = framework.common.tcuTextureUtil;
49     var deMath = framework.delibs.debase.deMath;
50     var deRandom = framework.delibs.debase.deRandom;
51     var deString = framework.delibs.debase.deString;
52     var gluShaderUtil = framework.opengl.gluShaderUtil;
53     var gluTextureUtil = framework.opengl.gluTextureUtil;
54     var sglrGLContext = framework.opengl.simplereference.sglrGLContext;
55     var sglrReferenceContext =
56         framework.opengl.simplereference.sglrReferenceContext;
57     var rrUtil = framework.referencerenderer.rrUtil;
58     var es3fFboTestUtil = functional.gles3.es3fFboTestUtil;
59     var tcuLogImage = framework.common.tcuLogImage;
61     /**
62      * @param {number} internalFormat
63      * @return {tcuTexture.TextureFormat}
64      */
65     es3fTextureSpecificationTests.mapGLUnsizedInternalFormat = function(
66         internalFormat
67     ) {
68         switch (internalFormat) {
69             case gl.ALPHA:
70                 return new tcuTexture.TextureFormat(
71                     tcuTexture.ChannelOrder.A,
72                     tcuTexture.ChannelType.UNORM_INT8
73                 );
74             case gl.LUMINANCE:
75                 return new tcuTexture.TextureFormat(
76                     tcuTexture.ChannelOrder.L,
77                     tcuTexture.ChannelType.UNORM_INT8
78                 );
79             case gl.LUMINANCE_ALPHA:
80                 return new tcuTexture.TextureFormat(
81                     tcuTexture.ChannelOrder.LA,
82                     tcuTexture.ChannelType.UNORM_INT8
83                 );
84             case gl.RGB:
85                 return new tcuTexture.TextureFormat(
86                     tcuTexture.ChannelOrder.RGB,
87                     tcuTexture.ChannelType.UNORM_INT8
88                 );
89             case gl.RGBA:
90                 return new tcuTexture.TextureFormat(
91                     tcuTexture.ChannelOrder.RGBA,
92                     tcuTexture.ChannelType.UNORM_INT8
93                 );
94             default:
95                 throw new Error(
96                     'Can\'t map GL unsized internal format (' +
97                     internalFormat.toString(16) + ') to texture format'
98                 );
99         }
100     };
102     var VIEWPORT_WIDTH = 256;
103     var VIEWPORT_HEIGHT = 256;
105     /**
106      * @param {number} width
107      * @param {number} height
108      * @param {number=} depth
109      * @return {number}
110      */
111     es3fTextureSpecificationTests.maxLevelCount = function(
112         width, height, depth
113     ) {
114         depth = depth || 0;
115         return deMath.logToFloor(Math.max(width, Math.max(height, depth))) + 1;
116     };
118     /**
119      * @param {deRandom.Random} rnd
120      * @param {Array<number>} minVal
121      * @param {Array<number>} maxVal
122      * @param {number} size
123      * @return {Array<number>}
124      */
125     es3fTextureSpecificationTests.randomVector = function(
126         rnd, minVal, maxVal, size
127     ) {
128         var res = [];
129         for (var ndx = 0; ndx < size; ndx++)
130             res[ndx] = rnd.getFloat(minVal[ndx], maxVal[ndx]);
131         return res;
132     };
134     /**
135      * @param {tcuPixelFormat.PixelFormat} pixelFormat
136      * @param {tcuTexture.TextureFormat} textureFormat
137      * @return {Array<number>} (ivec4)
138      */
139     es3fTextureSpecificationTests.getPixelFormatCompareDepth = function(
140         pixelFormat, textureFormat
141     ) {
142         switch (textureFormat.order) {
143             case tcuTexture.ChannelOrder.L:
144             case tcuTexture.ChannelOrder.LA:
145                 return [
146                     pixelFormat.redBits, pixelFormat.redBits,
147                     pixelFormat.redBits, pixelFormat.alphaBits
148                 ];
149             default:
150                 return [
151                     pixelFormat.redBits, pixelFormat.greenBits,
152                     pixelFormat.blueBits, pixelFormat.alphaBits
153                 ];
154         }
155     };
157     /**
158      * @param {tcuPixelFormat.PixelFormat} pixelFormat
159      * @param {tcuTexture.TextureFormat} textureFormat
160      * @return {Array<number>} (uvec4)
161      */
162     es3fTextureSpecificationTests.computeCompareThreshold = function(
163         pixelFormat, textureFormat
164     ) {
165         /** @type {Array<number>} */
166         var texFormatBits = tcuTextureUtil.getTextureFormatBitDepth(
167             textureFormat
168         );
169         /** @type {Array<number>} */
170         var pixelFormatBits =
171             es3fTextureSpecificationTests.getPixelFormatCompareDepth(
172                 pixelFormat, textureFormat
173             );
174         /** @type {Array<number>} */
175         var accurateFmtBits = deMath.min(pixelFormatBits, texFormatBits);
176         /** @type {Array<number>} */
177         var compareBits = deMath.addScalar(
178             tcuTextureUtil.select(
179                 accurateFmtBits, [8, 8, 8, 8],
180                 deMath.greaterThan(accurateFmtBits, [0, 0, 0, 0])
181             ), - 1
182         );
184         var result = [];
185         for (var i = 0; i < compareBits.length; i++)
186             result.push(1 << compareBits[i]);
187         return result;
188     };
190     /**
191      * @constructor
192      * @extends {tcuTestCase.DeqpTest}
193      * @param {string} name
194      * @param {string} desc
195      * context
196      */
197     es3fTextureSpecificationTests.TextureSpecCase = function(name, desc) {
198         tcuTestCase.DeqpTest.call(this, name, desc);
199         /**
200          * @type {
201          *     ?sglrGLContext.GLContext|sglrReferenceContext.ReferenceContext
202          * }
203          */
204          this.m_context = null;
205     };
207     es3fTextureSpecificationTests.TextureSpecCase.prototype = Object.create(
208         tcuTestCase.DeqpTest.prototype
209     );
211     es3fTextureSpecificationTests.TextureSpecCase.prototype.constructor =
212         es3fTextureSpecificationTests.TextureSpecCase;
214     /**
215      * deinit
216      */
217     es3fTextureSpecificationTests.TextureSpecCase.prototype.deinit =
218     function() {
219         gl.pixelStorei(gl.UNPACK_ALIGNMENT, 4);
220         gl.pixelStorei(gl.UNPACK_ROW_LENGTH, 0);
221         gl.pixelStorei(gl.UNPACK_IMAGE_HEIGHT, 0);
222         gl.pixelStorei(gl.UNPACK_SKIP_PIXELS, 0);
223         gl.pixelStorei(gl.UNPACK_SKIP_ROWS, 0);
224         gl.pixelStorei(gl.UNPACK_SKIP_IMAGES, 0);
226         gl.bindBuffer(gl.PIXEL_UNPACK_BUFFER, null);
227     }
229     /**
230      * createTexture - Needs to be overridden
231      */
232     es3fTextureSpecificationTests.TextureSpecCase.prototype.createTexture =
233     function() {
234         throw new Error('Must override');
235     };
237     /**
238      * verifyTexture - Needs to be overridden
239      * @param {sglrGLContext.GLContext} webgl2Context
240      * @param {sglrReferenceContext.ReferenceContext} refContext
241      * @return {boolean}
242      */
243     es3fTextureSpecificationTests.TextureSpecCase.prototype.verifyTexture =
244     function(
245         webgl2Context, refContext
246     ) {
247         throw new Error('Must override');
248     };
250     /**
251      * @return {tcuTestCase.IterateResult}
252      */
253     es3fTextureSpecificationTests.TextureSpecCase.prototype.iterate = function() {
254         if (gl.canvas.width < VIEWPORT_WIDTH ||
255             gl.canvas.height < VIEWPORT_HEIGHT)
256             throw new Error('Too small viewport', '');
258         // Context size, and viewport for GLES3
259         var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
260         var width = Math.min(gl.canvas.width, VIEWPORT_WIDTH);
261         var height = Math.min(gl.canvas.height, VIEWPORT_HEIGHT);
262         var x = rnd.getInt(0, gl.canvas.width - width);
263         var y = rnd.getInt(0, gl.canvas.height - height);
265         // Contexts.
266         /** @type {sglrGLContext.GLContext} */
267         var webgl2Context = new sglrGLContext.GLContext(
268             gl, [x, y, width, height]
269         );
271         /** @type {sglrReferenceContext.ReferenceContextBuffers} */
272         var refBuffers = new sglrReferenceContext.ReferenceContextBuffers(
273             new tcuPixelFormat.PixelFormat(
274                 8, 8, 8, gl.getParameter(gl.ALPHA_BITS) ? 8 : 0
275             ), 0 /* depth */, 0 /* stencil */, width, height
276         );
278         /** @type {sglrReferenceContext.ReferenceContext} */
279         var refContext = new sglrReferenceContext.ReferenceContext(
280             new sglrReferenceContext.ReferenceContextLimits(gl),
281             refBuffers.getColorbuffer(), refBuffers.getDepthbuffer(),
282             refBuffers.getStencilbuffer()
283         );
285         // Clear color buffer.
286         for (var ndx = 0; ndx < 2; ndx++) {
287             this.m_context = ndx ? refContext : webgl2Context;
288             // C++ port uses (0.125, 0.25, 0.5, 1.0), but here we use (0, 0, 0, 0)
289             // in order to optimize the `clear' op in ReferenceContext.
290             this.m_context.clearColor(0, 0, 0, 0);
291             this.m_context.clear(
292                 gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT |
293                 gl.STENCIL_BUFFER_BIT
294             );
295         }
297         // Construct texture using both GLES3 and reference contexts.
298         for (var ndx = 0; ndx < 2; ndx++) {
299             this.m_context = ndx ? refContext : webgl2Context;
300             this.createTexture();
301             checkMessage(
302                 this.m_context.getError() == gl.NO_ERROR,
303                 'Problem creating texture.'
304             );
305         }
307         // Verify results.
308         if (this.verifyTexture(webgl2Context, refContext))
309             testPassed();
310         else
311             testFailed('Verification failed');
313         return tcuTestCase.IterateResult.STOP;
314     };
316     /**
317      * @param {tcuSurface.Surface} dst
318      * @param {
319      *  ?WebGLProgram|
320      *  framework.opengl.simplereference.sglrShaderProgram.ShaderProgram
321      * } program
322      * @param {number} width
323      * @param {number} height
324      */
325     es3fTextureSpecificationTests.TextureSpecCase.prototype.renderTex =
326     function(dst, program, width, height) {
327         var targetW = this.m_context.getWidth();
328         var targetH = this.m_context.getHeight();
330         var w = width / targetW;
331         var h = height / targetH;
333         rrUtil.drawQuad(
334             this.m_context, program, [-1.0, -1.0, 0.0],
335             [-1.0 + w * 2.0, -1.0 + h * 2.0, 0.0]
336         );
338         // Read pixels back.
339         dst.readViewport(this.m_context, [0, 0, width, height]);
340     };
342     /**
343      * @constructor
344      * @extends {es3fTextureSpecificationTests.TextureSpecCase}
345      * @param {string} name
346      * @param {string} desc
347      * @param {tcuTexture.TextureFormat} format
348      * @param {number} width
349      * @param {number} height
350      * @param {number} numLevels
351      */
352     es3fTextureSpecificationTests.Texture2DSpecCase = function(
353         name, desc, format, width, height, numLevels
354     ) {
355         es3fTextureSpecificationTests.TextureSpecCase.call(this, name, desc);
357         this.m_texFormat = format;
358         this.m_texFormatInfo = tcuTextureUtil.getTextureFormatInfo(format);
359         this.m_width = width;
360         this.m_height = height;
361         this.m_numLevels = numLevels;
362     };
364     es3fTextureSpecificationTests.Texture2DSpecCase.prototype = Object.create(
365         es3fTextureSpecificationTests.TextureSpecCase.prototype
366     );
368     es3fTextureSpecificationTests.Texture2DSpecCase.prototype.constructor =
369         es3fTextureSpecificationTests.Texture2DSpecCase;
371     /**
372      * @param {sglrGLContext.GLContext} webgl2Context
373      * @param {sglrReferenceContext.ReferenceContext} refContext
374      */
375     es3fTextureSpecificationTests.Texture2DSpecCase.prototype.verifyTexture =
376     function(
377         webgl2Context, refContext
378     ) {
379         /** @type {es3fFboTestUtil.Texture2DShader} */
380         var shader = new es3fFboTestUtil.Texture2DShader(
381             [gluTextureUtil.getSampler2DType(this.m_texFormat)],
382             gluShaderUtil.DataType.FLOAT_VEC4
383         );
385         var shaderIDgles = webgl2Context.createProgram(shader);
386         var shaderIDRef = refContext.createProgram(shader);
388         shader.setTexScaleBias(
389             0, this.m_texFormatInfo.lookupScale,
390             this.m_texFormatInfo.lookupBias
391         );
393         // Set state.
394         for (var ndx = 0; ndx < 2; ndx++) {
395             var ctx = ndx ? refContext : webgl2Context;
397             this.m_context = ctx;
399             this.m_context.texParameteri(
400                 gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_NEAREST
401             );
402             this.m_context.texParameteri(
403                 gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST
404             );
405             this.m_context.texParameteri(
406                 gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE
407             );
408             this.m_context.texParameteri(
409                 gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE
410             );
411             this.m_context.texParameteri(
412                 gl.TEXTURE_2D, gl.TEXTURE_MAX_LEVEL, this.m_numLevels - 1
413             );
414         }
416         for (var levelNdx = 0; levelNdx < this.m_numLevels; levelNdx++) {
417             var levelW = Math.max(1, this.m_width >> levelNdx);
418             var levelH = Math.max(1, this.m_height >> levelNdx);
419             /** @type {tcuSurface.Surface} */ var reference = new tcuSurface.Surface();
420             /** @type {tcuSurface.Surface} */ var result = new tcuSurface.Surface();
422             for (var ndx = 0; ndx < 2; ndx++) {
423                 /** @type {tcuSurface.Surface} */
424                 var dst = ndx ? reference : result;
425                 var ctx = ndx ? refContext : webgl2Context;
426                 var shaderID = ndx ? shaderIDRef : shaderIDgles;
428                 this.m_context = ctx;
429                 shader.setUniforms(ctx, shaderID);
430                 this.renderTex(dst, shaderID, levelW, levelH);
431             }
433             var threshold =
434             es3fTextureSpecificationTests.computeCompareThreshold(
435                 tcuPixelFormat.PixelFormatFromContext(gl), this.m_texFormat
436             );
437             var levelStr = levelNdx.toString();
438             var name = 'Level' + levelStr;
439             var desc = 'Level ' + levelStr;
440             var isOk = tcuImageCompare.intThresholdCompare(
441                 name, desc, reference.getAccess(), result.getAccess(),
442                 threshold, levelNdx == 0 ?
443                 tcuImageCompare.CompareLogMode.RESULT :
444                 tcuImageCompare.CompareLogMode.ON_ERROR
445             );
447             if (!isOk) {
448                 testFailed('Image comparison failed');
449                 return false;
450             } else {
451                 // tcuLogImage.logImageWithInfo(result.getAccess(),'Comparison OK on level: ' + levelNdx);
452             }
453         }
454         return true;
455     };
457     /**
458      * @constructor
459      * @extends {es3fTextureSpecificationTests.TextureSpecCase}
460      * @param {string} name
461      * @param {string} desc
462      * @param {tcuTexture.TextureFormat} format
463      * @param {number} size
464      * @param {number} numLevels
465      */
466     es3fTextureSpecificationTests.TextureCubeSpecCase = function(
467         name, desc, format, size, numLevels
468     ) {
469         es3fTextureSpecificationTests.TextureSpecCase.call(
470             this, name, desc
471         );
472         this.m_texFormat = format;
473         this.m_texFormatInfo = tcuTextureUtil.getTextureFormatInfo(format);
474         this.m_size = size;
475         this.m_numLevels = numLevels;
476     };
478     es3fTextureSpecificationTests.TextureCubeSpecCase.prototype =
479         Object.create(es3fTextureSpecificationTests.TextureSpecCase.prototype);
481     es3fTextureSpecificationTests.TextureCubeSpecCase.prototype.constructor =
482         es3fTextureSpecificationTests.TextureCubeSpecCase;
484     /**
485      * @param {sglrGLContext.GLContext} webgl2Context
486      * @param {sglrReferenceContext.ReferenceContext} refContext
487      */
488     es3fTextureSpecificationTests.TextureCubeSpecCase.prototype.verifyTexture =
489     function(
490         webgl2Context, refContext
491     ) {
492         /** @type {es3fFboTestUtil.TextureCubeShader} */
493         var shader = new es3fFboTestUtil.TextureCubeShader(
494             gluTextureUtil.getSamplerCubeType(this.m_texFormat),
495             gluShaderUtil.DataType.FLOAT_VEC4
496         );
497         var shaderIDgles = webgl2Context.createProgram(shader);
498         var shaderIDRef = refContext.createProgram(shader);
500         shader.setTexScaleBias(
501             this.m_texFormatInfo.lookupScale, this.m_texFormatInfo.lookupBias
502         );
504         // Set state.
505         for (var ndx = 0; ndx < 2; ndx++) {
506             var ctx = ndx ? refContext : webgl2Context;
508             this.m_context = ctx;
510             this.m_context.texParameteri(
511                 gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER,
512                 gl.NEAREST_MIPMAP_NEAREST
513             );
514             this.m_context.texParameteri(
515                 gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER,
516                 gl.NEAREST
517             );
518             this.m_context.texParameteri(
519                 gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S,
520                 gl.CLAMP_TO_EDGE
521             );
522             this.m_context.texParameteri(
523                 gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T,
524                 gl.CLAMP_TO_EDGE
525             );
526             this.m_context.texParameteri(
527                 gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAX_LEVEL,
528                 this.m_numLevels - 1
529             );
530         }
532         for (var levelNdx = 0; levelNdx < this.m_numLevels; levelNdx++) {
533             var levelSize = Math.max(1, this.m_size >> levelNdx);
534             var isOk = true;
536             for (var f in tcuTexture.CubeFace) {
537                 var face = tcuTexture.CubeFace[f];
538                 /** @type {tcuSurface.Surface} */
539                 var reference = new tcuSurface.Surface();
540                 /** @type {tcuSurface.Surface} */
541                 var result = new tcuSurface.Surface();
543                 if (levelSize <= 2)
544                     continue; // Fuzzy compare doesn't work for images this small.
546                 shader.setFace(face);
548                 for (var ndx = 0; ndx < 2; ndx++) {
549                     /** @type {tcuSurface.Surface} */
550                     var dst = ndx ? reference : result;
551                     ctx = ndx ? refContext : webgl2Context;
552                     var shaderID = ndx ? shaderIDRef : shaderIDgles;
554                     this.m_context = ctx;
555                     shader.setUniforms(ctx, shaderID);
556                     this.renderTex(dst, shaderID, levelSize, levelSize);
557                 }
559                 var threshold = 0.02;
560                 var faceStr = face.toString();
561                 var levelStr = levelNdx.toString();
562                 var name = 'Level' + levelStr;
563                 var desc = 'Level ' + levelStr + ', face ' + faceStr;
564                 var isFaceOk = tcuImageCompare.fuzzyCompare(
565                     name, desc, reference.getAccess(), result.getAccess(),
566                     threshold, levelNdx == 0 ?
567                     tcuImageCompare.CompareLogMode.RESULT :
568                     tcuImageCompare.CompareLogMode.ON_ERROR
569                 );
571                 if (!isFaceOk) {
572                     testFailed('Image comparison failed');
573                     return false;
574                 }
575             }
577         }
578         return true;
579     };
581     /**
582      * @constructor
583      * @extends {es3fTextureSpecificationTests.TextureSpecCase}
584      * @param {string} name
585      * @param {string} desc
586      * @param {tcuTexture.TextureFormat} format
587      * @param {number} width
588      * @param {number} height
589      * @param {number} numLayers
590      * @param {number} numLevels
591      */
592     es3fTextureSpecificationTests.Texture2DArraySpecCase = function(
593         name, desc, format, width, height, numLayers, numLevels
594     ) {
595         es3fTextureSpecificationTests.TextureSpecCase.call(
596             this, name, desc
597         );
598         this.m_texFormat = format;
599         this.m_texFormatInfo = tcuTextureUtil.getTextureFormatInfo(format);
600         this.m_width = width;
601         this.m_height = height;
602         this.m_numLayers = numLayers;
603         this.m_numLevels = numLevels;
604     };
606     es3fTextureSpecificationTests.Texture2DArraySpecCase.prototype =
607         Object.create(es3fTextureSpecificationTests.TextureSpecCase.prototype);
609     es3fTextureSpecificationTests.Texture2DArraySpecCase.prototype.constructor =
610         es3fTextureSpecificationTests.Texture2DArraySpecCase;
612     /**
613      * @param {sglrGLContext.GLContext} webgl2Context
614      * @param {sglrReferenceContext.ReferenceContext} refContext
615      */
616     es3fTextureSpecificationTests.Texture2DArraySpecCase.prototype.verifyTexture =
617     function(
618         webgl2Context, refContext
619     ) {
620         /** @type {es3fFboTestUtil.Texture2DArrayShader} */
621         var shader = new es3fFboTestUtil.Texture2DArrayShader(
622             gluTextureUtil.getSampler2DArrayType(this.m_texFormat),
623             gluShaderUtil.DataType.FLOAT_VEC4
624         );
625         var shaderIDgles = webgl2Context.createProgram(shader);
626         var shaderIDRef = refContext.createProgram(shader);
628         shader.setTexScaleBias(
629             this.m_texFormatInfo.lookupScale, this.m_texFormatInfo.lookupBias
630         );
632         // Set state.
633         for (var ndx = 0; ndx < 2; ndx++) {
634             var ctx = ndx ? refContext : webgl2Context;
636             this.m_context = ctx;
638             this.m_context.texParameteri(
639                 gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MIN_FILTER,
640                 gl.NEAREST_MIPMAP_NEAREST
641             );
642             this.m_context.texParameteri(
643                 gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MAG_FILTER,
644                 gl.NEAREST
645             );
646             this.m_context.texParameteri(
647                 gl.TEXTURE_2D_ARRAY, gl.TEXTURE_WRAP_S,
648                 gl.CLAMP_TO_EDGE
649             );
650             this.m_context.texParameteri(
651                 gl.TEXTURE_2D_ARRAY, gl.TEXTURE_WRAP_T,
652                 gl.CLAMP_TO_EDGE
653             );
654             this.m_context.texParameteri(
655                 gl.TEXTURE_2D_ARRAY, gl.TEXTURE_WRAP_R,
656                 gl.CLAMP_TO_EDGE
657             );
658             this.m_context.texParameteri(
659                 gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MAX_LEVEL,
660                 this.m_numLevels - 1
661             );
662         }
664         for (var layerNdx = 0; layerNdx < this.m_numLayers; layerNdx++) {
665             var layerOk = true;
667             shader.setLayer(layerNdx);
668             for (var levelNdx = 0; levelNdx < this.m_numLevels; levelNdx++) {
669                 var levelW = Math.max(1, this.m_width >> levelNdx);
670                 var levelH = Math.max(1, this.m_height >> levelNdx);
672                 if (levelW == 1 || levelH == 1) {
673                     // Rendering to texture of size x1 is problematic in referencerenderer
674                     // due to its deviation from c++ code: crbug.com/613206
675                     continue;
676                 }
677                 /** @type {tcuSurface.Surface} */
678                 var reference = new tcuSurface.Surface();
679                 /** @type {tcuSurface.Surface} */
680                 var result = new tcuSurface.Surface();
682                 var isOk = true;
684                 for (var ndx = 0; ndx < 2; ndx++) {
685                     /** @type {tcuSurface.Surface} */
686                     var dst = ndx ? reference : result;
687                     ctx = ndx ? refContext : webgl2Context;
688                     var shaderID = ndx ? shaderIDRef : shaderIDgles;
690                     this.m_context = ctx;
691                     shader.setUniforms(ctx, shaderID);
692                     this.renderTex(dst, shaderID, levelW, levelH);
693                 }
695                 var threshold =
696                 es3fTextureSpecificationTests.computeCompareThreshold(
697                     tcuPixelFormat.PixelFormatFromContext(gl), this.m_texFormat
698                 );
699                 var levelStr = levelNdx.toString();
700                 var layerStr = layerNdx.toString();
701                 var name = 'Layer' + layerStr + 'Level' + levelStr;
702                 var desc = 'Layer ' + layerStr + ', Level ' + levelStr;
703                 var depthOk = tcuImageCompare.intThresholdCompare(
704                     name, desc, reference.getAccess(), result.getAccess(),
705                     threshold, (levelNdx == 0 && layerNdx == 0) ?
706                     tcuImageCompare.CompareLogMode.RESULT :
707                     tcuImageCompare.CompareLogMode.ON_ERROR
708                 );
710                 if (!depthOk) {
711                     testFailed('Image comparison failed');
712                     return false;
713                 }
714             }
716         }
717         return true;
718     };
720     /**
721      * @constructor
722      * @extends {es3fTextureSpecificationTests.TextureSpecCase}
723      * @param {string} name
724      * @param {string} desc
725      * @param {tcuTexture.TextureFormat} format
726      * @param {number} width
727      * @param {number} height
728      * @param {number} depth
729      * @param {number} numLevels
730      */
731     es3fTextureSpecificationTests.Texture3DSpecCase = function(
732         name, desc, format, width, height, depth, numLevels
733     ) {
734         es3fTextureSpecificationTests.TextureSpecCase.call(
735             this, name, desc
736         );
737         this.m_texFormat = format;
738         this.m_texFormatInfo = tcuTextureUtil.getTextureFormatInfo(format);
739         this.m_width = width;
740         this.m_height = height;
741         this.m_depth = depth;
742         this.m_numLevels = numLevels;
743     };
745     es3fTextureSpecificationTests.Texture3DSpecCase.prototype =
746         Object.create(es3fTextureSpecificationTests.TextureSpecCase.prototype);
748     es3fTextureSpecificationTests.Texture3DSpecCase.prototype.constructor =
749         es3fTextureSpecificationTests.Texture3DSpecCase;
751     /**
752      * @param {sglrGLContext.GLContext} webgl2Context
753      * @param {sglrReferenceContext.ReferenceContext} refContext
754      */
755     es3fTextureSpecificationTests.Texture3DSpecCase.prototype.verifyTexture =
756     function(
757         webgl2Context, refContext
758     ) {
759         /** @type {es3fFboTestUtil.Texture3DShader} */
760         var shader = new es3fFboTestUtil.Texture3DShader(
761             gluTextureUtil.getSampler3D(this.m_texFormat),
762             gluShaderUtil.DataType.FLOAT_VEC4
763         );
764         var shaderIDgles = webgl2Context.createProgram(shader);
765         var shaderIDRef = refContext.createProgram(shader);
767         shader.setTexScaleBias(
768             this.m_texFormatInfo.lookupScale, this.m_texFormatInfo.lookupBias
769         );
771         // Set state.
772         for (var ndx = 0; ndx < 2; ndx++) {
773             var ctx = ndx ? refContext : webgl2Context;
775             this.m_context = ctx;
777             this.m_context.texParameteri(
778                 gl.TEXTURE_3D, gl.TEXTURE_MIN_FILTER,
779                 gl.NEAREST_MIPMAP_NEAREST
780             );
781             this.m_context.texParameteri(
782                 gl.TEXTURE_3D, gl.TEXTURE_MAG_FILTER,
783                 gl.NEAREST
784             );
785             this.m_context.texParameteri(
786                 gl.TEXTURE_3D, gl.TEXTURE_WRAP_S,
787                 gl.CLAMP_TO_EDGE
788             );
789             this.m_context.texParameteri(
790                 gl.TEXTURE_3D, gl.TEXTURE_WRAP_T,
791                 gl.CLAMP_TO_EDGE
792             );
793             this.m_context.texParameteri(
794                 gl.TEXTURE_3D, gl.TEXTURE_WRAP_R,
795                 gl.CLAMP_TO_EDGE
796             );
797             this.m_context.texParameteri(
798                 gl.TEXTURE_3D, gl.TEXTURE_MAX_LEVEL,
799                 this.m_numLevels - 1
800             );
801         }
803         for (var levelNdx = 0; levelNdx < this.m_numLevels; levelNdx++) {
804             var levelW = Math.max(1, this.m_width >> levelNdx);
805             var levelH = Math.max(1, this.m_height >> levelNdx);
806             var levelD = Math.max(1, this.m_depth >> levelNdx);
807             var levelOk = true;
809             if (levelW == 1 || levelH == 1) {
810                 // Rendering to texture of size x1 is problematic in referencerenderer
811                 // due to its deviation from c++ code: crbug.com/613206
812                 continue;
813             }
815             for (var depth = 0; depth < levelD; depth++) {
816                 /** @type {tcuSurface.Surface} */
817                 var reference = new tcuSurface.Surface();
818                 /** @type {tcuSurface.Surface} */
819                 var result = new tcuSurface.Surface();
821                 shader.setDepth((depth + 0.5) / levelD);
823                 for (var ndx = 0; ndx < 2; ndx++) {
824                     /** @type {tcuSurface.Surface} */
825                     var dst = ndx ? reference : result;
826                     ctx = ndx ? refContext : webgl2Context;
827                     var shaderID = ndx ? shaderIDRef : shaderIDgles;
829                     this.m_context = ctx;
830                     shader.setUniforms(ctx, shaderID);
831                     this.renderTex(dst, shaderID, levelW, levelH);
832                 }
834                 var threshold =
835                 es3fTextureSpecificationTests.computeCompareThreshold(
836                     tcuPixelFormat.PixelFormatFromContext(gl), this.m_texFormat
837                 );
838                 var levelStr = levelNdx.toString();
839                 var sliceStr = depth.toString();
840                 var name = 'Layer' + levelStr + 'Slice' + sliceStr;
841                 var desc = 'Layer ' + levelStr + ', Slice ' + sliceStr;
842                 var depthOk = tcuImageCompare.intThresholdCompare(
843                     name, desc, reference.getAccess(), result.getAccess(),
844                     threshold, (levelNdx == 0 && depth == 0) ?
845                     tcuImageCompare.CompareLogMode.RESULT :
846                     tcuImageCompare.CompareLogMode.ON_ERROR
847                 );
849                 if (!depthOk) {
850                     testFailed('Image comparison failed');
851                     return false;
852                 }
853             }
855         }
856         return true;
857     };
859     // Basic TexImage2D() with 2D texture usage
860     /**
861      * @constructor
862      * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
863      * @param {string} name
864      * @param {string} desc
865      * @param {number} format
866      * @param {number} dataType
867      * @param {number} width
868      * @param {number} height
869      */
870     es3fTextureSpecificationTests.BasicTexImage2DCase = function(
871         name, desc, format, dataType, width, height
872     ) {
873         // Unsized internal format.
874         es3fTextureSpecificationTests.Texture2DSpecCase.call(
875             this, name, desc, gluTextureUtil.mapGLTransferFormat(
876                 format, dataType
877             ), width, height,
878             es3fTextureSpecificationTests.maxLevelCount(
879                 width, height
880             )
881         );
883         this.m_internalFormat = format;
884         this.m_format = format;
885         this.m_dataType = dataType;
886     };
888     es3fTextureSpecificationTests.BasicTexImage2DCase.prototype = Object.create(
889         es3fTextureSpecificationTests.Texture2DSpecCase.prototype
890     );
892     es3fTextureSpecificationTests.BasicTexImage2DCase.prototype.constructor =
893         es3fTextureSpecificationTests.BasicTexImage2DCase;
895     /**
896      * @param {string} name
897      * @param {string} desc
898      * @param {number} internalFormat
899      * @param {number} width
900      * @param {number} height
901      * @return {es3fTextureSpecificationTests.BasicTexImage2DCase}
902      */
903     es3fTextureSpecificationTests.newBasicTexImage2DCaseInternal = function(
904         name, desc, internalFormat, width, height
905     ) {
906         // Sized internal format.
907         var fmt = gluTextureUtil.getTransferFormat(
908             gluTextureUtil.mapGLInternalFormat(internalFormat)
909         );
910         var testcase = new es3fTextureSpecificationTests.BasicTexImage2DCase(
911             name, desc, fmt.format, fmt.dataType, width, height
912         );
913         testcase.m_internalFormat = internalFormat;
914         return testcase;
915     };
917     /**
918      * createTexture
919      */
920     es3fTextureSpecificationTests.BasicTexImage2DCase.prototype.createTexture =
921     function() {
922         var tex = null;
923         var levelData = new tcuTexture.TextureLevel(
924             this.m_texFormat, this.m_width, this.m_height
925         );
926         var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
928         tex = this.m_context.createTexture();
929         this.m_context.bindTexture(gl.TEXTURE_2D, tex);
930         this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
932         for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
933             var levelW = Math.max(1, this.m_width >> ndx);
934             var levelH = Math.max(1, this.m_height >> ndx);
935             var gMin = es3fTextureSpecificationTests.randomVector(
936                 rnd, this.m_texFormatInfo.valueMin,
937                 this.m_texFormatInfo.valueMax, 4
938             );
939             var gMax = es3fTextureSpecificationTests.randomVector(
940                 rnd, this.m_texFormatInfo.valueMin,
941                 this.m_texFormatInfo.valueMax, 4
942             );
944             levelData.setSize(levelW, levelH);
945             tcuTextureUtil.fillWithComponentGradients(
946                 levelData.getAccess(), gMin, gMax
947             );
949             this.m_context.texImage2D(
950                 gl.TEXTURE_2D, ndx, this.m_internalFormat, levelW, levelH, 0,
951                 this.m_format, this.m_dataType,
952                 levelData.getAccess().getDataPtr()
953             );
954         }
955     };
957     // Basic TexImage2D() with cubemap usage
958     /**
959      * @constructor
960      * @extends {es3fTextureSpecificationTests.TextureCubeSpecCase}
961      * @param {string} name
962      * @param {string} desc
963      * @param {number} format
964      * @param {number} dataType
965      * @param {number} size
966      */
967     es3fTextureSpecificationTests.BasicTexImageCubeCase = function(
968         name, desc, format, dataType, size
969     ) {
970         // Unsized internal format.
971         es3fTextureSpecificationTests.TextureCubeSpecCase.call(
972             this, name, desc, gluTextureUtil.mapGLTransferFormat(
973                 format, dataType
974             ), size, deMath.logToFloor(size) + 1
975         );
977         this.m_internalFormat = format;
978         this.m_format = format;
979         this.m_dataType = dataType;
980     };
982     es3fTextureSpecificationTests.BasicTexImageCubeCase.prototype =
983         Object.create(
984             es3fTextureSpecificationTests.TextureCubeSpecCase.prototype
985         );
987     es3fTextureSpecificationTests.
988     BasicTexImageCubeCase.prototype.constructor =
989         es3fTextureSpecificationTests.BasicTexImageCubeCase;
991     /**
992      * @param {string} name
993      * @param {string} desc
994      * @param {number} internalFormat
995      * @param {number} size
996      * @return {es3fTextureSpecificationTests.BasicTexImageCubeCase}
997      */
998     es3fTextureSpecificationTests.newBasicTexImageCubeCaseInternal = function(
999         name, desc, internalFormat, size
1000     ) {
1001         // Sized internal format.
1002         var fmt = gluTextureUtil.getTransferFormat(
1003             gluTextureUtil.mapGLInternalFormat(internalFormat)
1004         );
1005         var testcase = new es3fTextureSpecificationTests.BasicTexImageCubeCase(
1006             name, desc, fmt.format, fmt.dataType, size
1007         );
1008         testcase.m_internalFormat = internalFormat;
1009         return testcase;
1010     };
1012     /**
1013      * createTexture
1014      */
1015     es3fTextureSpecificationTests.
1016     BasicTexImageCubeCase.prototype.createTexture =
1017     function() {
1018         var tex = null;
1019         var levelData = new tcuTexture.TextureLevel(
1020             this.m_texFormat, this.m_size, this.m_size
1021         );
1022         var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
1024         tex = this.m_context.createTexture();
1025         this.m_context.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
1026         this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
1028         for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
1029             var levelSize = Math.max(1, this.m_size >> ndx);
1031             levelData.setSize(levelSize, levelSize);
1033             for (var f in tcuTexture.CubeFace) {
1034                 var face = tcuTexture.CubeFace[f];
1035                 var gMin = es3fTextureSpecificationTests.randomVector(
1036                     rnd, this.m_texFormatInfo.valueMin,
1037                     this.m_texFormatInfo.valueMax, 4
1038                 );
1039                 var gMax = es3fTextureSpecificationTests.randomVector(
1040                     rnd, this.m_texFormatInfo.valueMin,
1041                     this.m_texFormatInfo.valueMax, 4
1042                 );
1044                 tcuTextureUtil.fillWithComponentGradients(
1045                     levelData.getAccess(), gMin, gMax
1046                 );
1048                 this.m_context.texImage2D(
1049                     es3fTextureSpecificationTests.s_cubeMapFaces[face],
1050                     ndx, this.m_internalFormat, levelSize, levelSize, 0,
1051                     this.m_format, this.m_dataType,
1052                     levelData.getAccess().getDataPtr()
1053                 );
1054             }
1055         }
1056     };
1058     // Basic TexImage3D() with 2D array texture usage
1059     /**
1060      * @constructor
1061      * @extends {es3fTextureSpecificationTests.Texture2DArraySpecCase}
1062      * @param {string} name
1063      * @param {string} desc
1064      * @param {number} internalFormat
1065      * @param {number} width
1066      * @param {number} height
1067      * @param {number} numLayers
1068      */
1069     es3fTextureSpecificationTests.BasicTexImage2DArrayCase = function(
1070         name, desc, internalFormat, width, height, numLayers
1071     ) {
1072         es3fTextureSpecificationTests.Texture2DArraySpecCase.call(
1073             this, name, desc,
1074             gluTextureUtil.mapGLInternalFormat(internalFormat), width, height,
1075             numLayers, es3fTextureSpecificationTests.maxLevelCount(
1076                 width, height
1077             )
1078         );
1080         this.m_internalFormat = internalFormat;
1081     };
1083     es3fTextureSpecificationTests.BasicTexImage2DArrayCase.prototype =
1084         Object.create(
1085             es3fTextureSpecificationTests.Texture2DArraySpecCase.prototype
1086         );
1088     es3fTextureSpecificationTests.
1089     BasicTexImage2DArrayCase.prototype.constructor =
1090         es3fTextureSpecificationTests.BasicTexImage2DArrayCase;
1092     /**
1093      * createTexture
1094      */
1095     es3fTextureSpecificationTests.
1096     BasicTexImage2DArrayCase.prototype.createTexture =
1097     function() {
1098         var tex = null;
1099         var levelData = new tcuTexture.TextureLevel(
1100             this.m_texFormat, this.m_width, this.m_height
1101         );
1102         var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
1103         var transferFmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
1105         tex = this.m_context.createTexture();
1106         this.m_context.bindTexture(gl.TEXTURE_2D_ARRAY, tex);
1107         this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
1109         for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
1110             var levelW = Math.max(1, this.m_width >> ndx);
1111             var levelH = Math.max(1, this.m_height >> ndx);
1113             var gMin = es3fTextureSpecificationTests.randomVector(
1114                 rnd, this.m_texFormatInfo.valueMin,
1115                 this.m_texFormatInfo.valueMax, 4
1116             );
1117             var gMax = es3fTextureSpecificationTests.randomVector(
1118                 rnd, this.m_texFormatInfo.valueMin,
1119                 this.m_texFormatInfo.valueMax, 4
1120             );
1122             levelData.setSize(levelW, levelH, this.m_numLayers);
1123             tcuTextureUtil.fillWithComponentGradients(
1124                 levelData.getAccess(), gMin, gMax
1125             );
1127             this.m_context.texImage3D(
1128                 gl.TEXTURE_2D_ARRAY, ndx, this.m_internalFormat, levelW, levelH,
1129                 this.m_numLayers, 0, transferFmt.format,
1130                 transferFmt.dataType, levelData.getAccess().getDataPtr()
1131             );
1132         }
1133     };
1135     // Basic TexImage3D() with 3D texture usage
1136     /**
1137      * @constructor
1138      * @extends {es3fTextureSpecificationTests.Texture3DSpecCase}
1139      * @param {string} name
1140      * @param {string} desc
1141      * @param {number} internalFormat
1142      * @param {number} width
1143      * @param {number} height
1144      * @param {number} depth
1145      */
1146     es3fTextureSpecificationTests.BasicTexImage3DCase = function(
1147         name, desc, internalFormat, width, height, depth
1148     ) {
1149         es3fTextureSpecificationTests.Texture3DSpecCase.call(
1150             this, name, desc,
1151             gluTextureUtil.mapGLInternalFormat(internalFormat), width, height,
1152             depth, es3fTextureSpecificationTests.maxLevelCount(
1153                 width, height, depth
1154             )
1155         );
1157         this.m_internalFormat = internalFormat;
1158     };
1160     es3fTextureSpecificationTests.BasicTexImage3DCase.prototype =
1161         Object.create(
1162             es3fTextureSpecificationTests.Texture3DSpecCase.prototype
1163         );
1165     es3fTextureSpecificationTests.
1166     BasicTexImage3DCase.prototype.constructor =
1167         es3fTextureSpecificationTests.BasicTexImage3DCase;
1169     /**
1170      * createTexture
1171      */
1172     es3fTextureSpecificationTests.
1173     BasicTexImage3DCase.prototype.createTexture =
1174     function() {
1175         var tex = null;
1176         var levelData = new tcuTexture.TextureLevel(
1177             this.m_texFormat, this.m_width, this.m_height
1178         );
1179         var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
1180         var transferFmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
1182         tex = this.m_context.createTexture();
1183         this.m_context.bindTexture(gl.TEXTURE_3D, tex);
1184         this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
1186         for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
1187             var levelW = Math.max(1, this.m_width >> ndx);
1188             var levelH = Math.max(1, this.m_height >> ndx);
1189             var levelD = Math.max(1, this.m_depth >> ndx);
1191             var gMin = es3fTextureSpecificationTests.randomVector(
1192                 rnd, this.m_texFormatInfo.valueMin,
1193                 this.m_texFormatInfo.valueMax, 4
1194             );
1195             var gMax = es3fTextureSpecificationTests.randomVector(
1196                 rnd, this.m_texFormatInfo.valueMin,
1197                 this.m_texFormatInfo.valueMax, 4
1198             );
1200             levelData.setSize(levelW, levelH, levelD);
1201             tcuTextureUtil.fillWithComponentGradients(
1202                 levelData.getAccess(), gMin, gMax
1203             );
1205             this.m_context.texImage3D(
1206                 gl.TEXTURE_3D, ndx, this.m_internalFormat, levelW, levelH,
1207                 levelD, 0, transferFmt.format, transferFmt.dataType,
1208                 levelData.getAccess().getDataPtr()
1209             );
1210         }
1211     };
1213     // Randomized 2D texture specification using TexImage2D
1214     /**
1215      * @constructor
1216      * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
1217      * @param {string} name
1218      * @param {string} desc
1219      * @param {number} format
1220      * @param {number} dataType
1221      * @param {number} width
1222      * @param {number} height
1223      */
1224     es3fTextureSpecificationTests.RandomOrderTexImage2DCase = function(
1225         name, desc, format, dataType, width, height
1226     ) {
1227         // Unsized internal format.
1228         es3fTextureSpecificationTests.Texture2DSpecCase.call(
1229             this, name, desc, gluTextureUtil.mapGLTransferFormat(
1230                 format, dataType
1231             ), width, height,
1232             es3fTextureSpecificationTests.maxLevelCount(
1233                 width, height
1234             )
1235         );
1237         this.m_internalFormat = format;
1238         this.m_format = format;
1239         this.m_dataType = dataType;
1240     };
1242     es3fTextureSpecificationTests.RandomOrderTexImage2DCase.prototype = Object.create(
1243         es3fTextureSpecificationTests.Texture2DSpecCase.prototype
1244     );
1246     es3fTextureSpecificationTests.
1247     RandomOrderTexImage2DCase.prototype.constructor =
1248         es3fTextureSpecificationTests.RandomOrderTexImage2DCase;
1250     /**
1251      * @param {string} name
1252      * @param {string} desc
1253      * @param {number} internalFormat
1254      * @param {number} width
1255      * @param {number} height
1256      * @return {es3fTextureSpecificationTests.RandomOrderTexImage2DCase}
1257      */
1258     es3fTextureSpecificationTests.newRandomOrderTexImage2DCaseInternal =
1259     function(name, desc, internalFormat, width, height) {
1260         // Sized internal format.
1261         var fmt = gluTextureUtil.getTransferFormat(
1262             gluTextureUtil.mapGLInternalFormat(internalFormat)
1263         );
1264         var testcase = new es3fTextureSpecificationTests.RandomOrderTexImage2DCase(
1265             name, desc, fmt.format, fmt.dataType, width, height
1266         );
1267         testcase.m_internalFormat = internalFormat;
1268         return testcase;
1269     };
1271     /**
1272      * createTexture
1273      */
1274     es3fTextureSpecificationTests.
1275     RandomOrderTexImage2DCase.prototype.createTexture = function() {
1276         var tex = null;
1277         var levelData = new tcuTexture.TextureLevel(
1278             this.m_texFormat, this.m_width, this.m_height
1279         );
1280         var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
1282         tex = this.m_context.createTexture();
1283         this.m_context.bindTexture(gl.TEXTURE_2D, tex);
1284         this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
1286         var levels = [];
1287         for (var i = 0; i < this.m_numLevels; i++)
1288             levels[i] = i;
1289         levels = rnd.shuffle(levels);
1291         for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
1292             var levelNdx = levels[ndx];
1293             var levelW = Math.max(1, this.m_width >> levelNdx);
1294             var levelH = Math.max(1, this.m_height >> levelNdx);
1295             var gMin = es3fTextureSpecificationTests.randomVector(
1296                 rnd, this.m_texFormatInfo.valueMin,
1297                 this.m_texFormatInfo.valueMax, 4
1298             );
1299             var gMax = es3fTextureSpecificationTests.randomVector(
1300                 rnd, this.m_texFormatInfo.valueMin,
1301                 this.m_texFormatInfo.valueMax, 4
1302             );
1304             levelData.setSize(levelW, levelH);
1305             tcuTextureUtil.fillWithComponentGradients(
1306                 levelData.getAccess(), gMin, gMax
1307             );
1309             this.m_context.texImage2D(
1310                 gl.TEXTURE_2D, levelNdx, this.m_internalFormat, levelW, levelH, 0,
1311                 this.m_format, this.m_dataType,
1312                 levelData.getAccess().getDataPtr()
1313             );
1314         }
1315     };
1317     // Randomized cubemap texture specification using TexImage2D
1318     /**
1319      * @constructor
1320      * @extends {es3fTextureSpecificationTests.TextureCubeSpecCase}
1321      * @param {string} name
1322      * @param {string} desc
1323      * @param {number} format
1324      * @param {number} dataType
1325      * @param {number} size
1326      */
1327     es3fTextureSpecificationTests.RandomOrderTexImageCubeCase = function(
1328         name, desc, format, dataType, size
1329     ) {
1330         // Unsized internal format.
1331         es3fTextureSpecificationTests.TextureCubeSpecCase.call(
1332             this, name, desc, gluTextureUtil.mapGLTransferFormat(
1333                 format, dataType
1334             ), size, deMath.logToFloor(size) + 1
1335         );
1337         this.m_internalFormat = format;
1338         this.m_format = format;
1339         this.m_dataType = dataType;
1340     };
1342     es3fTextureSpecificationTests.RandomOrderTexImageCubeCase.prototype =
1343         Object.create(
1344             es3fTextureSpecificationTests.TextureCubeSpecCase.prototype
1345         );
1347     es3fTextureSpecificationTests.
1348     RandomOrderTexImageCubeCase.prototype.constructor =
1349         es3fTextureSpecificationTests.RandomOrderTexImageCubeCase;
1351     /**
1352      * @param {string} name
1353      * @param {string} desc
1354      * @param {number} internalFormat
1355      * @param {number} size
1356      * @return {es3fTextureSpecificationTests.RandomOrderTexImageCubeCase}
1357      */
1358     es3fTextureSpecificationTests.newRandomOrderTexImageCubeCaseInternal =
1359     function(name, desc, internalFormat, size) {
1360         // Sized internal format.
1361         var fmt = gluTextureUtil.getTransferFormat(
1362             gluTextureUtil.mapGLInternalFormat(internalFormat)
1363         );
1364         var testcase = new es3fTextureSpecificationTests.RandomOrderTexImageCubeCase(
1365             name, desc, fmt.format, fmt.dataType, size
1366         );
1367         testcase.m_internalFormat = internalFormat;
1368         return testcase;
1369     };
1371     /**
1372      * createTexture
1373      */
1374     es3fTextureSpecificationTests.
1375     RandomOrderTexImageCubeCase.prototype.createTexture =
1376     function() {
1377         var tex = null;
1378         var levelData = new tcuTexture.TextureLevel(
1379             this.m_texFormat, this.m_size, this.m_size
1380         );
1381         var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
1383         tex = this.m_context.createTexture();
1384         this.m_context.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
1385         this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
1387         // Level-face pairs.
1388         var images = [];
1390         for (var ndx = 0; ndx < this.m_numLevels; ndx++)
1391             for (var f in tcuTexture.CubeFace) {
1392                 var face = tcuTexture.CubeFace[f];
1393                 images[ndx * 6 + face] = {ndx: ndx, face: face};
1394             }
1396         images = rnd.shuffle(images);
1398         for (var ndx = 0; ndx < images.length; ndx++) {
1399             var levelNdx = images[ndx].ndx;
1400             /** @type {framework.common.tcuTexture.CubeFace} */
1401             var face = images[ndx].face;
1402             var levelSize = Math.max(1, this.m_size >> levelNdx);
1404             var gMin = es3fTextureSpecificationTests.randomVector(
1405                 rnd, this.m_texFormatInfo.valueMin,
1406                 this.m_texFormatInfo.valueMax, 4
1407             );
1408             var gMax = es3fTextureSpecificationTests.randomVector(
1409                 rnd, this.m_texFormatInfo.valueMin,
1410                 this.m_texFormatInfo.valueMax, 4
1411             );
1413             levelData.setSize(levelSize, levelSize);
1414             tcuTextureUtil.fillWithComponentGradients(
1415                 levelData.getAccess(), gMin, gMax
1416             );
1418             this.m_context.texImage2D(
1419                 es3fTextureSpecificationTests.s_cubeMapFaces[face],
1420                 levelNdx, this.m_internalFormat, levelSize, levelSize, 0,
1421                 this.m_format, this.m_dataType,
1422                 levelData.getAccess().getDataPtr()
1423             );
1424         }
1425     };
1427     // TexImage2D() unpack alignment case.
1428     /**
1429      * @constructor
1430      * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
1431      * @param {string} name
1432      * @param {string} desc
1433      * @param {number} format
1434      * @param {number} dataType
1435      * @param {number} width
1436      * @param {number} height
1437      * @param {number} numLevels
1438      * @param {number} alignment
1439      */
1440     es3fTextureSpecificationTests.TexImage2DAlignCase = function(
1441         name, desc, format, dataType, width, height, numLevels, alignment
1442     ) {
1443         // Unsized internal format.
1444         es3fTextureSpecificationTests.Texture2DSpecCase.call(
1445             this, name, desc, gluTextureUtil.mapGLTransferFormat(
1446                 format, dataType
1447             ), width, height, numLevels
1448         );
1450         this.m_internalFormat = format;
1451         this.m_format = format;
1452         this.m_dataType = dataType;
1453         this.m_alignment = alignment;
1454     };
1456     es3fTextureSpecificationTests.TexImage2DAlignCase.prototype = Object.create(
1457         es3fTextureSpecificationTests.Texture2DSpecCase.prototype
1458     );
1460     es3fTextureSpecificationTests.
1461     TexImage2DAlignCase.prototype.constructor =
1462         es3fTextureSpecificationTests.TexImage2DAlignCase;
1464     /**
1465     * @param {string} name
1466     * @param {string} desc
1467     * @param {number} internalFormat
1468     * @param {number} width
1469     * @param {number} height
1470     * @param {number} numLevels
1471     * @param {number} alignment
1472      * @return {es3fTextureSpecificationTests.TexImage2DAlignCase}
1473      */
1474     es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal = function(
1475         name, desc, internalFormat, width, height, numLevels, alignment
1476     ) {
1477         // Sized internal format.
1478         var fmt = gluTextureUtil.getTransferFormat(
1479             gluTextureUtil.mapGLInternalFormat(internalFormat)
1480         );
1481         var testcase = new es3fTextureSpecificationTests.TexImage2DAlignCase(
1482             name, desc, fmt.format, fmt.dataType,
1483             width, height, numLevels, alignment
1484         );
1485         testcase.m_internalFormat = internalFormat;
1486         return testcase;
1487     };
1489     /**
1490      * createTexture
1491      */
1492     es3fTextureSpecificationTests.TexImage2DAlignCase.prototype.createTexture =
1493     function() {
1494         var tex = null;
1495         /** @type {ArrayBuffer} */ var data;
1497         tex = this.m_context.createTexture();
1498         this.m_context.bindTexture(gl.TEXTURE_2D, tex);
1499         this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
1501         for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
1502             var levelW = Math.max(1, this.m_width >> ndx);
1503             var levelH = Math.max(1, this.m_height >> ndx);
1504             var colorA = deMath.add(
1505                 deMath.multiply(
1506                     [1.0, 0.0, 0.0, 1.0],
1507                     deMath.subtract(
1508                         this.m_texFormatInfo.valueMax,
1509                         this.m_texFormatInfo.valueMin
1510                     )
1511                 ), this.m_texFormatInfo.valueMin
1512             );
1513             var colorB = deMath.add(
1514                 deMath.multiply(
1515                     [0.0, 1.0, 0.0, 1.0],
1516                     deMath.subtract(
1517                         this.m_texFormatInfo.valueMax,
1518                         this.m_texFormatInfo.valueMin
1519                     )
1520                 ), this.m_texFormatInfo.valueMin
1521             );
1523             var rowPitch = deMath.deAlign32(
1524                 levelW * this.m_texFormat.getPixelSize(), this.m_alignment
1525             );
1526             var cellSize = Math.max(1, Math.min(levelW >> 2, levelH >> 2));
1527             data = new ArrayBuffer(rowPitch * levelH);
1528             var access = new tcuTexture.PixelBufferAccess({format: this.m_texFormat, width: levelW,
1529                     height: levelH, rowPitch: rowPitch, data: data}
1530                 );
1531             tcuTextureUtil.fillWithGrid(access, cellSize, colorA, colorB
1532             );
1534             this.m_context.texImage2D(
1535                 gl.TEXTURE_2D, ndx, this.m_internalFormat, levelW, levelH, 0,
1536                 this.m_format, this.m_dataType,
1537                 access.getDataPtr()
1538             );
1539         }
1540     };
1542     // TexImageCube unpack alignment case.
1543     /**
1544      * @constructor
1545      * @extends {es3fTextureSpecificationTests.TextureCubeSpecCase}
1546      * @param {string} name
1547      * @param {string} desc
1548      * @param {number} format
1549      * @param {number} dataType
1550      * @param {number} size
1551      * @param {number} numLevels
1552      * @param {number} alignment
1553      */
1554     es3fTextureSpecificationTests.TexImageCubeAlignCase = function(
1555         name, desc, format, dataType, size, numLevels, alignment
1556     ) {
1557         // Unsized internal format.
1558         es3fTextureSpecificationTests.TextureCubeSpecCase.call(
1559             this, name, desc, gluTextureUtil.mapGLTransferFormat(
1560                 format, dataType
1561             ), size, numLevels
1562         );
1564         this.m_internalFormat = format;
1565         this.m_format = format;
1566         this.m_dataType = dataType;
1567         this.m_alignment = alignment;
1568     };
1570     es3fTextureSpecificationTests.TexImageCubeAlignCase.prototype =
1571         Object.create(
1572             es3fTextureSpecificationTests.TextureCubeSpecCase.prototype
1573         );
1575     es3fTextureSpecificationTests.
1576     TexImageCubeAlignCase.prototype.constructor =
1577         es3fTextureSpecificationTests.TexImageCubeAlignCase;
1579     /**
1580      * @param {string} name
1581      * @param {string} desc
1582      * @param {number} internalFormat
1583      * @param {number} size
1584      * @param {number} numLevels
1585      * @param {number} alignment
1586      * @return {es3fTextureSpecificationTests.TexImageCubeAlignCase}
1587      */
1588     es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal =
1589     function(name, desc, internalFormat, size, numLevels, alignment) {
1590         // Sized internal format.
1591         var fmt = gluTextureUtil.getTransferFormat(
1592             gluTextureUtil.mapGLInternalFormat(internalFormat)
1593         );
1594         var testcase = new es3fTextureSpecificationTests.TexImageCubeAlignCase(
1595             name, desc, fmt.format, fmt.dataType, size, numLevels, alignment
1596         );
1597         testcase.m_internalFormat = internalFormat;
1598         return testcase;
1599     };
1601     /**
1602      * createTexture
1603      */
1604     es3fTextureSpecificationTests.
1605     TexImageCubeAlignCase.prototype.createTexture =
1606     function() {
1607         var tex = null;
1608         var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
1609         /** @type {ArrayBuffer} */ var data;
1611         tex = this.m_context.createTexture();
1612         this.m_context.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
1613         this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
1615         for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
1616             var levelSize = Math.max(1, this.m_size >> ndx);
1617             var cellSize = Math.max(1, levelSize >> 2);
1618             var rowPitch = deMath.deAlign32(
1619                 this.m_texFormat.getPixelSize() * levelSize, this.m_alignment
1620             );
1621             var colorA = deMath.add(deMath.multiply(
1622                 [1.0, 0.0, 0.0, 1.0], deMath.subtract(
1623                     this.m_texFormatInfo.valueMax, this.m_texFormatInfo.valueMin
1624                 )), this.m_texFormatInfo.valueMin
1625             );
1626             var colorB = deMath.add(deMath.multiply(
1627                 [0.0, 1.0, 0.0, 1.0], deMath.subtract(
1628                     this.m_texFormatInfo.valueMax, this.m_texFormatInfo.valueMin
1629                 )), this.m_texFormatInfo.valueMin
1630             );
1632             data = new ArrayBuffer(rowPitch * levelSize);
1633             var access = new tcuTexture.PixelBufferAccess({format: this.m_texFormat, width: levelSize,
1634                     height: levelSize, rowPitch: rowPitch, data: data}
1635                 );
1636             tcuTextureUtil.fillWithGrid(access, cellSize, colorA, colorB
1637             );
1639             for (var f in tcuTexture.CubeFace) {
1640                 var face = tcuTexture.CubeFace[f];
1641                 this.m_context.texImage2D(
1642                     es3fTextureSpecificationTests.s_cubeMapFaces[face],
1643                     ndx, this.m_internalFormat, levelSize, levelSize, 0,
1644                     this.m_format, this.m_dataType,
1645                     access.getDataPtr()
1646                 );
1647             }
1648         }
1649     };
1651     // TexImage2D() unpack parameters case.
1652     /**
1653      * @constructor
1654      * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
1655      * @param {string} name
1656      * @param {string} desc
1657      * @param {number} internalFormat
1658      * @param {number} width
1659      * @param {number} height
1660      * @param {number} rowLength
1661      * @param {number} skipRows
1662      * @param {number} skipPixels
1663      * @param {number} alignment
1664      */
1665     es3fTextureSpecificationTests.TexImage2DParamsCase = function(
1666         name, desc, internalFormat, width, height, rowLength, skipRows,
1667         skipPixels, alignment
1668     ) {
1669         es3fTextureSpecificationTests.Texture2DSpecCase.call(
1670             this, name, desc,
1671             gluTextureUtil.mapGLInternalFormat(internalFormat),
1672             width, height, 1
1673         );
1674         this.m_internalFormat = internalFormat;
1675         this.m_rowLength = rowLength;
1676         this.m_skipRows = skipRows;
1677         this.m_skipPixels = skipPixels;
1678         this.m_alignment = alignment;
1679     };
1681     es3fTextureSpecificationTests.TexImage2DParamsCase.prototype =
1682     Object.create(es3fTextureSpecificationTests.Texture2DSpecCase.prototype);
1684     es3fTextureSpecificationTests.TexImage2DParamsCase.prototype.constructor =
1685         es3fTextureSpecificationTests.TexImage2DParamsCase;
1687     /**
1688      * createTexture
1689      */
1690     es3fTextureSpecificationTests.TexImage2DParamsCase.prototype.createTexture =
1691     function() {
1692         var transferFmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
1693         var pixelSize = this.m_texFormat.getPixelSize();
1694         var rowLength = this.m_rowLength > 0 ? this.m_rowLength : this.m_width;
1695         var rowPitch = deMath.deAlign32(rowLength * pixelSize, this.m_alignment);
1696         var height = this.m_height + this.m_skipRows;
1697         var tex = null;
1698         /** @type {ArrayBuffer} */ var data;
1700         assertMsgOptions(
1701             this.m_numLevels == 1, 'Number of levels different to 1',
1702             false, true
1703         );
1705         // Fill data with grid.
1706         data = new ArrayBuffer(rowPitch * height + this.m_skipPixels * pixelSize);
1708         var cScale = deMath.subtract(
1709             this.m_texFormatInfo.valueMax, this.m_texFormatInfo.valueMin
1710         );
1711         var cBias = this.m_texFormatInfo.valueMin;
1712         var colorA = deMath.add(
1713             deMath.multiply(
1714                 [1.0, 0.0, 0.0, 1.0], cScale
1715             ), cBias
1716         );
1717         var colorB = deMath.add(
1718             deMath.multiply(
1719                 [0.0, 1.0, 0.0, 1.0], cScale
1720             ), cBias
1721         );
1723         var accessWithOffset = new tcuTexture.PixelBufferAccess({
1724                 format: this.m_texFormat,
1725                 width: this.m_width,
1726                 height: this.m_height,
1727                 rowPitch: rowPitch,
1728                 data: data,
1729                 offset: this.m_skipRows * rowPitch + this.m_skipPixels * pixelSize
1730                 });
1731         tcuTextureUtil.fillWithGrid(accessWithOffset, 4, colorA, colorB
1732         );
1733         var access = new tcuTexture.PixelBufferAccess({
1734                 format: this.m_texFormat,
1735                 width: this.m_width,
1736                 height: this.m_height,
1737                 rowPitch: rowPitch,
1738                 data: data,
1739                 });
1741         this.m_context.pixelStorei(gl.UNPACK_ROW_LENGTH, this.m_rowLength);
1742         this.m_context.pixelStorei(gl.UNPACK_SKIP_ROWS, this.m_skipRows);
1743         this.m_context.pixelStorei(gl.UNPACK_SKIP_PIXELS, this.m_skipPixels);
1744         this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
1746         tex = this.m_context.createTexture();
1747         this.m_context.bindTexture(gl.TEXTURE_2D, tex);
1748         this.m_context.texImage2D(
1749             gl.TEXTURE_2D, 0, this.m_internalFormat,
1750             this.m_width, this.m_height, 0,
1751             transferFmt.format, transferFmt.dataType, access.getDataPtr()
1752         );
1753     };
1755     // TexImage3D() unpack parameters case.
1756     /**
1757      * @constructor
1758      * @extends {es3fTextureSpecificationTests.Texture3DSpecCase}
1759      * @param {string} name
1760      * @param {string} desc
1761      * @param {number} internalFormat
1762      * @param {number} width
1763      * @param {number} height
1764      * @param {number} depth
1765      * @param {number} imageHeight
1766      * @param {number} rowLength
1767      * @param {number} skipImages
1768      * @param {number} skipRows
1769      * @param {number} skipPixels
1770      * @param {number} alignment
1771      */
1772     es3fTextureSpecificationTests.TexImage3DParamsCase = function(
1773         name, desc, internalFormat, width, height, depth, imageHeight,
1774         rowLength, skipImages, skipRows, skipPixels, alignment
1775     ) {
1776         es3fTextureSpecificationTests.Texture3DSpecCase.call(
1777             this, name, desc,
1778             gluTextureUtil.mapGLInternalFormat(internalFormat),
1779             width, height, depth, 1
1780         );
1782         this.m_internalFormat = internalFormat;
1783         this.m_imageHeight = imageHeight;
1784         this.m_rowLength = rowLength;
1785         this.m_skipImages = skipImages;
1786         this.m_skipRows = skipRows;
1787         this.m_skipPixels = skipPixels;
1788         this.m_alignment = alignment;
1789     };
1791     es3fTextureSpecificationTests.TexImage3DParamsCase.prototype =
1792     Object.create(es3fTextureSpecificationTests.Texture3DSpecCase.prototype);
1794     es3fTextureSpecificationTests.TexImage3DParamsCase.prototype.constructor =
1795         es3fTextureSpecificationTests.Texture3DSpecCase;
1797     /**
1798      * createTexture
1799      */
1800     es3fTextureSpecificationTests.TexImage3DParamsCase.prototype.createTexture =
1801     function() {
1802         var transferFmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
1803         var pixelSize = this.m_texFormat.getPixelSize();
1804         var rowLength = this.m_rowLength > 0 ? this.m_rowLength : this.m_width;
1805         var rowPitch = deMath.deAlign32(rowLength * pixelSize, this.m_alignment);
1806         var imageHeight = this.m_imageHeight > 0 ?
1807             this.m_imageHeight : this.m_height;
1808         var slicePitch = imageHeight * rowPitch;
1810         var tex = null;
1811         /** @type {ArrayBuffer} */ var data;
1813         assertMsgOptions(
1814             this.m_numLevels == 1, 'Number of levels different to 1',
1815             false, true
1816         );
1818         // Fill data with grid.
1819         data = new ArrayBuffer(slicePitch * (this.m_depth + this.m_skipImages) +
1820                                this.m_skipRows * rowPitch + this.m_skipPixels * pixelSize);
1822         var cScale = deMath.subtract(
1823             this.m_texFormatInfo.valueMax, this.m_texFormatInfo.valueMin
1824         );
1825         var cBias = this.m_texFormatInfo.valueMin;
1826         var colorA = deMath.add(
1827             deMath.multiply(
1828                 [1.0, 0.0, 0.0, 1.0], cScale
1829             ), cBias
1830         );
1831         var colorB = deMath.add(
1832             deMath.multiply(
1833                 [0.0, 1.0, 0.0, 1.0], cScale
1834             ), cBias
1835         );
1837         var accessWithOffset = new tcuTexture.PixelBufferAccess({
1838                 format: this.m_texFormat,
1839                 width: this.m_width,
1840                 height: this.m_height,
1841                 depth: this.m_depth,
1842                 rowPitch: rowPitch,
1843                 slicePitch: slicePitch,
1844                 data: data,
1845                 offset: this.m_skipImages * slicePitch + this.m_skipRows * rowPitch + this.m_skipPixels * pixelSize
1846             });
1847         var access = new tcuTexture.PixelBufferAccess({
1848                 format: this.m_texFormat,
1849                 width: this.m_width,
1850                 height: this.m_height,
1851                 depth: this.m_depth,
1852                 rowPitch: rowPitch,
1853                 slicePitch: slicePitch,
1854                 data: data
1855             });
1856         tcuTextureUtil.fillWithGrid(
1857             accessWithOffset, 4, colorA, colorB
1858         );
1860         this.m_context.pixelStorei(gl.UNPACK_IMAGE_HEIGHT, this.m_imageHeight);
1861         this.m_context.pixelStorei(gl.UNPACK_ROW_LENGTH, this.m_rowLength);
1862         this.m_context.pixelStorei(gl.UNPACK_SKIP_IMAGES, this.m_skipImages);
1863         this.m_context.pixelStorei(gl.UNPACK_SKIP_ROWS, this.m_skipRows);
1864         this.m_context.pixelStorei(gl.UNPACK_SKIP_PIXELS, this.m_skipPixels);
1865         this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
1867         tex = this.m_context.createTexture();
1868         this.m_context.bindTexture(gl.TEXTURE_3D, tex);
1869         this.m_context.texImage3D(
1870             gl.TEXTURE_3D, 0, this.m_internalFormat,
1871             this.m_width, this.m_height, this.m_depth, 0,
1872             transferFmt.format, transferFmt.dataType, access.getDataPtr()
1873         );
1874     };
1876     /**
1877      * @constructor
1878      * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
1879      * @param {string} name
1880      * @param {string} desc
1881      * @param {number} format
1882      * @param {number} dataType
1883      * @param {number} width
1884      * @param {number} height
1885      */
1886     es3fTextureSpecificationTests.BasicTexSubImage2DCase = function(
1887         name, desc, format, dataType, width, height
1888     ) {
1889         es3fTextureSpecificationTests.Texture2DSpecCase.call(
1890             this, name, desc, gluTextureUtil.mapGLTransferFormat(
1891                 format, dataType
1892             ), width, height, es3fTextureSpecificationTests.maxLevelCount(
1893                 width, height
1894             )
1895         );
1897         this.m_format = format;
1898         this.m_internalFormat = format;
1899         this.m_dataType = dataType;
1900     };
1902     es3fTextureSpecificationTests.BasicTexSubImage2DCase.prototype =
1903     Object.create(es3fTextureSpecificationTests.Texture2DSpecCase.prototype);
1905     es3fTextureSpecificationTests.BasicTexSubImage2DCase.prototype.constructor =
1906         es3fTextureSpecificationTests.BasicTexSubImage2DCase;
1908     /**
1909      * @param {string} name
1910      * @param {string} desc
1911      * @param {number} internalFormat
1912      * @param {number} width
1913      * @param {number} height
1914      * @return {es3fTextureSpecificationTests.BasicTexSubImage2DCase}
1915      */
1916     es3fTextureSpecificationTests.newBasicTexSubImage2DCaseInternal =
1917     function(name, desc, internalFormat, width, height) {
1918         // Sized internal format.
1919         var fmt = gluTextureUtil.getTransferFormat(
1920             gluTextureUtil.mapGLInternalFormat(internalFormat)
1921         );
1922         var testcase = new es3fTextureSpecificationTests.BasicTexSubImage2DCase(
1923             name, desc, fmt.format, fmt.dataType, width, height
1924         );
1925         testcase.m_internalFormat = internalFormat;
1926         return testcase;
1927     };
1929     /**
1930      */
1931     es3fTextureSpecificationTests.
1932     BasicTexSubImage2DCase.prototype.createTexture = function() {
1933         var tex = null;
1934         var data = new tcuTexture.TextureLevel(
1935             this.m_texFormat, this.m_width, this.m_height
1936         );
1937         var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
1939         tex = this.m_context.createTexture();
1940         this.m_context.bindTexture(gl.TEXTURE_2D, tex);
1941         this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
1943         for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
1944             var levelW = Math.max(1, this.m_width >> ndx);
1945             var levelH = Math.max(1, this.m_height >> ndx);
1946             var gMin = es3fTextureSpecificationTests.randomVector(
1947                 rnd, this.m_texFormatInfo.valueMin,
1948                 this.m_texFormatInfo.valueMax, 4
1949             );
1950             var gMax = es3fTextureSpecificationTests.randomVector(
1951                 rnd, this.m_texFormatInfo.valueMin,
1952                 this.m_texFormatInfo.valueMax, 4
1953             );
1955             data.setSize(levelW, levelH);
1956             tcuTextureUtil.fillWithComponentGradients(
1957                 data.getAccess(), gMin, gMax
1958             );
1960             this.m_context.texImage2D(
1961                 gl.TEXTURE_2D, ndx, this.m_internalFormat, levelW, levelH, 0,
1962                 this.m_format, this.m_dataType,
1963                 data.getAccess().getDataPtr()
1964             );
1965         }
1967         for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
1968             var levelW = Math.max(1, this.m_width >> ndx);
1969             var levelH = Math.max(1, this.m_height >> ndx);
1971             var w = rnd.getInt(1, levelW);
1972             var h = rnd.getInt(1, levelH);
1973             var x = rnd.getInt(0, levelW - w);
1974             var y = rnd.getInt(0, levelH - h);
1976             var colorA = es3fTextureSpecificationTests.randomVector(
1977                 rnd, this.m_texFormatInfo.valueMin,
1978                 this.m_texFormatInfo.valueMax, 4
1979             );
1980             var colorB = es3fTextureSpecificationTests.randomVector(
1981                 rnd, this.m_texFormatInfo.valueMin,
1982                 this.m_texFormatInfo.valueMax, 4
1983             );
1984             var cellSize = rnd.getInt(2, 16);
1986             data.setSize(w, h);
1987             tcuTextureUtil.fillWithGrid(
1988                 data.getAccess(), cellSize, colorA, colorB
1989             );
1991             this.m_context.texSubImage2D(
1992                 gl.TEXTURE_2D, ndx, x, y, w, h, this.m_format, this.m_dataType,
1993                 data.getAccess().getDataPtr()
1994             );
1995         }
1996     };
1998     /**
1999      * @constructor
2000      * @extends {es3fTextureSpecificationTests.TextureCubeSpecCase}
2001      * @param {string} name
2002      * @param {string} desc
2003      * @param {number} format
2004      * @param {number} dataType
2005      * @param {number} size
2006      */
2007     es3fTextureSpecificationTests.BasicTexSubImageCubeCase = function(
2008         name, desc, format, dataType, size
2009     ) {
2010         es3fTextureSpecificationTests.TextureCubeSpecCase.call(
2011             this, name, desc, gluTextureUtil.mapGLTransferFormat(
2012                 format, dataType
2013             ), size, deMath.logToFloor(size) + 1
2014         );
2016         this.m_internalFormat = format;
2017         this.m_format = format;
2018         this.m_dataType = dataType;
2019     };
2021     es3fTextureSpecificationTests.BasicTexSubImageCubeCase.prototype =
2022     Object.create(es3fTextureSpecificationTests.TextureCubeSpecCase.prototype);
2024     es3fTextureSpecificationTests.
2025     BasicTexSubImageCubeCase.prototype.constructor =
2026         es3fTextureSpecificationTests.BasicTexSubImageCubeCase;
2028     /**
2029      * @param {string} name
2030      * @param {string} desc
2031      * @param {number} internalFormat
2032      * @param {number} size
2033      */
2034     es3fTextureSpecificationTests.newBasicTexSubImageCubeCaseInternal =
2035     function(name, desc, internalFormat, size) {
2036         // Sized internal format.
2037         var fmt = gluTextureUtil.getTransferFormat(
2038             gluTextureUtil.mapGLInternalFormat(internalFormat)
2039         );
2040         var testcase =
2041             new es3fTextureSpecificationTests.BasicTexSubImageCubeCase(
2042             name, desc, fmt.format, fmt.dataType,
2043             size);
2044         testcase.m_internalFormat = internalFormat;
2045         return testcase;
2046     };
2048     /**
2049      * createTexture
2050      */
2051     es3fTextureSpecificationTests.
2052     BasicTexSubImageCubeCase.prototype.createTexture = function() {
2053         var tex = null;
2054         var data = new tcuTexture.TextureLevel(
2055             this.m_texFormat, this.m_size, this.m_size
2056         );
2057         var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
2059         tex = this.m_context.createTexture();
2060         this.m_context.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
2061         this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
2063         for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
2064             var levelSize = Math.max(1, this.m_size >> ndx);
2065             data.setSize(levelSize, levelSize);
2067             for (var face = /** @type {tcuTexture.CubeFace} */ (0);
2068                 face < es3fTextureSpecificationTests.s_cubeMapFaces.length;
2069                 face++) {
2070                 var gMin = es3fTextureSpecificationTests.randomVector(
2071                     rnd, this.m_texFormatInfo.valueMin,
2072                     this.m_texFormatInfo.valueMax, 4
2073                 );
2074                 var gMax = es3fTextureSpecificationTests.randomVector(
2075                     rnd, this.m_texFormatInfo.valueMin,
2076                     this.m_texFormatInfo.valueMax, 4
2077                 );
2079                 tcuTextureUtil.fillWithComponentGradients(
2080                     data.getAccess(), gMin, gMax
2081                 );
2083                 this.m_context.texImage2D(
2084                     es3fTextureSpecificationTests.s_cubeMapFaces[face], ndx,
2085                     this.m_internalFormat, levelSize, levelSize, 0,
2086                     this.m_format, this.m_dataType,
2087                     data.getAccess().getDataPtr()
2088                 );
2089             }
2090         }
2092         // Re-specify parts of each face and level.
2093         for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
2094             var levelSize = Math.max(1, this.m_size >> ndx);
2096             for (var f in tcuTexture.CubeFace) {
2097                 var face = tcuTexture.CubeFace[f];
2099                 var w = rnd.getInt(1, levelSize);
2100                 var h = rnd.getInt(1, levelSize);
2101                 var x = rnd.getInt(0, levelSize - w);
2102                 var y = rnd.getInt(0, levelSize - h);
2104                 var colorA = es3fTextureSpecificationTests.randomVector(
2105                     rnd, this.m_texFormatInfo.valueMin,
2106                     this.m_texFormatInfo.valueMax, 4
2107                 );
2108                 var colorB = es3fTextureSpecificationTests.randomVector(
2109                     rnd, this.m_texFormatInfo.valueMin,
2110                     this.m_texFormatInfo.valueMax, 4
2111                 );
2112                 var cellSize = rnd.getInt(2, 16);
2114                 data.setSize(w, h);
2115                 tcuTextureUtil.fillWithGrid(
2116                     data.getAccess(), cellSize, colorA, colorB
2117                 );
2119                 this.m_context.texSubImage2D(
2120                     es3fTextureSpecificationTests.s_cubeMapFaces[face],
2121                     ndx, x, y, w, h, this.m_format,
2122                     this.m_dataType, data.getAccess().getDataPtr()
2123                 );
2124             }
2125         }
2126     };
2128     // TexSubImage2D() unpack parameters case.
2129     /**
2130      * @constructor
2131      * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
2132      * @param {string} name
2133      * @param {string} desc
2134      * @param {number} internalFormat
2135      * @param {number} width
2136      * @param {number} height
2137      * @param {number} subX
2138      * @param {number} subY
2139      * @param {number} subW
2140      * @param {number} subH
2141      * @param {number} rowLength
2142      * @param {number} skipRows
2143      * @param {number} skipPixels
2144      * @param {number} alignment
2145      */
2146     es3fTextureSpecificationTests.TexSubImage2DParamsCase = function(
2147         name, desc, internalFormat, width, height, subX, subY, subW, subH,
2148         rowLength, skipRows, skipPixels, alignment
2149     ) {
2150         es3fTextureSpecificationTests.Texture2DSpecCase.call(
2151             this, name, desc,
2152             gluTextureUtil.mapGLInternalFormat(internalFormat),
2153             width, height, 1
2154         );
2155         this.m_internalFormat = internalFormat;
2156         this.m_subX = subX;
2157         this.m_subY = subY;
2158         this.m_subW = subW;
2159         this.m_subH = subH;
2160         this.m_rowLength = rowLength;
2161         this.m_skipRows = skipRows;
2162         this.m_skipPixels = skipPixels;
2163         this.m_alignment = alignment;
2164     };
2166     es3fTextureSpecificationTests.TexSubImage2DParamsCase.prototype =
2167         Object.create(
2168             es3fTextureSpecificationTests.Texture2DSpecCase.prototype
2169         );
2171     es3fTextureSpecificationTests.
2172     TexSubImage2DParamsCase.prototype.constructor =
2173         es3fTextureSpecificationTests.TexSubImage2DParamsCase;
2175     /**
2176      * createTexture
2177      */
2178     es3fTextureSpecificationTests.
2179     TexSubImage2DParamsCase.prototype.createTexture = function() {
2180         var transferFmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
2181         var pixelSize = this.m_texFormat.getPixelSize();
2182         var tex = null;
2183         /** @type {ArrayBuffer} */ var data;
2185         assertMsgOptions(
2186             this.m_numLevels == 1, 'Number of levels different to 1',
2187             false, true
2188         );
2190         tex = this.m_context.createTexture();
2191         this.m_context.bindTexture(gl.TEXTURE_2D, tex);
2193         // First fill texture with gradient.
2194         data = new ArrayBuffer(
2195             deMath.deAlign32(this.m_width * pixelSize, 4) * this.m_height
2196         );
2197         var access = new tcuTexture.PixelBufferAccess({
2198                 format: this.m_texFormat,
2199                 width: this.m_width,
2200                 height: this.m_height,
2201                 rowPitch: deMath.deAlign32(this.m_width * pixelSize, 4),
2202                 data: data
2203             });
2204         tcuTextureUtil.fillWithComponentGradients(access, this.m_texFormatInfo.valueMin, this.m_texFormatInfo.valueMax
2205         );
2206         this.m_context.texImage2D(
2207             gl.TEXTURE_2D, 0, this.m_internalFormat, this.m_width,
2208             this.m_height, 0, transferFmt.format, transferFmt.dataType,
2209             access.getDataPtr()
2210         );
2212         // Fill data with grid.
2213         var rowLength = this.m_rowLength > 0 ? this.m_rowLength : this.m_subW;
2214         var rowPitch = deMath.deAlign32(rowLength * pixelSize, this.m_alignment);
2215         var height = this.m_subH + this.m_skipRows;
2216         var cScale = deMath.subtract(
2217             this.m_texFormatInfo.valueMax, this.m_texFormatInfo.valueMin
2218         );
2219         var cBias = this.m_texFormatInfo.valueMin;
2220         var colorA = deMath.add(
2221             deMath.multiply(
2222                 [1.0, 0.0, 0.0, 1.0], cScale
2223             ), cBias
2224         );
2225         var colorB = deMath.add(
2226             deMath.multiply(
2227                 [0.0, 1.0, 0.0, 1.0], cScale
2228             ), cBias
2229         );
2231         data = new ArrayBuffer(rowPitch * height + this.m_skipPixels * pixelSize);
2232         tcuTextureUtil.fillWithGrid(
2233             new tcuTexture.PixelBufferAccess({
2234                 format: this.m_texFormat,
2235                 width: this.m_subW,
2236                 height: this.m_subH,
2237                 rowPitch: rowPitch,
2238                 data: data,
2239                 offset: this.m_skipRows * rowPitch + this.m_skipPixels * pixelSize
2240                 }) ,
2241             4, colorA, colorB
2242         );
2244         access = new tcuTexture.PixelBufferAccess({
2245                 format: this.m_texFormat,
2246                 width: this.m_subW,
2247                 height: this.m_subH,
2248                 rowPitch: rowPitch,
2249                 data: data
2250             });
2251         this.m_context.pixelStorei(gl.UNPACK_ROW_LENGTH, this.m_rowLength);
2252         this.m_context.pixelStorei(gl.UNPACK_SKIP_ROWS, this.m_skipRows);
2253         this.m_context.pixelStorei(gl.UNPACK_SKIP_PIXELS, this.m_skipPixels);
2254         this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
2255         this.m_context.texSubImage2D(
2256             gl.TEXTURE_2D, 0, this.m_subX, this.m_subY,
2257             this.m_subW, this.m_subH,
2258             transferFmt.format, transferFmt.dataType,
2259             access.getDataPtr()
2260         );
2261     };
2263     // Basic TexSubImage3D() with 3D texture usage
2264     /**
2265      * @constructor
2266      * @extends {es3fTextureSpecificationTests.Texture3DSpecCase}
2267      * @param {string} name
2268      * @param {string} desc
2269      * @param {number} internalFormat
2270      * @param {number} width
2271      * @param {number} height
2272      * @param {number} depth
2273      */
2274     es3fTextureSpecificationTests.BasicTexSubImage3DCase = function(
2275         name, desc, internalFormat, width, height, depth
2276     ) {
2277         es3fTextureSpecificationTests.Texture3DSpecCase.call(
2278             this, name, desc,
2279             gluTextureUtil.mapGLInternalFormat(internalFormat),
2280             width, height, depth, es3fTextureSpecificationTests.maxLevelCount(
2281                 width, height, depth
2282             )
2283         );
2285         this.m_internalFormat = internalFormat;
2286     };
2288     es3fTextureSpecificationTests.BasicTexSubImage3DCase.prototype =
2289         Object.create(
2290             es3fTextureSpecificationTests.Texture3DSpecCase.prototype
2291         );
2293     es3fTextureSpecificationTests.BasicTexSubImage3DCase.prototype.constructor =
2294     es3fTextureSpecificationTests.BasicTexSubImage3DCase;
2296     /**
2297      * createTexture
2298      */
2299     es3fTextureSpecificationTests.
2300     BasicTexSubImage3DCase.prototype.createTexture = function() {
2301         var tex = null;
2302         var data = new tcuTexture.TextureLevel(
2303             this.m_texFormat, this.m_width, this.m_height
2304         );
2305         var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
2306         var transferFmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
2308         tex = this.m_context.createTexture();
2309         this.m_context.bindTexture(gl.TEXTURE_3D, tex);
2310         this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
2312         // First specify full texture.
2313         for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
2314             var levelW = Math.max(1, this.m_width >> ndx);
2315             var levelH = Math.max(1, this.m_height >> ndx);
2316             var levelD = Math.max(1, this.m_depth >> ndx);
2318             var gMin = es3fTextureSpecificationTests.randomVector(
2319                 rnd, this.m_texFormatInfo.valueMin,
2320                 this.m_texFormatInfo.valueMax, 4
2321             );
2322             var gMax = es3fTextureSpecificationTests.randomVector(
2323                 rnd, this.m_texFormatInfo.valueMin,
2324                 this.m_texFormatInfo.valueMax, 4
2325             );
2327             data.setSize(levelW, levelH, levelD);
2328             tcuTextureUtil.fillWithComponentGradients(
2329                 data.getAccess(), gMin, gMax
2330             );
2332             this.m_context.texImage3D(
2333                 gl.TEXTURE_3D, ndx, this.m_internalFormat, levelW, levelH,
2334                 levelD, 0, transferFmt.format, transferFmt.dataType,
2335                 data.getAccess().getDataPtr()
2336             );
2337         }
2339         // Re-specify parts of each level.
2340         for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
2341             var levelW = Math.max(1, this.m_width >> ndx);
2342             var levelH = Math.max(1, this.m_height >> ndx);
2343             var levelD = Math.max(1, this.m_depth >> ndx);
2345             var w = rnd.getInt(1, levelW);
2346             var h = rnd.getInt(1, levelH);
2347             var d = rnd.getInt(1, levelD);
2348             var x = rnd.getInt(0, levelW - w);
2349             var y = rnd.getInt(0, levelH - h);
2350             var z = rnd.getInt(0, levelD - d);
2352             var colorA = es3fTextureSpecificationTests.randomVector(
2353                 rnd, this.m_texFormatInfo.valueMin,
2354                 this.m_texFormatInfo.valueMax, 4
2355             );
2356             var colorB = es3fTextureSpecificationTests.randomVector(
2357                 rnd, this.m_texFormatInfo.valueMin,
2358                 this.m_texFormatInfo.valueMax, 4
2359             );
2360             var cellSize = rnd.getInt(2, 16);
2362             data.setSize(w, h, d);
2363             tcuTextureUtil.fillWithGrid(
2364                 data.getAccess(), cellSize, colorA, colorB
2365             );
2367             this.m_context.texSubImage3D(
2368                 gl.TEXTURE_3D, ndx, x, y, z, w, h, d,
2369                 transferFmt.format, transferFmt.dataType,
2370                 data.getAccess().getDataPtr()
2371             );
2372         }
2373     };
2375     // TexSubImage2D() to texture initialized with empty data
2376     /**
2377      * @constructor
2378      * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
2379      * @param {string} name
2380      * @param {string} desc
2381      * @param {number} format
2382      * @param {number} dataType
2383      * @param {number} width
2384      * @param {number} height
2385      */
2386     es3fTextureSpecificationTests.TexSubImage2DEmptyTexCase = function(
2387         name, desc, format, dataType, width, height
2388     ) {
2389         es3fTextureSpecificationTests.Texture2DSpecCase.call(
2390             this, name, desc, gluTextureUtil.mapGLTransferFormat(
2391                 format, dataType
2392             ), width, height, es3fTextureSpecificationTests.maxLevelCount(
2393                 width, height
2394             )
2395         );
2397         this.m_format = format;
2398         this.m_internalFormat = format;
2399         this.m_dataType = dataType;
2400     };
2402     es3fTextureSpecificationTests.TexSubImage2DEmptyTexCase.prototype =
2403     Object.create(es3fTextureSpecificationTests.Texture2DSpecCase.prototype);
2405     es3fTextureSpecificationTests.
2406     TexSubImage2DEmptyTexCase.prototype.constructor =
2407         es3fTextureSpecificationTests.TexSubImage2DEmptyTexCase;
2409     /**
2410      * @param {string} name
2411      * @param {string} desc
2412      * @param {number} internalFormat
2413      * @param {number} width
2414      * @param {number} height
2415      */
2416     es3fTextureSpecificationTests.newTexSubImage2DEmptyTexCaseInternal =
2417     function(name, desc, internalFormat, width, height) {
2418         // Sized internal format.
2419         var fmt = gluTextureUtil.getTransferFormat(
2420             gluTextureUtil.mapGLInternalFormat(internalFormat)
2421         );
2422         var testcase =
2423             new es3fTextureSpecificationTests.TexSubImage2DEmptyTexCase(
2424                 name, desc, fmt.format, fmt.dataType, width, height
2425             );
2426         testcase.m_internalFormat = internalFormat;
2427         return testcase;
2428     };
2430     /**
2431      * createTexture
2432      */
2433     es3fTextureSpecificationTests.
2434     TexSubImage2DEmptyTexCase.prototype.createTexture = function() {
2435         var tex = null;
2436         var data = new tcuTexture.TextureLevel(
2437             this.m_texFormat, this.m_width, this.m_height
2438         );
2439         var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
2441         tex = this.m_context.createTexture();
2442         this.m_context.bindTexture(gl.TEXTURE_2D, tex);
2443         this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
2445         // First allocate storage for each level.
2446         for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
2447             var levelW = Math.max(1, this.m_width >> ndx);
2448             var levelH = Math.max(1, this.m_height >> ndx);
2450             this.m_context.texImage2D(
2451                 gl.TEXTURE_2D, ndx, this.m_internalFormat, levelW, levelH, 0,
2452                 this.m_format, this.m_dataType,
2453                 null
2454             );
2455         }
2457         // Specify pixel data to all levels using glTexSubImage2D()
2458         for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
2459             var levelW = Math.max(1, this.m_width >> ndx);
2460             var levelH = Math.max(1, this.m_height >> ndx);
2461             var gMin = es3fTextureSpecificationTests.randomVector(
2462                 rnd, this.m_texFormatInfo.valueMin,
2463                 this.m_texFormatInfo.valueMax, 4
2464             );
2465             var gMax = es3fTextureSpecificationTests.randomVector(
2466                 rnd, this.m_texFormatInfo.valueMin,
2467                 this.m_texFormatInfo.valueMax, 4
2468             );
2470             data.setSize(levelW, levelH);
2471             tcuTextureUtil.fillWithComponentGradients(
2472                 data.getAccess(), gMin, gMax
2473             );
2475             this.m_context.texSubImage2D(
2476                 gl.TEXTURE_2D, ndx, 0, 0, levelW, levelH,
2477                 this.m_format, this.m_dataType,
2478                 data.getAccess().getDataPtr()
2479             );
2480         }
2481     };
2483     // TexSubImage2D() to empty cubemap texture
2484     /**
2485      * @constructor
2486      * @extends {es3fTextureSpecificationTests.TextureCubeSpecCase}
2487      * @param {string} name
2488      * @param {string} desc
2489      * @param {number} format
2490      * @param {number} dataType
2491      * @param {number} size
2492      */
2493     es3fTextureSpecificationTests.TexSubImageCubeEmptyTexCase = function(
2494         name, desc, format, dataType, size
2495     ) {
2496         // Unsized internal format.
2497         es3fTextureSpecificationTests.TextureCubeSpecCase.call(
2498             this, name, desc, gluTextureUtil.mapGLTransferFormat(
2499                 format, dataType
2500             ), size, deMath.logToFloor(size) + 1
2501         );
2503         this.m_internalFormat = format;
2504         this.m_format = format;
2505         this.m_dataType = dataType;
2506     };
2508     es3fTextureSpecificationTests.TexSubImageCubeEmptyTexCase.prototype =
2509         Object.create(
2510             es3fTextureSpecificationTests.TextureCubeSpecCase.prototype
2511         );
2513     es3fTextureSpecificationTests.
2514     TexSubImageCubeEmptyTexCase.prototype.constructor =
2515         es3fTextureSpecificationTests.TexSubImageCubeEmptyTexCase;
2517     /**
2518      * @param {string} name
2519      * @param {string} desc
2520      * @param {number} internalFormat
2521      * @param {number} size
2522      * @return {es3fTextureSpecificationTests.TexSubImageCubeEmptyTexCase}
2523      */
2524     es3fTextureSpecificationTests.newTexSubImageCubeEmptyTexCaseInternal =
2525     function(name, desc, internalFormat, size) {
2526         // Sized internal format.
2527         var fmt = gluTextureUtil.getTransferFormat(
2528             gluTextureUtil.mapGLInternalFormat(internalFormat)
2529         );
2530         var testcase =
2531             new es3fTextureSpecificationTests.TexSubImageCubeEmptyTexCase(
2532                 name, desc, fmt.format, fmt.dataType, size
2533             );
2534         testcase.m_internalFormat = internalFormat;
2535         return testcase;
2536     };
2538     /**
2539      * createTexture
2540      */
2541     es3fTextureSpecificationTests.
2542     TexSubImageCubeEmptyTexCase.prototype.createTexture =
2543     function() {
2544         var tex = null;
2545         var data = new tcuTexture.TextureLevel(
2546             this.m_texFormat, this.m_size, this.m_size
2547         );
2548         var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
2550         tex = this.m_context.createTexture();
2551         this.m_context.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
2552         this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
2554         // Specify storage for each level.
2555         for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
2556             var levelSize = Math.max(1, this.m_size >> ndx);
2558             for (var f in tcuTexture.CubeFace) {
2559                 var face = tcuTexture.CubeFace[f];
2560                 this.m_context.texImage2D(
2561                     es3fTextureSpecificationTests.s_cubeMapFaces[face],
2562                     ndx, this.m_internalFormat, levelSize, levelSize, 0,
2563                     this.m_format, this.m_dataType,
2564                     null
2565                 );
2566             }
2567         }
2569         // Specify data using glTexSubImage2D()
2570         for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
2571             var levelSize = Math.max(1, this.m_size >> ndx);
2573             data.setSize(levelSize, levelSize);
2575             for (var f in tcuTexture.CubeFace) {
2576                 var face = tcuTexture.CubeFace[f];
2577                 var gMin = es3fTextureSpecificationTests.randomVector(
2578                     rnd, this.m_texFormatInfo.valueMin,
2579                     this.m_texFormatInfo.valueMax, 4
2580                 );
2581                 var gMax = es3fTextureSpecificationTests.randomVector(
2582                     rnd, this.m_texFormatInfo.valueMin,
2583                     this.m_texFormatInfo.valueMax, 4
2584                 );
2586                 tcuTextureUtil.fillWithComponentGradients(
2587                     data.getAccess(), gMin, gMax
2588                 );
2590                 this.m_context.texSubImage2D(
2591                     es3fTextureSpecificationTests.s_cubeMapFaces[face],
2592                     ndx, 0, 0, levelSize, levelSize, this.m_format,
2593                     this.m_dataType, data.getAccess().getDataPtr()
2594                 );
2595             }
2596         }
2597     };
2599     // TexSubImage2D() unpack alignment with 2D texture
2600     /**
2601      * @constructor
2602      * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
2603      * @param {string} name
2604      * @param {string} desc
2605      * @param {number} format
2606      * @param {number} dataType
2607      * @param {number} width
2608      * @param {number} height
2609      * @param {number} subX
2610      * @param {number} subY
2611      * @param {number} subW
2612      * @param {number} subH
2613      * @param {number} alignment
2614      */
2615     es3fTextureSpecificationTests.TexSubImage2DAlignCase = function(
2616         name, desc, format, dataType, width, height, subX, subY, subW, subH,
2617         alignment
2618     ) {
2619         // Unsized internal format.
2620         es3fTextureSpecificationTests.Texture2DSpecCase.call(
2621             this, name, desc, gluTextureUtil.mapGLTransferFormat(
2622                 format, dataType
2623             ), width, height, 1
2624         );
2626         this.m_internalFormat = format;
2627         this.m_format = format;
2628         this.m_dataType = dataType;
2629         this.m_subX = subX;
2630         this.m_subY = subY;
2631         this.m_subW = subW;
2632         this.m_subH = subH;
2633         this.m_alignment = alignment;
2634     };
2636     es3fTextureSpecificationTests.TexSubImage2DAlignCase.prototype =
2637         Object.create(
2638             es3fTextureSpecificationTests.Texture2DSpecCase.prototype
2639         );
2641     es3fTextureSpecificationTests.
2642     TexSubImage2DAlignCase.prototype.constructor =
2643         es3fTextureSpecificationTests.TexSubImage2DAlignCase;
2645     /**
2646      * @param {string} name
2647      * @param {string} desc
2648      * @param {number} internalFormat
2649      * @param {number} width
2650      * @param {number} height
2651      * @param {number} subX
2652      * @param {number} subY
2653      * @param {number} subW
2654      * @param {number} subH
2655      * @param {number} alignment
2656      * @return {es3fTextureSpecificationTests.TexSubImage2DAlignCase}
2657      */
2658     es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal = function(
2659         name, desc, internalFormat, width, height, subX, subY, subW, subH,
2660         alignment
2661     ) {
2662         // Sized internal format.
2663         var fmt = gluTextureUtil.getTransferFormat(
2664             gluTextureUtil.mapGLInternalFormat(internalFormat)
2665         );
2666         var testcase = new es3fTextureSpecificationTests.TexSubImage2DAlignCase(
2667             name, desc, fmt.format, fmt.dataType,
2668             width, height, subX, subY, subW, subH, alignment
2669         );
2670         testcase.m_internalFormat = internalFormat;
2671         return testcase;
2672     };
2674     /**
2675      * createTexture
2676      */
2677     es3fTextureSpecificationTests.
2678     TexSubImage2DAlignCase.prototype.createTexture = function() {
2679         var tex = null;
2680         /** @type {ArrayBuffer} */ var data;
2682         tex = this.m_context.createTexture();
2683         this.m_context.bindTexture(gl.TEXTURE_2D, tex);
2685         // Specify base level.
2686         data = new ArrayBuffer(this.m_texFormat.getPixelSize() *
2687             this.m_width * this.m_height
2688         );
2689         var access = new tcuTexture.PixelBufferAccess({
2690                 format: this.m_texFormat,
2691                 width: this.m_width,
2692                 height: this.m_height,
2693                 data: data
2694             });
2695         tcuTextureUtil.fillWithComponentGradients(access, [0, 0, 0, 0], [1, 1, 1, 1]);
2697         this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
2698         this.m_context.texImage2D(gl.TEXTURE_2D, 0, this.m_internalFormat,
2699             this.m_width, this.m_height, 0, this.m_format, this.m_dataType,
2700             access.getDataPtr()
2701         );
2703         // Re-specify subrectangle.
2704         var rowPitch = deMath.deAlign32(
2705             this.m_texFormat.getPixelSize() * this.m_subW, this.m_alignment
2706         );
2707         data = new ArrayBuffer(rowPitch * this.m_subH);
2708         access = new tcuTexture.PixelBufferAccess({
2709                 format: this.m_texFormat,
2710                 width: this.m_subW,
2711                 height: this.m_subH,
2712                 rowPitch: rowPitch,
2713                 data: data
2714             });
2715         tcuTextureUtil.fillWithGrid(access, 4, [1, 0, 0, 1], [0, 1, 0, 1]
2716         );
2718         this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
2719         this.m_context.texSubImage2D(
2720             gl.TEXTURE_2D, 0, this.m_subX, this.m_subY, this.m_subW,
2721             this.m_subH, this.m_format, this.m_dataType, access.getDataPtr()
2722         );
2723     };
2725     // TexSubImage2D() unpack alignment with cubemap texture
2726     /**
2727      * @constructor
2728      * @extends {es3fTextureSpecificationTests.TextureCubeSpecCase}
2729      * @param {string} name
2730      * @param {string} desc
2731      * @param {number} format
2732      * @param {number} dataType
2733      * @param {number} size
2734      * @param {number} subX
2735      * @param {number} subY
2736      * @param {number} subW
2737      * @param {number} subH
2738      * @param {number} alignment
2739      */
2740     es3fTextureSpecificationTests.TexSubImageCubeAlignCase = function(
2741         name, desc, format, dataType, size, subX, subY, subW, subH, alignment
2742     ) {
2743         // Unsized internal format.
2744         es3fTextureSpecificationTests.TextureCubeSpecCase.call(
2745             this, name, desc, gluTextureUtil.mapGLTransferFormat(
2746                 format, dataType
2747             ), size, 1
2748         );
2750         this.m_internalFormat = format;
2751         this.m_format = format;
2752         this.m_dataType = dataType;
2753         this.m_subX = subX;
2754         this.m_subY = subY;
2755         this.m_subW = subW;
2756         this.m_subH = subH;
2757         this.m_alignment = alignment;
2758     };
2760     es3fTextureSpecificationTests.TexSubImageCubeAlignCase.prototype =
2761         Object.create(
2762             es3fTextureSpecificationTests.TextureCubeSpecCase.prototype
2763         );
2765     es3fTextureSpecificationTests.
2766     TexSubImageCubeAlignCase.prototype.constructor =
2767         es3fTextureSpecificationTests.TexSubImageCubeAlignCase;
2769     /**
2770      * @param {string} name
2771      * @param {string} desc
2772      * @param {number} internalFormat
2773      * @param {number} size
2774      * @param {number} subX
2775      * @param {number} subY
2776      * @param {number} subW
2777      * @param {number} subH
2778      * @param {number} alignment
2779      * @return {es3fTextureSpecificationTests.TexSubImageCubeAlignCase}
2780      */
2781     es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal =
2782     function(
2783         name, desc, internalFormat, size,
2784         subX, subY, subW, subH, alignment
2785     ) {
2786         // Sized internal format.
2787         var fmt = gluTextureUtil.getTransferFormat(
2788             gluTextureUtil.mapGLInternalFormat(internalFormat)
2789         );
2790         var testcase =
2791             new es3fTextureSpecificationTests.TexSubImageCubeAlignCase(
2792                 name, desc, fmt.format, fmt.dataType, size,
2793                 subX, subY, subW, subH, alignment
2794             );
2795         testcase.m_internalFormat = internalFormat;
2796         return testcase;
2797     };
2799     /**
2800      * createTexture
2801      */
2802     es3fTextureSpecificationTests.
2803     TexSubImageCubeAlignCase.prototype.createTexture =
2804     function() {
2805         var tex = null;
2806         tex = this.m_context.createTexture();
2807         this.m_context.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
2809         var data = new ArrayBuffer(this.m_texFormat.getPixelSize() * this.m_size * this.m_size);
2810         var access = new tcuTexture.PixelBufferAccess({
2811                 format: this.m_texFormat,
2812                 width: this.m_size,
2813                 height: this.m_size,
2814                 data: data
2815             });
2816         tcuTextureUtil.fillWithComponentGradients(access, [0, 0, 0, 0], [1, 1, 1, 1]
2817         );
2819         this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
2820         for (var f in tcuTexture.CubeFace) {
2821             var face = tcuTexture.CubeFace[f];
2822             this.m_context.texImage2D(
2823                 es3fTextureSpecificationTests.s_cubeMapFaces[face],
2824                 0, this.m_internalFormat, this.m_size, this.m_size, 0,
2825                 this.m_format, this.m_dataType,
2826                 access.getDataPtr()
2827             );
2828         }
2830         // Re-specify subrectangle.
2831         var rowPitch = deMath.deAlign32(
2832             this.m_texFormat.getPixelSize() * this.m_subW, this.m_alignment
2833         );
2834         data = new ArrayBuffer(rowPitch * this.m_subH);
2835         access = new tcuTexture.PixelBufferAccess({
2836                 format: this.m_texFormat,
2837                 width: this.m_subW,
2838                 height: this.m_subH,
2839                 rowPitch: rowPitch,
2840                 data: data
2841         });
2842         tcuTextureUtil.fillWithGrid(access, 4, [1, 0, 0, 1], [0, 1, 0, 1]
2843         );
2844         this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
2845         for (var f in tcuTexture.CubeFace) {
2846             var face = tcuTexture.CubeFace[f];
2847             this.m_context.texSubImage2D(
2848                 es3fTextureSpecificationTests.s_cubeMapFaces[face],
2849                 0, this.m_subX, this.m_subY, this.m_subW, this.m_subH,
2850                 this.m_format, this.m_dataType, access.getDataPtr()
2851             );
2852         }
2853     };
2855     // TexSubImage3D() unpack parameters case.
2856     /**
2857      * @constructor
2858      * @extends {es3fTextureSpecificationTests.Texture3DSpecCase}
2859      * @param {string} name
2860      * @param {string} desc
2861      * @param {number} internalFormat
2862      * @param {number} width
2863      * @param {number} height
2864      * @param {number} depth
2865      * @param {number} subX ,
2866      * @param {number} subY ,
2867      * @param {number} subZ ,
2868      * @param {number} subW ,
2869      * @param {number} subH ,
2870      * @param {number} subD ,
2871      * @param {number} imageHeight ,
2872      * @param {number} rowLength ,
2873      * @param {number} skipImages ,
2874      * @param {number} skipRows ,
2875      * @param {number} skipPixels ,
2876      * @param {number} alignment
2877      */
2878     es3fTextureSpecificationTests.TexSubImage3DParamsCase = function(
2879         name, desc, internalFormat, width, height, depth,
2880         subX, subY, subZ, subW, subH, subD,
2881         imageHeight, rowLength, skipImages, skipRows, skipPixels, alignment
2882     ) {
2883         es3fTextureSpecificationTests.Texture3DSpecCase.call(
2884             this, name, desc,
2885             gluTextureUtil.mapGLInternalFormat(internalFormat),
2886             width, height, depth, 1
2887         );
2889         this.m_internalFormat = internalFormat;
2890         this.m_subX = subX;
2891         this.m_subY = subY;
2892         this.m_subZ = subZ;
2893         this.m_subW = subW;
2894         this.m_subH = subH;
2895         this.m_subD = subD;
2896         this.m_imageHeight = imageHeight;
2897         this.m_rowLength = rowLength;
2898         this.m_skipImages = skipImages;
2899         this.m_skipRows = skipRows;
2900         this.m_skipPixels = skipPixels;
2901         this.m_alignment = alignment;
2902     };
2904     es3fTextureSpecificationTests.TexSubImage3DParamsCase.prototype =
2905         Object.create(
2906             es3fTextureSpecificationTests.Texture3DSpecCase.prototype
2907         );
2909     es3fTextureSpecificationTests.
2910     TexSubImage3DParamsCase.prototype.constructor =
2911         es3fTextureSpecificationTests.TexSubImage3DParamsCase;
2913     /**
2914      * createTexture
2915      */
2916     es3fTextureSpecificationTests.
2917     TexSubImage3DParamsCase.prototype.createTexture = function() {
2918         var transferFmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
2919         var pixelSize = this.m_texFormat.getPixelSize();
2920         var tex = null;
2921         var rowPitch = deMath.deAlign32(pixelSize * this.m_width, 4);
2922         var slicePitch = rowPitch * this.m_height;
2923         assertMsgOptions(
2924             this.m_numLevels == 1, 'Numbel of levels different than 1',
2925             false, true
2926         );
2928         tex = this.m_context.createTexture();
2929         this.m_context.bindTexture(gl.TEXTURE_3D, tex);
2931         // Fill with gradient.
2933         var data = new ArrayBuffer(slicePitch * this.m_depth);
2934         var access = new tcuTexture.PixelBufferAccess({
2935                             format: this.m_texFormat,
2936                             width: this.m_width,
2937                             height: this.m_height,
2938                             depth: this.m_depth,
2939                             rowPitch: rowPitch,
2940                             slicePitch: slicePitch,
2941                             data: data
2942                         });
2943         tcuTextureUtil.fillWithComponentGradients(access, this.m_texFormatInfo.valueMin, this.m_texFormatInfo.valueMax);
2945         this.m_context.texImage3D(
2946             gl.TEXTURE_3D, 0, this.m_internalFormat, this.m_width,
2947             this.m_height, this.m_depth, 0, transferFmt.format,
2948             transferFmt.dataType, access.getDataPtr()
2949         );
2951         // Fill data with grid.
2952         var rowLength = this.m_rowLength > 0 ? this.m_rowLength : this.m_subW;
2953         rowPitch = deMath.deAlign32(rowLength * pixelSize, this.m_alignment);
2954         var imageHeight = this.m_imageHeight > 0 ? this.m_imageHeight : this.m_subH;
2955         slicePitch = imageHeight * rowPitch;
2956         var cScale = deMath.subtract(this.m_texFormatInfo.valueMax, this.m_texFormatInfo.valueMin);
2957         var cBias = this.m_texFormatInfo.valueMin;
2958         var colorA = deMath.add(
2959             deMath.multiply([1.0, 0.0, 0.0, 1.0], cScale), cBias
2960         );
2961         var colorB = deMath.add(
2962             deMath.multiply([0.0, 1.0, 0.0, 1.0], cScale), cBias
2963         );
2965         data = new ArrayBuffer(slicePitch * (this.m_depth + this.m_skipImages) +
2966                                this.m_skipRows * rowPitch + this.m_skipPixels * pixelSize);
2967         var accessWithOffset = new tcuTexture.PixelBufferAccess({
2968                 format: this.m_texFormat,
2969                 width: this.m_subW,
2970                 height: this.m_subH,
2971                 depth: this.m_subD,
2972                 rowPitch: rowPitch,
2973                 slicePitch: slicePitch,
2974                 data: data,
2975                 offset: this.m_skipImages * slicePitch + this.m_skipRows * rowPitch + this.m_skipPixels * pixelSize
2976             });
2977         access = new tcuTexture.PixelBufferAccess({
2978                 format: this.m_texFormat,
2979                 width: this.m_subW,
2980                 height: this.m_subH,
2981                 depth: this.m_subD,
2982                 rowPitch: rowPitch,
2983                 slicePitch: slicePitch,
2984                 data: data
2985             });
2986         tcuTextureUtil.fillWithGrid(accessWithOffset, 4, colorA, colorB);
2988         this.m_context.pixelStorei(gl.UNPACK_IMAGE_HEIGHT, this.m_imageHeight);
2989         this.m_context.pixelStorei(gl.UNPACK_ROW_LENGTH, this.m_rowLength);
2990         this.m_context.pixelStorei(gl.UNPACK_SKIP_IMAGES, this.m_skipImages);
2991         this.m_context.pixelStorei(gl.UNPACK_SKIP_ROWS, this.m_skipRows);
2992         this.m_context.pixelStorei(gl.UNPACK_SKIP_PIXELS, this.m_skipPixels);
2993         this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
2994         this.m_context.texSubImage3D(
2995             gl.TEXTURE_3D, 0, this.m_subX, this.m_subY, this.m_subZ,
2996             this.m_subW, this.m_subH, this.m_subD,
2997             transferFmt.format, transferFmt.dataType, access.getDataPtr()
2998         );
2999     };
3001     // Basic CopyTexImage2D() with 2D texture usage
3002     /**
3003      * @constructor
3004      * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
3005      * @param {string} name
3006      * @param {string} desc
3007      * @param {number} internalFormat
3008      * @param {number} width
3009      * @param {number} height
3010      */
3011     es3fTextureSpecificationTests.BasicCopyTexImage2DCase = function(
3012         name, desc, internalFormat, width, height
3013     ) {
3014         es3fTextureSpecificationTests.Texture2DSpecCase.call(
3015             this, name, desc, gluTextureUtil.mapGLTransferFormat(
3016                 internalFormat, gl.UNSIGNED_BYTE
3017             ), width, height, es3fTextureSpecificationTests.maxLevelCount(
3018                 width, height
3019             )
3020         );
3022         this.m_internalFormat = internalFormat;
3023     };
3025     es3fTextureSpecificationTests.BasicCopyTexImage2DCase.prototype =
3026         Object.create(
3027             es3fTextureSpecificationTests.Texture2DSpecCase.prototype
3028         );
3030     es3fTextureSpecificationTests.
3031     BasicCopyTexImage2DCase.prototype.constructor =
3032         es3fTextureSpecificationTests.BasicCopyTexImage2DCase;
3034     /**
3035      * createTexture
3036      */
3037     es3fTextureSpecificationTests.
3038     BasicCopyTexImage2DCase.prototype.createTexture = function() {
3039         var pixelFormat = tcuPixelFormat.PixelFormatFromContext(gl);
3040         var targetHasRGB = pixelFormat.redBits > 0 &&
3041             pixelFormat.greenBits > 0 &&
3042             pixelFormat.blueBits > 0;
3043         var targetHasAlpha = pixelFormat.alphaBits > 0;
3044         var fmt = es3fTextureSpecificationTests.mapGLUnsizedInternalFormat(
3045                 this.m_internalFormat
3046         );
3047         var texHasRGB = fmt.order != tcuTexture.ChannelOrder.A;
3048         var texHasAlpha = fmt.order == tcuTexture.ChannelOrder.RGBA ||
3049             fmt.order == tcuTexture.ChannelOrder.LA ||
3050             fmt.order == tcuTexture.ChannelOrder.A;
3051         var tex = null;
3052         var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
3053         /** @type {es3fFboTestUtil.GradientShader} */
3054         var shader = new es3fFboTestUtil.GradientShader(
3055             gluShaderUtil.DataType.FLOAT_VEC4
3056         );
3057         var shaderID = this.m_context.createProgram(shader);
3059         if ((texHasRGB && !targetHasRGB) || (texHasAlpha && !targetHasAlpha))
3060             throw new Error(
3061                 'Copying from current framebuffer is not supported'
3062             );
3064         // Fill render target with gradient.
3065         shader.setGradient(
3066             this.m_context, shaderID, [0, 0, 0, 0], [1, 1, 1, 1]
3067         );
3068         rrUtil.drawQuad(
3069             this.m_context, shaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]
3070         );
3072         tex = this.m_context.createTexture();
3073         this.m_context.bindTexture(gl.TEXTURE_2D, tex);
3075         for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
3076             var levelW = Math.max(1, this.m_width >> ndx);
3077             var levelH = Math.max(1, this.m_height >> ndx);
3078             var x = rnd.getInt(0, this.m_width - levelW);
3079             var y = rnd.getInt(0, this.m_height - levelH);
3081             this.m_context.copyTexImage2D(
3082                 gl.TEXTURE_2D, ndx, this.m_internalFormat, x, y,
3083                 levelW, levelH, 0
3084             );
3085         }
3086     };
3088     // Basic CopyTexImage2D() with cubemap usage
3089     /**
3090      * @constructor
3091      * @extends {es3fTextureSpecificationTests.TextureCubeSpecCase}
3092      * @param {string} name
3093      * @param {string} desc
3094      * @param {number} internalFormat
3095      * @param {number} size
3096      */
3097     es3fTextureSpecificationTests.BasicCopyTexImageCubeCase = function(
3098         name, desc, internalFormat, size
3099     ) {
3100         es3fTextureSpecificationTests.TextureCubeSpecCase.call(
3101             this, name, desc, gluTextureUtil.mapGLTransferFormat(
3102                 internalFormat, gl.UNSIGNED_BYTE
3103             ), size, deMath.logToFloor(size) + 1
3104         );
3106         this.m_internalFormat = internalFormat;
3107     };
3109     es3fTextureSpecificationTests.BasicCopyTexImageCubeCase.prototype =
3110         Object.create(
3111             es3fTextureSpecificationTests.TextureCubeSpecCase.prototype
3112         );
3114     es3fTextureSpecificationTests.
3115     BasicCopyTexImageCubeCase.prototype.constructor =
3116         es3fTextureSpecificationTests.BasicCopyTexImageCubeCase;
3118     es3fTextureSpecificationTests.
3119     BasicCopyTexImageCubeCase.prototype.createTexture = function() {
3120         var pixelFormat = tcuPixelFormat.PixelFormatFromContext(gl);
3121         var targetHasRGB = pixelFormat.redBits > 0 &&
3122             pixelFormat.greenBits > 0 &&
3123             pixelFormat.blueBits > 0;
3124         var targetHasAlpha = pixelFormat.alphaBits > 0;
3125         var fmt = es3fTextureSpecificationTests.mapGLUnsizedInternalFormat(
3126                 this.m_internalFormat
3127         );
3128         var texHasRGB = fmt.order != tcuTexture.ChannelOrder.A;
3129         var texHasAlpha = fmt.order == tcuTexture.ChannelOrder.RGBA ||
3130             fmt.order == tcuTexture.ChannelOrder.LA ||
3131             fmt.order == tcuTexture.ChannelOrder.A;
3132         var tex = null;
3133         var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
3134         /** @type {es3fFboTestUtil.GradientShader} */
3135         var shader = new es3fFboTestUtil.GradientShader(
3136             gluShaderUtil.DataType.FLOAT_VEC4
3137         );
3138         var shaderID = this.m_context.createProgram(shader);
3140         if ((texHasRGB && !targetHasRGB) || (texHasAlpha && !targetHasAlpha))
3141             throw new Error(
3142                 'Copying from current framebuffer is not supported'
3143             );
3145         // Fill render target with gradient.
3146         shader.setGradient(
3147             this.m_context, shaderID, [0, 0, 0, 0], [1, 1, 1, 1]
3148         );
3149         rrUtil.drawQuad(
3150             this.m_context, shaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]
3151         );
3153         tex = this.m_context.createTexture();
3154         this.m_context.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
3156         for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
3157             var levelSize = Math.max(1, this.m_size >> ndx);
3159             for (var f in tcuTexture.CubeFace) {
3160                 var face = tcuTexture.CubeFace[f];
3161                 var x = rnd.getInt(0, this.m_size - levelSize);
3162                 var y = rnd.getInt(0, this.m_size - levelSize);
3164                 this.m_context.copyTexImage2D(
3165                     es3fTextureSpecificationTests.s_cubeMapFaces[face], ndx,
3166                     this.m_internalFormat, x, y, levelSize, levelSize, 0
3167                 );
3168             }
3169         }
3170     };
3172     // Basic CopyTexSubImage2D() with 2D texture usage
3173     /**
3174      * @constructor
3175      * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
3176      * @param {string} name
3177      * @param {string} desc
3178      * @param {number} format
3179      * @param {number} dataType
3180      * @param {number} width
3181      * @param {number} height
3182      */
3183     es3fTextureSpecificationTests.BasicCopyTexSubImage2DCase = function(
3184         name, desc, format, dataType, width, height
3185     ) {
3186         es3fTextureSpecificationTests.Texture2DSpecCase.call(
3187             this, name, desc, gluTextureUtil.mapGLTransferFormat(
3188                 format, dataType
3189             ), width, height, es3fTextureSpecificationTests.maxLevelCount(
3190                 width, height
3191             )
3192         );
3194         this.m_format = format;
3195         this.m_dataType = dataType;
3196     };
3198     es3fTextureSpecificationTests.BasicCopyTexSubImage2DCase.prototype =
3199         Object.create(
3200             es3fTextureSpecificationTests.Texture2DSpecCase.prototype
3201         );
3203     es3fTextureSpecificationTests.
3204     BasicCopyTexSubImage2DCase.prototype.constructor =
3205         es3fTextureSpecificationTests.BasicCopyTexSubImage2DCase;
3207     /**
3208      * createTexture
3209      */
3210     es3fTextureSpecificationTests.
3211     BasicCopyTexSubImage2DCase.prototype.createTexture = function() {
3212         var pixelFormat = tcuPixelFormat.PixelFormatFromContext(gl);
3213         var targetHasRGB = pixelFormat.redBits > 0 &&
3214             pixelFormat.greenBits > 0 &&
3215             pixelFormat.blueBits > 0;
3216         var targetHasAlpha = pixelFormat.alphaBits > 0;
3217         var fmt = gluTextureUtil.mapGLTransferFormat(
3218                 this.m_format, this.m_dataType
3219         );
3220         var texHasRGB = fmt.order != tcuTexture.ChannelOrder.A;
3221         var texHasAlpha = fmt.order == tcuTexture.ChannelOrder.RGBA ||
3222             fmt.order == tcuTexture.ChannelOrder.LA ||
3223             fmt.order == tcuTexture.ChannelOrder.A;
3224         var tex = null;
3225         var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
3226         /** @type {es3fFboTestUtil.GradientShader} */
3227         var shader = new es3fFboTestUtil.GradientShader(
3228             gluShaderUtil.DataType.FLOAT_VEC4
3229         );
3230         var shaderID = this.m_context.createProgram(shader);
3232         if ((texHasRGB && !targetHasRGB) || (texHasAlpha && !targetHasAlpha))
3233             throw new Error(
3234                 'Copying from current framebuffer is not supported'
3235             );
3237         tex = this.m_context.createTexture();
3238         this.m_context.bindTexture(gl.TEXTURE_2D, tex);
3239         this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
3241         // First specify full texture.
3242         for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
3243             var levelW = Math.max(1, this.m_width >> ndx);
3244             var levelH = Math.max(1, this.m_height >> ndx);
3246             var colorA = es3fTextureSpecificationTests.randomVector(
3247                 rnd, [0, 0, 0, 0], [1, 1, 1, 1], 4
3248             );
3249             var colorB = es3fTextureSpecificationTests.randomVector(
3250                 rnd, [0, 0, 0, 0], [1, 1, 1, 1], 4
3251             );
3252             var cellSize = rnd.getInt(2, 16);
3254             var data = new tcuTexture.TextureLevel(fmt, levelW, levelH);
3255             tcuTextureUtil.fillWithGrid(
3256                 data.getAccess(), cellSize, colorA, colorB
3257             );
3259             this.m_context.texImage2D(
3260                 gl.TEXTURE_2D, ndx, this.m_format, levelW, levelH, 0, this.m_format, this.m_dataType, data.getAccess().getDataPtr()
3261             );
3262         }
3264         // Fill render target with gradient.
3265         shader.setGradient(
3266             this.m_context, shaderID, [0, 0, 0, 0], [1, 1, 1, 1]
3267         );
3268         rrUtil.drawQuad(
3269             this.m_context, shaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]
3270         );
3272         // Re-specify parts of each level.
3273         for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
3274             var levelW = Math.max(1, this.m_width >> ndx);
3275             var levelH = Math.max(1, this.m_height >> ndx);
3277             var w = rnd.getInt(1, levelW);
3278             var h = rnd.getInt(1, levelH);
3279             var xo = rnd.getInt(0, levelW - w);
3280             var yo = rnd.getInt(0, levelH - h);
3282             var x = rnd.getInt(0, this.m_width - w);
3283             var y = rnd.getInt(0, this.m_height - h);
3285             this.m_context.copyTexSubImage2D(
3286                 gl.TEXTURE_2D, ndx, xo, yo, x, y, w, h
3287             );
3288         }
3289     };
3291     // Basic CopyTexSubImage2D() with cubemap usage
3292     /**
3293      * @constructor
3294      * @extends {es3fTextureSpecificationTests.TextureCubeSpecCase}
3295      * @param {string} name
3296      * @param {string} desc
3297      * @param {number} format
3298      * @param {number} dataType
3299      * @param {number} size
3300      */
3301     es3fTextureSpecificationTests.BasicCopyTexSubImageCubeCase = function(
3302         name, desc, format, dataType, size
3303     ) {
3304         es3fTextureSpecificationTests.TextureCubeSpecCase.call(
3305             this, name, desc, gluTextureUtil.mapGLTransferFormat(
3306                 format, dataType
3307             ), size, deMath.logToFloor(size) + 1
3308         );
3310         this.m_format = format;
3311         this.m_dataType = dataType;
3312     };
3314     es3fTextureSpecificationTests.BasicCopyTexSubImageCubeCase.prototype =
3315         Object.create(
3316             es3fTextureSpecificationTests.TextureCubeSpecCase.prototype
3317         );
3319     es3fTextureSpecificationTests.
3320     BasicCopyTexSubImageCubeCase.prototype.constructor =
3321         es3fTextureSpecificationTests.BasicCopyTexSubImageCubeCase;
3323     es3fTextureSpecificationTests.
3324     BasicCopyTexSubImageCubeCase.prototype.createTexture = function() {
3325         var pixelFormat = tcuPixelFormat.PixelFormatFromContext(gl);
3326         var targetHasRGB = pixelFormat.redBits > 0 &&
3327             pixelFormat.greenBits > 0 &&
3328             pixelFormat.blueBits > 0;
3329         var targetHasAlpha = pixelFormat.alphaBits > 0;
3330         var fmt = gluTextureUtil.mapGLTransferFormat(this.m_format, this.m_dataType);
3331         var texHasRGB = fmt.order != tcuTexture.ChannelOrder.A;
3332         var texHasAlpha = fmt.order == tcuTexture.ChannelOrder.RGBA ||
3333             fmt.order == tcuTexture.ChannelOrder.LA ||
3334             fmt.order == tcuTexture.ChannelOrder.A;
3335         var tex = null;
3336         var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
3337         /** @type {es3fFboTestUtil.GradientShader} */
3338         var shader = new es3fFboTestUtil.GradientShader(
3339             gluShaderUtil.DataType.FLOAT_VEC4
3340         );
3341         var shaderID = this.m_context.createProgram(shader);
3343         if ((texHasRGB && !targetHasRGB) || (texHasAlpha && !targetHasAlpha))
3344             throw new Error(
3345                 'Copying from current framebuffer is not supported'
3346             );
3348         tex = this.m_context.createTexture();
3349         this.m_context.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
3350         this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
3352         var data = new tcuTexture.TextureLevel(fmt);
3354         // First specify full texture.
3355         for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
3356             var levelSize = Math.max(1, this.m_size >> ndx);
3358             data.setSize(levelSize, levelSize);
3360             for (var f in tcuTexture.CubeFace) {
3361                 var face = tcuTexture.CubeFace[f];
3362                 var colorA = es3fTextureSpecificationTests.randomVector(
3363                     rnd, [0, 0, 0, 0], [1, 1, 1, 1], 4
3364                 );
3365                 var colorB = es3fTextureSpecificationTests.randomVector(
3366                     rnd, [0, 0, 0, 0], [1, 1, 1, 1], 4
3367                 );
3368                 var cellSize = rnd.getInt(2, 16);
3370                 tcuTextureUtil.fillWithGrid(
3371                     data.getAccess(), cellSize, colorA, colorB
3372                 );
3374                 this.m_context.texImage2D(
3375                     es3fTextureSpecificationTests.s_cubeMapFaces[face],
3376                     ndx, this.m_format, levelSize, levelSize, 0, this.m_format,
3377                     this.m_dataType, data.getAccess().getDataPtr()
3378                 );
3379             }
3380         }
3382         // Fill render target with gradient.
3383         shader.setGradient(
3384             this.m_context, shaderID, [0, 0, 0, 0], [1, 1, 1, 1]
3385         );
3386         rrUtil.drawQuad(
3387             this.m_context, shaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]
3388         );
3390         // Re-specify parts of each face and level.
3391         for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
3392             var levelSize = Math.max(1, this.m_size >> ndx);
3394             for (var f in es3fTextureSpecificationTests.s_cubeMapFaces) {
3395                 var w = rnd.getInt(1, levelSize);
3396                 var h = rnd.getInt(1, levelSize);
3397                 var xo = rnd.getInt(0, levelSize - w);
3398                 var yo = rnd.getInt(0, levelSize - h);
3400                 var x = rnd.getInt(0, this.m_size - w);
3401                 var y = rnd.getInt(0, this.m_size - h);
3403                 this.m_context.copyTexSubImage2D(
3404                     es3fTextureSpecificationTests.s_cubeMapFaces[f],
3405                     ndx, xo, yo, x, y, w, h
3406                 );
3407             }
3408         }
3409     };
3411     // Basic glTexStorage2D() with 2D texture usage
3412     /**
3413      * @constructor
3414      * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
3415      * @param {string} name
3416      * @param {string} desc
3417      * @param {number} internalFormat
3418      * @param {number} width
3419      * @param {number} height
3420      * @param {number} numLevels
3421      */
3422     es3fTextureSpecificationTests.BasicTexStorage2DCase = function(
3423         name, desc, internalFormat, width, height, numLevels
3424     ) {
3425         es3fTextureSpecificationTests.Texture2DSpecCase.call(
3426             this, name, desc, gluTextureUtil.mapGLInternalFormat(
3427                 internalFormat
3428             ), width, height, numLevels
3429         );
3431         this.m_internalFormat = internalFormat;
3432     };
3434     es3fTextureSpecificationTests.BasicTexStorage2DCase.prototype =
3435         Object.create(
3436             es3fTextureSpecificationTests.Texture2DSpecCase.prototype
3437         );
3439     es3fTextureSpecificationTests.BasicTexStorage2DCase.prototype.constructor =
3440         es3fTextureSpecificationTests.BasicTexStorage2DCase;
3442     /**
3443      * createTexture
3444      */
3445     es3fTextureSpecificationTests.
3446     BasicTexStorage2DCase.prototype.createTexture = function() {
3447         var fmt = gluTextureUtil.mapGLInternalFormat(this.m_internalFormat);
3448         var transferFmt = gluTextureUtil.getTransferFormat(fmt);
3449         var tex = null;
3450         var levelData = new tcuTexture.TextureLevel(
3451             fmt, this.m_width, this.m_height
3452         );
3453         var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
3455         tex = this.m_context.createTexture();
3456         this.m_context.bindTexture(gl.TEXTURE_2D, tex);
3457         this.m_context.texStorage2D(
3458             gl.TEXTURE_2D, this.m_numLevels, this.m_internalFormat,
3459             this.m_width, this.m_height
3460         );
3462         this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
3464         for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
3465             var levelW = Math.max(1, this.m_width >> ndx);
3466             var levelH = Math.max(1, this.m_height >> ndx);
3467             var gMin = es3fTextureSpecificationTests.randomVector(
3468                 rnd, this.m_texFormatInfo.valueMin,
3469                 this.m_texFormatInfo.valueMax, 4
3470             );
3471             var gMax = es3fTextureSpecificationTests.randomVector(
3472                 rnd, this.m_texFormatInfo.valueMin,
3473                 this.m_texFormatInfo.valueMax, 4
3474             );
3476             levelData.setSize(levelW, levelH);
3477             tcuTextureUtil.fillWithComponentGradients(
3478                 levelData.getAccess(), gMin, gMax
3479             );
3481             this.m_context.texSubImage2D(
3482                 gl.TEXTURE_2D, ndx, 0, 0, levelW, levelH,
3483                 transferFmt.format, transferFmt.dataType,
3484                 levelData.getAccess().getDataPtr()
3485             );
3486         }
3487     };
3489     // Basic glTexStorage2D() with cubemap usage
3490     /**
3491      * @constructor
3492      * @extends {es3fTextureSpecificationTests.TextureCubeSpecCase}
3493      * @param {string} name
3494      * @param {string} desc
3495      * @param {number} internalFormat
3496      * @param {number} size
3497      * @param {number} numLevels
3498      */
3499     es3fTextureSpecificationTests.BasicTexStorageCubeCase = function(
3500         name, desc, internalFormat, size, numLevels
3501     ) {
3502         es3fTextureSpecificationTests.TextureCubeSpecCase.call(
3503             this, name, desc, gluTextureUtil.mapGLInternalFormat(
3504                 internalFormat
3505             ), size, numLevels
3506         );
3508         this.m_internalFormat = internalFormat;
3509     };
3511     es3fTextureSpecificationTests.BasicTexStorageCubeCase.prototype =
3512         Object.create(
3513             es3fTextureSpecificationTests.TextureCubeSpecCase.prototype
3514         );
3516     es3fTextureSpecificationTests.BasicTexStorageCubeCase.prototype.constructor =
3517         es3fTextureSpecificationTests.BasicTexStorageCubeCase;
3519     /**
3520      * createTexture
3521      */
3522     es3fTextureSpecificationTests.BasicTexStorageCubeCase.prototype.createTexture = function() {
3523         var fmt = gluTextureUtil.mapGLInternalFormat(this.m_internalFormat);
3524         var transferFmt = gluTextureUtil.getTransferFormat(fmt);
3525         var tex = null;
3526         var levelData = new tcuTexture.TextureLevel(
3527             fmt, this.m_size, this.m_size
3528         );
3529         var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
3531         tex = this.m_context.createTexture();
3532         this.m_context.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
3533         this.m_context.texStorage2D(
3534             gl.TEXTURE_CUBE_MAP, this.m_numLevels, this.m_internalFormat,
3535             this.m_size, this.m_size
3536         );
3538         this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
3540         for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
3541             var levelSize = Math.max(1, this.m_size >> ndx);
3543             levelData.setSize(levelSize, levelSize);
3545             for (var f in tcuTexture.CubeFace) {
3546                 var face = tcuTexture.CubeFace[f];
3547                 var gMin = es3fTextureSpecificationTests.randomVector(
3548                     rnd, this.m_texFormatInfo.valueMin,
3549                     this.m_texFormatInfo.valueMax, 4
3550                 );
3551                 var gMax = es3fTextureSpecificationTests.randomVector(
3552                     rnd, this.m_texFormatInfo.valueMin,
3553                     this.m_texFormatInfo.valueMax, 4
3554                 );
3556                 tcuTextureUtil.fillWithComponentGradients(
3557                     levelData.getAccess(), gMin, gMax
3558                 );
3560                 this.m_context.texSubImage2D(
3561                     es3fTextureSpecificationTests.s_cubeMapFaces[face],
3562                     ndx, 0, 0, levelSize, levelSize,
3563                     transferFmt.format, transferFmt.dataType,
3564                     levelData.getAccess().getDataPtr()
3565                 );
3566             }
3567         }
3568     };
3570     // Basic glTexStorage3D() with 2D array texture usage
3571     /**
3572      * @constructor
3573      * @extends {es3fTextureSpecificationTests.Texture2DArraySpecCase}
3574      * @param {string} name
3575      * @param {string} desc
3576      * @param {number} internalFormat
3577      * @param {number} width
3578      * @param {number} height
3579      * @param {number} numLayers
3580      * @param {number} numLevels
3581      */
3582     es3fTextureSpecificationTests.BasicTexStorage2DArrayCase = function(
3583         name, desc, internalFormat, width, height, numLayers, numLevels
3584     ) {
3585         es3fTextureSpecificationTests.Texture2DArraySpecCase.call(
3586             this, name, desc, gluTextureUtil.mapGLInternalFormat(
3587                 internalFormat
3588             ), width, height, numLayers, numLevels
3589         );
3590         this.m_internalFormat = internalFormat;
3591     };
3593     es3fTextureSpecificationTests.BasicTexStorage2DArrayCase.prototype =
3594         Object.create(
3595             es3fTextureSpecificationTests.Texture2DArraySpecCase.prototype
3596         );
3598     es3fTextureSpecificationTests.
3599     BasicTexStorage2DArrayCase.prototype.constructor =
3600         es3fTextureSpecificationTests.BasicTexStorage2DArrayCase;
3602     /**
3603      * createTexture
3604      */
3605     es3fTextureSpecificationTests.BasicTexStorage2DArrayCase.prototype.createTexture = function() {
3606         var tex = null;
3607         var levelData = new tcuTexture.TextureLevel(
3608             this.m_texFormat, this.m_width, this.m_height
3609         );
3610         var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
3611         var transferFmt = gluTextureUtil.getTransferFormat(
3612             this.m_texFormat
3613         );
3615         tex = this.m_context.createTexture();
3616         this.m_context.bindTexture(gl.TEXTURE_2D_ARRAY, tex);
3617         this.m_context.texStorage3D(
3618             gl.TEXTURE_2D_ARRAY, this.m_numLevels, this.m_internalFormat,
3619             this.m_width, this.m_height, this.m_numLayers
3620         );
3622         this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
3624         for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
3625             var levelW = Math.max(1, this.m_width >> ndx);
3626             var levelH = Math.max(1, this.m_height >> ndx);
3627             var gMin = es3fTextureSpecificationTests.randomVector(
3628                 rnd, this.m_texFormatInfo.valueMin,
3629                 this.m_texFormatInfo.valueMax, 4
3630             );
3631             var gMax = es3fTextureSpecificationTests.randomVector(
3632                 rnd, this.m_texFormatInfo.valueMin,
3633                 this.m_texFormatInfo.valueMax, 4
3634             );
3636             levelData.setSize(levelW, levelH, this.m_numLayers);
3637             tcuTextureUtil.fillWithComponentGradients(
3638                 levelData.getAccess(), gMin, gMax
3639             );
3641             this.m_context.texSubImage3D(
3642                 gl.TEXTURE_2D_ARRAY, ndx, 0, 0, 0, levelW, levelH,
3643                 this.m_numLayers, transferFmt.format, transferFmt.dataType,
3644                 levelData.getAccess().getDataPtr()
3645             );
3646         }
3647     };
3649     // Basic TexStorage3D() with 3D texture usage
3650     /**
3651      * @constructor
3652      * @extends {es3fTextureSpecificationTests.Texture3DSpecCase}
3653      * @param {string} name
3654      * @param {string} desc
3655      * @param {number} internalFormat
3656      * @param {number} width
3657      * @param {number} height
3658      * @param {number} depth
3659      * @param {number} numLevels
3660      */
3661     es3fTextureSpecificationTests.BasicTexStorage3DCase = function(
3662         name, desc, internalFormat, width, height, depth, numLevels
3663     ) {
3664         es3fTextureSpecificationTests.Texture3DSpecCase.call(
3665             this, name, desc, gluTextureUtil.mapGLInternalFormat(
3666                 internalFormat
3667             ), width, height, depth, numLevels
3668         );
3670         this.m_internalFormat = internalFormat;
3671     };
3673     es3fTextureSpecificationTests.BasicTexStorage3DCase.prototype =
3674         Object.create(
3675             es3fTextureSpecificationTests.Texture3DSpecCase.prototype
3676         );
3678     es3fTextureSpecificationTests.
3679     BasicTexStorage3DCase.prototype.constructor =
3680         es3fTextureSpecificationTests.BasicTexStorage3DCase;
3682     /**
3683      * createTexture
3684      */
3685     es3fTextureSpecificationTests.
3686     BasicTexStorage3DCase.prototype.createTexture = function() {
3687         var tex = null;
3688         var levelData = new tcuTexture.TextureLevel(
3689             this.m_texFormat, this.m_width, this.m_height
3690         );
3691         var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
3692         var transferFmt = gluTextureUtil.getTransferFormat(
3693             this.m_texFormat
3694         );
3696         tex = this.m_context.createTexture();
3697         this.m_context.bindTexture(gl.TEXTURE_3D, tex);
3698         this.m_context.texStorage3D(
3699             gl.TEXTURE_3D, this.m_numLevels, this.m_internalFormat,
3700             this.m_width, this.m_height, this.m_depth
3701         );
3703         this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
3705         for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
3706             var levelW = Math.max(1, this.m_width >> ndx);
3707             var levelH = Math.max(1, this.m_height >> ndx);
3708             var levelD = Math.max(1, this.m_depth >> ndx);
3709             var gMin = es3fTextureSpecificationTests.randomVector(
3710                 rnd, this.m_texFormatInfo.valueMin,
3711                 this.m_texFormatInfo.valueMax, 4
3712             );
3713             var gMax = es3fTextureSpecificationTests.randomVector(
3714                 rnd, this.m_texFormatInfo.valueMin,
3715                 this.m_texFormatInfo.valueMax, 4
3716             );
3718             levelData.setSize(levelW, levelH, levelD);
3719             tcuTextureUtil.fillWithComponentGradients(
3720                 levelData.getAccess(), gMin, gMax
3721             );
3723             this.m_context.texSubImage3D(
3724                 gl.TEXTURE_3D, ndx, 0, 0, 0, levelW, levelH,
3725                 levelD, transferFmt.format, transferFmt.dataType,
3726                 levelData.getAccess().getDataPtr()
3727             );
3728         }
3729     };
3731     // Pixel buffer object cases.
3733     // TexImage2D() from pixel buffer object.
3734     /**
3735      * @constructor
3736      * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
3737      * @param {string} name
3738      * @param {string} desc
3739      * @param {number} internalFormat
3740      * @param {number} width
3741      * @param {number} height
3742      * @param {number} rowLength
3743      * @param {number} skipRows
3744      * @param {number} skipPixels
3745      * @param {number} alignment
3746      * @param {number} offset
3747      */
3748     es3fTextureSpecificationTests.TexImage2DBufferCase = function(
3749         name, desc, internalFormat, width, height, rowLength,
3750         skipRows, skipPixels, alignment, offset
3751     ) {
3752         es3fTextureSpecificationTests.Texture2DSpecCase.call(
3753             this, name, desc, gluTextureUtil.mapGLInternalFormat(
3754                 internalFormat
3755             ), width, height, 1
3756         );
3758         this.m_internalFormat = internalFormat;
3759         this.m_rowLength = rowLength;
3760         this.m_skipRows = skipRows;
3761         this.m_skipPixels = skipPixels;
3762         this.m_alignment = alignment;
3763         this.m_offset = offset;
3764     };
3766     es3fTextureSpecificationTests.TexImage2DBufferCase.prototype =
3767         Object.create(
3768             es3fTextureSpecificationTests.Texture2DSpecCase.prototype
3769         );
3771     es3fTextureSpecificationTests.
3772     TexImage2DBufferCase.prototype.constructor =
3773         es3fTextureSpecificationTests.TexImage2DBufferCase;
3775     /**
3776      * createTexture
3777      */
3778     es3fTextureSpecificationTests.TexImage2DBufferCase.prototype.createTexture =
3779     function() {
3780         var transferFmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
3781         var pixelSize = this.m_texFormat.getPixelSize();
3782         var rowLength = this.m_rowLength > 0 ?
3783             this.m_rowLength :
3784             this.m_width + this.m_skipPixels;
3785         var rowPitch = deMath.deAlign32(
3786             rowLength * pixelSize, this.m_alignment
3787         );
3788         var height = this.m_height + this.m_skipRows;
3789         var buf = null;
3790         var tex = null;
3791         var data = new ArrayBuffer(rowPitch * height + this.m_skipPixels * pixelSize + this.m_offset);
3793         assertMsgOptions(
3794             this.m_numLevels == 1, 'Number of levels different than 1',
3795             false, true
3796         );
3798         // Fill data with grid.
3799         var cScale = deMath.subtract(this.m_texFormatInfo.valueMax, this.m_texFormatInfo.valueMin);
3800         var cBias = this.m_texFormatInfo.valueMin;
3801         var colorA = deMath.add(
3802             deMath.multiply([1.0, 0.0, 0.0, 1.0], cScale), cBias
3803         );
3804         var colorB = deMath.add(
3805             deMath.multiply([0.0, 1.0, 0.0, 1.0], cScale), cBias
3806         );
3808         var access = new tcuTexture.PixelBufferAccess({
3809                     format: this.m_texFormat,
3810                     width: this.m_width,
3811                     height: this.m_height,
3812                     rowPitch: rowPitch,
3813                     data: data,
3814                     offset: this.m_skipRows * rowPitch + this.m_skipPixels * pixelSize + this.m_offset
3815                     });
3816         tcuTextureUtil.fillWithGrid(access, 4, colorA, colorB);
3818         // Create buffer and upload.
3819         buf = this.m_context.createBuffer();
3820         this.m_context.bindBuffer(gl.PIXEL_UNPACK_BUFFER, buf);
3821         this.m_context.bufferData(gl.PIXEL_UNPACK_BUFFER, data, gl.STATIC_DRAW
3822         );
3824         this.m_context.pixelStorei(gl.UNPACK_ROW_LENGTH, this.m_rowLength);
3825         this.m_context.pixelStorei(gl.UNPACK_SKIP_ROWS, this.m_skipRows);
3826         this.m_context.pixelStorei(gl.UNPACK_SKIP_PIXELS, this.m_skipPixels);
3827         this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
3829         tex = this.m_context.createTexture();
3830         this.m_context.bindTexture(gl.TEXTURE_2D, tex);
3831         this.m_context.texImage2D(gl.TEXTURE_2D, 0, this.m_internalFormat,
3832             this.m_width, this.m_height, 0, transferFmt.format, transferFmt.dataType,
3833             this.m_offset
3834         );
3835     };
3837     // TexImage2D() cubemap from pixel buffer object case
3838     /**
3839      * @constructor
3840      * @extends {es3fTextureSpecificationTests.TextureCubeSpecCase}
3841      * @param {string} name
3842      * @param {string} desc
3843      * @param {number} internalFormat
3844      * @param {number} size
3845      * @param {number} rowLength
3846      * @param {number} skipRows
3847      * @param {number} skipPixels
3848      * @param {number} alignment
3849      * @param {number} offset
3850      */
3851     es3fTextureSpecificationTests.TexImageCubeBufferCase = function(
3852         name, desc, internalFormat, size, rowLength, skipRows, skipPixels,
3853         alignment, offset
3854     ) {
3855         es3fTextureSpecificationTests.TextureCubeSpecCase.call(
3856             this, name, desc, gluTextureUtil.mapGLInternalFormat(
3857                 internalFormat
3858             ), size, 1
3859         );
3861         this.m_internalFormat = internalFormat;
3862         this.m_rowLength = rowLength;
3863         this.m_skipRows = skipRows;
3864         this.m_skipPixels = skipPixels;
3865         this.m_alignment = alignment;
3866         this.m_offset = offset;
3867     };
3869     es3fTextureSpecificationTests.TexImageCubeBufferCase.prototype =
3870         Object.create(
3871             es3fTextureSpecificationTests.TextureCubeSpecCase.prototype
3872         );
3874     es3fTextureSpecificationTests.
3875     TexImageCubeBufferCase.prototype.constructor =
3876         es3fTextureSpecificationTests.TexImageCubeBufferCase;
3878     /**
3879      * createTexture
3880      */
3881     es3fTextureSpecificationTests.
3882     TexImageCubeBufferCase.prototype.createTexture = function() {
3883         var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
3884         var tex = null;
3885         var fmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
3886         var pixelSize = this.m_texFormat.getPixelSize();
3887         var rowLength = this.m_rowLength > 0 ?
3888             this.m_rowLength : this.m_size + this.m_skipPixels;
3889         var rowPitch = deMath.deAlign32(
3890             rowLength * pixelSize, this.m_alignment
3891         );
3892         var height = this.m_size + this.m_skipRows;
3894         var data = new ArrayBuffer(rowPitch * height + this.m_skipPixels * pixelSize + this.m_offset);
3895         var access = new tcuTexture.PixelBufferAccess({
3896                             format: this.m_texFormat,
3897                             width: this.m_size,
3898                             height: this.m_size,
3899                             rowPitch: rowPitch,
3900                             data: data,
3901                             offset: this.m_skipRows * rowPitch + this.m_skipPixels * pixelSize + this.m_offset
3902                         });
3904         assertMsgOptions(
3905             this.m_numLevels == 1, 'Number of levels is different than 1',
3906             false, true
3907         );
3909         tex = this.m_context.createTexture();
3910         this.m_context.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
3911         this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
3913         for (var f in tcuTexture.CubeFace) {
3914             var face = tcuTexture.CubeFace[f];
3915             var buf = null;
3917             var gMin = es3fTextureSpecificationTests.randomVector(
3918                 rnd, this.m_texFormatInfo.valueMin,
3919                 this.m_texFormatInfo.valueMax, 4
3920             );
3921             var gMax = es3fTextureSpecificationTests.randomVector(
3922                 rnd, this.m_texFormatInfo.valueMin,
3923                 this.m_texFormatInfo.valueMax, 4
3924             );
3926             tcuTextureUtil.fillWithComponentGradients(access, gMin, gMax);
3928             // Create buffer and upload.
3929             buf = this.m_context.createBuffer();
3930             this.m_context.bindBuffer(gl.PIXEL_UNPACK_BUFFER, buf);
3931             this.m_context.bufferData(gl.PIXEL_UNPACK_BUFFER, data, gl.STATIC_DRAW);
3933             this.m_context.pixelStorei(gl.UNPACK_ROW_LENGTH, this.m_rowLength);
3934             this.m_context.pixelStorei(gl.UNPACK_SKIP_ROWS, this.m_skipRows);
3935             this.m_context.pixelStorei(gl.UNPACK_SKIP_PIXELS, this.m_skipPixels);
3936             this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
3938             this.m_context.texImage2D(
3939                 es3fTextureSpecificationTests.s_cubeMapFaces[face], 0,
3940                 this.m_internalFormat, this.m_size, this.m_size, 0, fmt.format,
3941                 fmt.dataType, this.m_offset);
3942         }
3943     };
3945     // TexImage3D() 2D array from pixel buffer object.
3946     /**
3947      * @constructor
3948      * @extends {es3fTextureSpecificationTests.Texture2DArraySpecCase}
3949      * @param {string} name
3950      * @param {string} desc
3951      * @param {number} internalFormat
3952      * @param {number} width
3953      * @param {number} height
3954      * @param {number} depth
3955      * @param {number} imageHeight
3956      * @param {number} rowLength
3957      * @param {number} skipImages
3958      * @param {number} skipRows
3959      * @param {number} skipPixels
3960      * @param {number} alignment
3961      * @param {number} offset
3962      */
3963     es3fTextureSpecificationTests.TexImage2DArrayBufferCase = function(
3964         name, desc, internalFormat, width, height, depth, imageHeight,
3965         rowLength, skipImages, skipRows, skipPixels, alignment, offset
3966     ) {
3967         es3fTextureSpecificationTests.Texture2DArraySpecCase.call(
3968             this, name, desc, gluTextureUtil.mapGLInternalFormat(
3969                 internalFormat
3970             ), width, height, depth, 1
3971         );
3973         this.m_internalFormat = internalFormat;
3974         this.m_imageHeight = imageHeight;
3975         this.m_rowLength = rowLength;
3976         this.m_skipImages = skipImages;
3977         this.m_skipRows = skipRows;
3978         this.m_skipPixels = skipPixels;
3979         this.m_alignment = alignment;
3980         this.m_offset = offset;
3981     };
3983     es3fTextureSpecificationTests.TexImage2DArrayBufferCase.prototype =
3984         Object.create(
3985             es3fTextureSpecificationTests.Texture2DArraySpecCase.prototype
3986         );
3988     es3fTextureSpecificationTests.
3989     TexImage2DArrayBufferCase.prototype.constructor =
3990         es3fTextureSpecificationTests.TexImage2DArrayBufferCase;
3992     /**
3993      * createTexture
3994      */
3995     es3fTextureSpecificationTests.
3996     TexImage2DArrayBufferCase.prototype.createTexture = function() {
3997         var transferFmt = gluTextureUtil.getTransferFormat(
3998             this.m_texFormat
3999         );
4000         var pixelSize = this.m_texFormat.getPixelSize();
4001         var rowLength = this.m_rowLength > 0 ? this.m_rowLength : this.m_width;
4002         var rowPitch = deMath.deAlign32(
4003             rowLength * pixelSize, this.m_alignment
4004         );
4005         var imageHeight = this.m_imageHeight > 0 ?
4006             this.m_imageHeight : this.m_height;
4007         var slicePitch = imageHeight * rowPitch;
4008         var tex = null;
4009         var buf = null;
4010         var data = new ArrayBuffer(
4011             slicePitch * (this.m_numLayers + this.m_skipImages) +
4012             this.m_skipRows * rowPitch + this.m_skipPixels * pixelSize + this.m_offset
4013         );
4015         assertMsgOptions(
4016             this.m_numLevels == 1, 'Number of levels is different than 1',
4017             false, true
4018         );
4020         // Fill data with grid.
4021         var cScale = deMath.subtract(this.m_texFormatInfo.valueMax, this.m_texFormatInfo.valueMin);
4022         var cBias = this.m_texFormatInfo.valueMin;
4023         var colorA = deMath.add(
4024             deMath.multiply([1.0, 0.0, 0.0, 1.0], cScale), cBias
4025         );
4026         var colorB = deMath.add(
4027             deMath.multiply([0.0, 1.0, 0.0, 1.0], cScale), cBias
4028         );
4030         var access = new tcuTexture.PixelBufferAccess({
4031                         format: this.m_texFormat,
4032                         width: this.m_width,
4033                         height: this.m_height,
4034                         depth: this.m_numLayers,
4035                         rowPitch: rowPitch,
4036                         slicePitch: slicePitch,
4037                         data: data,
4038                         offset: this.m_skipImages * slicePitch +
4039                             this.m_skipRows * rowPitch +
4040                             this.m_skipPixels * pixelSize +
4041                             this.m_offset
4042                         });
4043         tcuTextureUtil.fillWithGrid(access, 4, colorA, colorB);
4045         // Create buffer and upload.
4046         buf = this.m_context.createBuffer();
4047         this.m_context.bindBuffer(gl.PIXEL_UNPACK_BUFFER, buf);
4048         this.m_context.bufferData(gl.PIXEL_UNPACK_BUFFER, data, gl.STATIC_DRAW);
4050         this.m_context.pixelStorei(gl.UNPACK_IMAGE_HEIGHT, this.m_imageHeight);
4051         this.m_context.pixelStorei(gl.UNPACK_ROW_LENGTH, this.m_rowLength);
4052         this.m_context.pixelStorei(gl.UNPACK_SKIP_IMAGES, this.m_skipImages);
4053         this.m_context.pixelStorei(gl.UNPACK_SKIP_ROWS, this.m_skipRows);
4054         this.m_context.pixelStorei(gl.UNPACK_SKIP_PIXELS, this.m_skipPixels);
4055         this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
4057         tex = this.m_context.createTexture();
4058         this.m_context.bindTexture(gl.TEXTURE_2D_ARRAY, tex);
4059         this.m_context.texImage3D(
4060             gl.TEXTURE_2D_ARRAY, 0, this.m_internalFormat, this.m_width,
4061             this.m_height, this.m_numLayers, 0, transferFmt.format,
4062             transferFmt.dataType, this.m_offset
4063         );
4064     };
4066     // TexImage3D() from pixel buffer object.
4067     /**
4068      * @constructor
4069      * @extends {es3fTextureSpecificationTests.Texture3DSpecCase}
4070      * @param {string} name
4071      * @param {string} desc
4072      * @param {number} internalFormat
4073      * @param {number} width
4074      * @param {number} height
4075      * @param {number} depth
4076      * @param {number} imageHeight
4077      * @param {number} rowLength
4078      * @param {number} skipImages
4079      * @param {number} skipRows
4080      * @param {number} skipPixels
4081      * @param {number} alignment
4082      * @param {number} offset
4083      */
4084     es3fTextureSpecificationTests.TexImage3DBufferCase = function(
4085         name, desc, internalFormat, width, height, depth, imageHeight,
4086         rowLength, skipImages, skipRows, skipPixels, alignment, offset
4087     ) {
4088         es3fTextureSpecificationTests.Texture3DSpecCase.call(
4089             this, name, desc, gluTextureUtil.mapGLInternalFormat(
4090                 internalFormat
4091             ), width, height, depth, 1
4092         );
4094         this.m_internalFormat = internalFormat;
4095         this.m_imageHeight = imageHeight;
4096         this.m_rowLength = rowLength;
4097         this.m_skipImages = skipImages;
4098         this.m_skipRows = skipRows;
4099         this.m_skipPixels = skipPixels;
4100         this.m_alignment = alignment;
4101         this.m_offset = offset;
4102     };
4104     es3fTextureSpecificationTests.TexImage3DBufferCase.prototype =
4105         Object.create(
4106             es3fTextureSpecificationTests.Texture3DSpecCase.prototype
4107         );
4109     es3fTextureSpecificationTests.
4110     TexImage3DBufferCase.prototype.constructor =
4111         es3fTextureSpecificationTests.TexImage3DBufferCase;
4113     /**
4114      * createTexture
4115      */
4116     es3fTextureSpecificationTests.
4117     TexImage3DBufferCase.prototype.createTexture = function() {
4118         var transferFmt = gluTextureUtil.getTransferFormat(
4119             this.m_texFormat
4120         );
4121         var pixelSize = this.m_texFormat.getPixelSize();
4122         var rowLength = this.m_rowLength > 0 ? this.m_rowLength : this.m_width;
4123         var rowPitch = deMath.deAlign32(
4124             rowLength * pixelSize, this.m_alignment
4125         );
4126         var imageHeight = this.m_imageHeight > 0 ?
4127             this.m_imageHeight : this.m_height;
4128         var slicePitch = imageHeight * rowPitch;
4129         var tex = null;
4130         var buf = null;
4131         var data = new ArrayBuffer(
4132             slicePitch * (this.m_depth + this.m_skipImages) +
4133             rowPitch * this.m_skipRows + pixelSize * this.m_skipPixels + this.m_offset
4134         );
4136         assertMsgOptions(
4137             this.m_numLevels == 1, 'Number of levels is different than 1',
4138             false, true
4139         );
4141         // Fill data with grid.
4142         var cScale = deMath.subtract(this.m_texFormatInfo.valueMax, this.m_texFormatInfo.valueMin);
4143         var cBias = this.m_texFormatInfo.valueMin;
4144         var colorA = deMath.add(
4145             deMath.multiply([1.0, 0.0, 0.0, 1.0], cScale), cBias
4146         );
4147         var colorB = deMath.add(
4148             deMath.multiply([0.0, 1.0, 0.0, 1.0], cScale), cBias
4149         );
4151         var access = new tcuTexture.PixelBufferAccess({
4152                         format: this.m_texFormat,
4153                         width: this.m_width,
4154                         height: this.m_height,
4155                         depth: this.m_depth,
4156                         rowPitch: rowPitch,
4157                         slicePitch: slicePitch,
4158                         data: data,
4159                         offset: this.m_skipImages * slicePitch +
4160                             this.m_skipRows * rowPitch +
4161                             this.m_skipPixels * pixelSize +
4162                             this.m_offset
4163                         });
4164         tcuTextureUtil.fillWithGrid(access, 4, colorA, colorB);
4166         // Create buffer and upload.
4167         buf = this.m_context.createBuffer();
4168         this.m_context.bindBuffer(gl.PIXEL_UNPACK_BUFFER, buf);
4169         this.m_context.bufferData(gl.PIXEL_UNPACK_BUFFER, data, gl.STATIC_DRAW);
4171         this.m_context.pixelStorei(gl.UNPACK_IMAGE_HEIGHT, this.m_imageHeight);
4172         this.m_context.pixelStorei(gl.UNPACK_ROW_LENGTH, this.m_rowLength);
4173         this.m_context.pixelStorei(gl.UNPACK_SKIP_IMAGES, this.m_skipImages);
4174         this.m_context.pixelStorei(gl.UNPACK_SKIP_ROWS, this.m_skipRows);
4175         this.m_context.pixelStorei(gl.UNPACK_SKIP_PIXELS, this.m_skipPixels);
4176         this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
4178         tex = this.m_context.createTexture();
4179         this.m_context.bindTexture(gl.TEXTURE_3D, tex);
4180         this.m_context.texImage3D(
4181             gl.TEXTURE_3D, 0, this.m_internalFormat, this.m_width,
4182             this.m_height, this.m_depth, 0, transferFmt.format,
4183             transferFmt.dataType, this.m_offset
4184         );
4185     };
4187     // TexSubImage2D() PBO case.
4188     /**
4189      * @constructor
4190      * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
4191      * @param {string} name
4192      * @param {string} desc
4193      * @param {number} internalFormat
4194      * @param {number} width
4195      * @param {number} height
4196      * @param {number} subX
4197      * @param {number} subY
4198      * @param {number} subW
4199      * @param {number} subH
4200      * @param {number} rowLength
4201      * @param {number} skipRows
4202      * @param {number} skipPixels
4203      * @param {number} alignment
4204      * @param {number} offset
4205      */
4206     es3fTextureSpecificationTests.TexSubImage2DBufferCase = function(
4207         name, desc, internalFormat, width, height, subX, subY, subW, subH,
4208         rowLength, skipRows, skipPixels, alignment, offset
4209     ) {
4210         es3fTextureSpecificationTests.Texture2DSpecCase.call(
4211             this, name, desc, gluTextureUtil.mapGLInternalFormat(
4212                 internalFormat
4213             ), width, height, 1
4214         );
4215         this.m_internalFormat = internalFormat;
4216         this.m_subX = subX;
4217         this.m_subY = subY;
4218         this.m_subW = subW;
4219         this.m_subH = subH;
4220         this.m_rowLength = rowLength;
4221         this.m_skipRows = skipRows;
4222         this.m_skipPixels = skipPixels;
4223         this.m_alignment = alignment;
4224         this.m_offset = offset;
4225     };
4227     es3fTextureSpecificationTests.TexSubImage2DBufferCase.prototype =
4228         Object.create(
4229             es3fTextureSpecificationTests.Texture2DSpecCase.prototype
4230         );
4232     es3fTextureSpecificationTests.
4233     TexSubImage2DBufferCase.prototype.constructor =
4234         es3fTextureSpecificationTests.TexSubImage2DBufferCase;
4236     /**
4237      * createTexture
4238      */
4239     es3fTextureSpecificationTests.
4240     TexSubImage2DBufferCase.prototype.createTexture = function() {
4241         var transferFmt = gluTextureUtil.getTransferFormat(
4242             this.m_texFormat
4243         );
4244         var pixelSize = this.m_texFormat.getPixelSize();
4245         var tex = null;
4246         var buf = null;
4247         var data = new ArrayBuffer(
4248             deMath.deAlign32(this.m_width * pixelSize, 4) * this.m_height
4249         );
4251         assertMsgOptions(
4252             this.m_numLevels == 1, 'Number of levels is different than 1',
4253             false, true
4254         );
4256         tex = this.m_context.createTexture();
4257         this.m_context.bindTexture(gl.TEXTURE_2D, tex);
4259         var access = new tcuTexture.PixelBufferAccess({
4260                         format: this.m_texFormat,
4261                         width: this.m_width,
4262                         height: this.m_height,
4263                         rowPitch: deMath.deAlign32(this.m_width * pixelSize, 4),
4264                         data: data
4265                         });
4266         // First fill texture with gradient.
4267         tcuTextureUtil.fillWithComponentGradients(access, this.m_texFormatInfo.valueMin, this.m_texFormatInfo.valueMax);
4268         this.m_context.texImage2D(
4269             gl.TEXTURE_2D, 0, this.m_internalFormat,
4270             this.m_width, this.m_height, 0, transferFmt.format,
4271             transferFmt.dataType, access.getDataPtr()
4272         );
4274         // Fill data with grid.
4275         var rowLength = this.m_rowLength > 0 ? this.m_rowLength : this.m_subW;
4276         var rowPitch = deMath.deAlign32(
4277             rowLength * pixelSize, this.m_alignment
4278         );
4279         var height = this.m_subH + this.m_skipRows;
4280         var cScale = deMath.subtract(this.m_texFormatInfo.valueMax, this.m_texFormatInfo.valueMin);
4281         var cBias = this.m_texFormatInfo.valueMin;
4282         var colorA = deMath.add(
4283             deMath.multiply([1.0, 0.0, 0.0, 1.0], cScale), cBias
4284         );
4285         var colorB = deMath.add(
4286             deMath.multiply([0.0, 1.0, 0.0, 1.0], cScale), cBias
4287         );
4289         access = new tcuTexture.PixelBufferAccess({
4290                         format: this.m_texFormat,
4291                         width: this.m_subW,
4292                         height: this.m_subH,
4293                         rowPitch: rowPitch,
4294                         data: new ArrayBuffer(rowPitch * height + this.m_offset),
4295                         offset: this.m_skipRows * rowPitch +
4296                                 this.m_skipPixels * pixelSize +
4297                                 this.m_offset
4298                         });
4299         tcuTextureUtil.fillWithGrid(access, 4, colorA, colorB);
4301         buf = this.m_context.createBuffer();
4302         this.m_context.bindBuffer(gl.PIXEL_UNPACK_BUFFER, buf);
4303         this.m_context.bufferData(gl.PIXEL_UNPACK_BUFFER, access.getBuffer(), gl.STATIC_DRAW);
4305         this.m_context.pixelStorei(gl.UNPACK_ROW_LENGTH, this.m_rowLength);
4306         this.m_context.pixelStorei(gl.UNPACK_SKIP_ROWS, this.m_skipRows);
4307         this.m_context.pixelStorei(gl.UNPACK_SKIP_PIXELS, this.m_skipPixels);
4308         this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
4310         this.m_context.texSubImage2D(
4311             gl.TEXTURE_2D, 0, this.m_subX, this.m_subY,
4312             this.m_subW, this.m_subH, transferFmt.format,
4313             transferFmt.dataType, this.m_offset
4314         );
4315     };
4317     // TexSubImage2D() cubemap PBO case.
4318     /**
4319      * @constructor
4320      * @extends {es3fTextureSpecificationTests.TextureCubeSpecCase}
4321      * @param {string} name
4322      * @param {string} desc
4323      * @param {number} internalFormat
4324      * @param {number} size
4325      * @param {number} subX
4326      * @param {number} subY
4327      * @param {number} subW
4328      * @param {number} subH
4329      * @param {number} rowLength
4330      * @param {number} skipRows
4331      * @param {number} skipPixels
4332      * @param {number} alignment
4333      * @param {number} offset
4334      */
4335     es3fTextureSpecificationTests.TexSubImageCubeBufferCase = function(
4336         name, desc, internalFormat, size, subX, subY, subW, subH, rowLength,
4337         skipRows, skipPixels, alignment, offset
4338     ) {
4339         es3fTextureSpecificationTests.TextureCubeSpecCase.call(
4340             this, name, desc, gluTextureUtil.mapGLInternalFormat(
4341                 internalFormat
4342             ), size, 1
4343         );
4345         this.m_internalFormat = internalFormat;
4346         this.m_subX = subX;
4347         this.m_subY = subY;
4348         this.m_subW = subW;
4349         this.m_subH = subH;
4350         this.m_rowLength = rowLength;
4351         this.m_skipRows = skipRows;
4352         this.m_skipPixels = skipPixels;
4353         this.m_alignment = alignment;
4354         this.m_offset = offset;
4355     };
4357     es3fTextureSpecificationTests.TexSubImageCubeBufferCase.prototype =
4358         Object.create(
4359             es3fTextureSpecificationTests.TextureCubeSpecCase.prototype
4360         );
4362     es3fTextureSpecificationTests.
4363     TexSubImageCubeBufferCase.prototype.constructor =
4364         es3fTextureSpecificationTests.TexSubImageCubeBufferCase;
4366     /**
4367      * createTexture
4368      */
4369     es3fTextureSpecificationTests.
4370     TexSubImageCubeBufferCase.prototype.createTexture = function() {
4371         var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
4372         var transferFmt = gluTextureUtil.getTransferFormat(
4373             this.m_texFormat
4374         );
4375         var pixelSize = this.m_texFormat.getPixelSize();
4376         var tex = null;
4377         var buf = null;
4378         var data = new ArrayBuffer(
4379             deMath.deAlign32(this.m_size * pixelSize, 4) * this.m_size
4380         );
4381         var access = new tcuTexture.PixelBufferAccess({
4382                             format: this.m_texFormat,
4383                             width: this.m_size,
4384                             height: this.m_size,
4385                             rowPitch: deMath.deAlign32(this.m_size * pixelSize, 4),
4386                             data: data
4387                         });
4388         assertMsgOptions(
4389             this.m_numLevels == 1, 'Number of levels is different than 1',
4390             false, true
4391         );
4393         tex = this.m_context.createTexture();
4394         this.m_context.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
4396         // Fill faces with different gradients.
4398         this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
4400         for (var f in tcuTexture.CubeFace) {
4401             var face = tcuTexture.CubeFace[f];
4402             var gMin = es3fTextureSpecificationTests.randomVector(
4403                 rnd, this.m_texFormatInfo.valueMin,
4404                 this.m_texFormatInfo.valueMax, 4
4405             );
4406             var gMax = es3fTextureSpecificationTests.randomVector(
4407                 rnd, this.m_texFormatInfo.valueMin,
4408                 this.m_texFormatInfo.valueMax, 4
4409             );
4411             tcuTextureUtil.fillWithComponentGradients(access, gMin, gMax);
4413             this.m_context.texImage2D(
4414                 es3fTextureSpecificationTests.s_cubeMapFaces[face], 0,
4415                 this.m_internalFormat, this.m_size, this.m_size, 0,
4416                 transferFmt.format, transferFmt.dataType,
4417                 access.getDataPtr()
4418             );
4419         }
4421         // Fill data with grid.
4422         var rowLength = this.m_rowLength > 0 ? this.m_rowLength : this.m_subW;
4423         var rowPitch = deMath.deAlign32(
4424             rowLength * pixelSize, this.m_alignment
4425         );
4426         var height = this.m_subH + this.m_skipRows;
4427         var cScale = deMath.subtract(this.m_texFormatInfo.valueMax, this.m_texFormatInfo.valueMin);
4428         var cBias = this.m_texFormatInfo.valueMin;
4429         var colorA = deMath.add(
4430             deMath.multiply([1.0, 0.0, 0.0, 1.0], cScale), cBias
4431         );
4432         var colorB = deMath.add(
4433             deMath.multiply([0.0, 1.0, 0.0, 1.0], cScale), cBias
4434         );
4436         data = new ArrayBuffer(rowPitch * height + this.m_skipPixels * pixelSize + this.m_offset);
4437         var accessSub = new tcuTexture.PixelBufferAccess({
4438                         format: this.m_texFormat,
4439                         width: this.m_subW,
4440                         height: this.m_subH,
4441                         rowPitch: rowPitch,
4442                         data: data,
4443                         offset: this.m_skipRows * rowPitch +
4444                             this.m_skipPixels * pixelSize +
4445                             this.m_offset
4446                         });
4447         tcuTextureUtil.fillWithGrid(accessSub, 4, colorA, colorB);
4449         buf = this.m_context.createBuffer();
4450         this.m_context.bindBuffer(gl.PIXEL_UNPACK_BUFFER, buf);
4451         this.m_context.bufferData(
4452             gl.PIXEL_UNPACK_BUFFER, data, gl.STATIC_DRAW
4453         );
4455         this.m_context.pixelStorei(gl.UNPACK_ROW_LENGTH, this.m_rowLength);
4456         this.m_context.pixelStorei(gl.UNPACK_SKIP_ROWS, this.m_skipRows);
4457         this.m_context.pixelStorei(gl.UNPACK_SKIP_PIXELS, this.m_skipPixels);
4458         this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
4460         for (var f in tcuTexture.CubeFace) {
4461             var face = tcuTexture.CubeFace[f];
4462             this.m_context.texSubImage2D(
4463                 es3fTextureSpecificationTests.s_cubeMapFaces[face], 0,
4464                 this.m_subX, this.m_subY, this.m_subW, this.m_subH,
4465                 transferFmt.format, transferFmt.dataType, this.m_offset
4466             );
4467         }
4468     };
4470     // TexSubImage3D() 2D array PBO case.
4471     /**
4472      * @constructor
4473      * @extends {es3fTextureSpecificationTests.Texture2DArraySpecCase}
4474      * @param {string} name
4475      * @param {string} desc
4476      * @param {number} internalFormat
4477      * @param {number} width
4478      * @param {number} height
4479      * @param {number} depth
4480      * @param {number} subX
4481      * @param {number} subY
4482      * @param {number} subZ
4483      * @param {number} subW
4484      * @param {number} subH
4485      * @param {number} subD
4486      * @param {number} imageHeight
4487      * @param {number} rowLength
4488      * @param {number} skipImages
4489      * @param {number} skipRows
4490      * @param {number} skipPixels
4491      * @param {number} alignment
4492      * @param {number} offset
4493      */
4494     es3fTextureSpecificationTests.TexSubImage2DArrayBufferCase = function(
4495         name, desc, internalFormat, width, height, depth, subX, subY, subZ,
4496         subW, subH, subD, imageHeight, rowLength, skipImages, skipRows,
4497         skipPixels, alignment, offset
4498     ) {
4499         es3fTextureSpecificationTests.Texture2DArraySpecCase.call(
4500             this, name, desc, gluTextureUtil.mapGLInternalFormat(
4501                 internalFormat
4502             ), width, height, depth, 1
4503         );
4504         this.m_internalFormat = internalFormat;
4505         this.m_subX = subX;
4506         this.m_subY = subY;
4507         this.m_subZ = subZ;
4508         this.m_subW = subW;
4509         this.m_subH = subH;
4510         this.m_subD = subD;
4511         this.m_imageHeight = imageHeight;
4512         this.m_rowLength = rowLength;
4513         this.m_skipImages = skipImages;
4514         this.m_skipRows = skipRows;
4515         this.m_skipPixels = skipPixels;
4516         this.m_alignment = alignment;
4517         this.m_offset = offset;
4518     };
4520     es3fTextureSpecificationTests.TexSubImage2DArrayBufferCase.prototype =
4521         Object.create(
4522             es3fTextureSpecificationTests.Texture2DArraySpecCase.prototype
4523         );
4525     es3fTextureSpecificationTests.
4526     TexSubImage2DArrayBufferCase.prototype.constructor =
4527         es3fTextureSpecificationTests.TexSubImage2DArrayBufferCase;
4529     /**
4530      * createTexture
4531      */
4532     es3fTextureSpecificationTests.
4533     TexSubImage2DArrayBufferCase.prototype.createTexture = function() {
4534         var transferFmt = gluTextureUtil.getTransferFormat(
4535             this.m_texFormat
4536         );
4537         var pixelSize = this.m_texFormat.getPixelSize();
4538         var tex = null;
4539         var buf = null;
4540         /** @type {ArrayBuffer} */ var data;
4542         assertMsgOptions(
4543             this.m_numLevels == 1, 'Number of levels is different than 1',
4544             false, true
4545         );
4547         tex = this.m_context.createTexture();
4548         this.m_context.bindTexture(gl.TEXTURE_2D_ARRAY, tex);
4550         // Fill with gradient.
4551         var rowPitch = deMath.deAlign32(pixelSize * this.m_width, 4);
4552         var slicePitch = rowPitch * this.m_height;
4554         data = new ArrayBuffer(slicePitch * this.m_numLayers);
4555         var access = new tcuTexture.PixelBufferAccess({
4556                         format: this.m_texFormat,
4557                         width: this.m_width,
4558                         height: this.m_height,
4559                         depth: this.m_numLayers,
4560                         rowPitch: rowPitch,
4561                         slicePitch: slicePitch,
4562                         data: data
4563                     });
4564         tcuTextureUtil.fillWithComponentGradients(access, this.m_texFormatInfo.valueMin, this.m_texFormatInfo.valueMax
4565         );
4567         this.m_context.texImage3D(gl.TEXTURE_2D_ARRAY, 0, this.m_internalFormat, this.m_width, this.m_height,
4568             this.m_numLayers, 0, transferFmt.format, transferFmt.dataType, access.getDataPtr());
4570         // Fill data with grid.
4571         var rowLength = this.m_rowLength > 0 ? this.m_rowLength : this.m_subW;
4572         rowPitch = deMath.deAlign32(
4573             rowLength * pixelSize, this.m_alignment
4574         );
4575         var height = this.m_subH + this.m_skipRows;
4576         var cScale = deMath.subtract(this.m_texFormatInfo.valueMax, this.m_texFormatInfo.valueMin);
4578         var cBias = this.m_texFormatInfo.valueMin;
4579         var colorA = deMath.add(
4580             deMath.multiply([1.0, 0.0, 0.0, 1.0], cScale), cBias
4581         );
4582         var colorB = deMath.add(
4583             deMath.multiply([0.0, 1.0, 0.0, 1.0], cScale), cBias
4584         );
4586         var accessSub = new tcuTexture.PixelBufferAccess({
4587                         format: this.m_texFormat,
4588                         width: this.m_subW,
4589                         height: this.m_subH,
4590                         rowPitch: rowPitch,
4591                         data: new ArrayBuffer(rowPitch * height + this.m_offset),
4592                         offset: this.m_skipRows * rowPitch +
4593                                 this.m_skipPixels * pixelSize +
4594                                 this.m_offset
4595                     });
4596         tcuTextureUtil.fillWithGrid(accessSub, 4, colorA, colorB);
4598         buf = this.m_context.createBuffer();
4599         this.m_context.bindBuffer(gl.PIXEL_UNPACK_BUFFER, buf);
4600         this.m_context.bufferData(
4601             gl.PIXEL_UNPACK_BUFFER, accessSub.getBuffer(), gl.STATIC_DRAW
4602         );
4604         this.m_context.pixelStorei(gl.UNPACK_ROW_LENGTH, this.m_rowLength);
4605         this.m_context.pixelStorei(gl.UNPACK_SKIP_ROWS, this.m_skipRows);
4606         this.m_context.pixelStorei(gl.UNPACK_SKIP_PIXELS, this.m_skipPixels);
4607         this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
4608     };
4610     // TexSubImage3D() PBO case.
4611     /**
4612      * @constructor
4613      * @extends {es3fTextureSpecificationTests.Texture3DSpecCase}
4614      * @param {string} name
4615      * @param {string} desc
4616      * @param {number} internalFormat
4617      * @param {number} width
4618      * @param {number} height
4619      * @param {number} depth
4620      * @param {number} subX
4621      * @param {number} subY
4622      * @param {number} subZ
4623      * @param {number} subW
4624      * @param {number} subH
4625      * @param {number} subD
4626      * @param {number} imageHeight
4627      * @param {number} rowLength
4628      * @param {number} skipImages
4629      * @param {number} skipRows
4630      * @param {number} skipPixels
4631      * @param {number} alignment
4632      * @param {number} offset
4633      */
4634     es3fTextureSpecificationTests.TexSubImage3DBufferCase = function(
4635         name, desc, internalFormat, width, height, depth, subX, subY, subZ,
4636         subW, subH, subD, imageHeight, rowLength, skipImages, skipRows,
4637         skipPixels, alignment, offset
4638     ) {
4639         es3fTextureSpecificationTests.Texture3DSpecCase.call(
4640             this, name, desc, gluTextureUtil.mapGLInternalFormat(
4641                 internalFormat
4642             ), width, height, depth, 1
4643         );
4645         this.m_internalFormat = internalFormat;
4646         this.m_subX = subX;
4647         this.m_subY = subY;
4648         this.m_subZ = subZ;
4649         this.m_subW = subW;
4650         this.m_subH = subH;
4651         this.m_subD = subD;
4652         this.m_imageHeight = imageHeight;
4653         this.m_rowLength = rowLength;
4654         this.m_skipImages = skipImages;
4655         this.m_skipRows = skipRows;
4656         this.m_skipPixels = skipPixels;
4657         this.m_alignment = alignment;
4658         this.m_offset = offset;
4659     };
4661     es3fTextureSpecificationTests.TexSubImage3DBufferCase.prototype =
4662         Object.create(
4663             es3fTextureSpecificationTests.Texture3DSpecCase.prototype
4664         );
4666     es3fTextureSpecificationTests.
4667     TexSubImage3DBufferCase.prototype.constructor =
4668         es3fTextureSpecificationTests.TexSubImage3DBufferCase;
4670     /**
4671      * createTexture
4672      */
4673     es3fTextureSpecificationTests.
4674     TexSubImage3DBufferCase.prototype.createTexture = function() {
4675         var transferFmt = gluTextureUtil.getTransferFormat(
4676             this.m_texFormat
4677         );
4678         var pixelSize = this.m_texFormat.getPixelSize();
4679         var tex = null;
4680         var buf = null;
4681         /** @type {ArrayBuffer} */ var data;
4683         assertMsgOptions(
4684             this.m_numLevels == 1, 'Number of levels is different than 1',
4685             false, true
4686         );
4688         tex = this.m_context.createTexture();
4689         this.m_context.bindTexture(gl.TEXTURE_3D, tex);
4691         // Fill with gradient.
4692         var rowPitch = deMath.deAlign32(pixelSize * this.m_width, 4);
4693         var slicePitch = rowPitch * this.m_height;
4695         data = new ArrayBuffer(slicePitch * this.m_depth);
4696         var access = new tcuTexture.PixelBufferAccess({
4697                         format: this.m_texFormat,
4698                         width: this.m_width,
4699                         height: this.m_height,
4700                         depth: this.m_depth,
4701                         rowPitch: rowPitch,
4702                         slicePitch: slicePitch,
4703                         data: data});
4704         tcuTextureUtil.fillWithComponentGradients(access, this.m_texFormatInfo.valueMin, this.m_texFormatInfo.valueMax
4705         );
4707         this.m_context.texImage3D(
4708             gl.TEXTURE_3D, 0, this.m_internalFormat, this.m_width,
4709             this.m_height, this.m_depth, 0, transferFmt.format,
4710             transferFmt.dataType, access.getDataPtr()
4711         );
4713         // Fill data with grid.
4714         var rowLength = this.m_rowLength > 0 ? this.m_rowLength : this.m_subW;
4715         rowPitch = deMath.deAlign32(
4716             rowLength * pixelSize, this.m_alignment
4717         );
4718         var imageHeight = this.m_imageHeight > 0 ?
4719             this.m_imageHeight : this.m_subH;
4720         slicePitch = imageHeight * rowPitch;
4721         var cScale = deMath.subtract(this.m_texFormatInfo.valueMax, this.m_texFormatInfo.valueMin);
4722         var cBias = this.m_texFormatInfo.valueMin;
4723         var colorA = deMath.add(
4724             deMath.multiply([1.0, 0.0, 0.0, 1.0], cScale), cBias
4725         );
4726         var colorB = deMath.add(
4727             deMath.multiply([0.0, 1.0, 0.0, 1.0], cScale), cBias
4728         );
4730         data = new ArrayBuffer(slicePitch * (this.m_subD + this.m_skipImages) +
4731                                rowPitch * this.m_skipRows + pixelSize * this.m_skipPixels + this.m_offset);
4732         var accessSub = new tcuTexture.PixelBufferAccess({
4733                         format: this.m_texFormat,
4734                         width: this.m_subW,
4735                         height: this.m_subH,
4736                         depth: this.m_subD,
4737                         rowPitch: rowPitch,
4738                         slicePitch: slicePitch,
4739                         data: data,
4740                         offset: this.m_skipImages * slicePitch +
4741                                 this.m_skipRows * rowPitch +
4742                                 this.m_skipPixels * pixelSize +
4743                                 this.m_offset
4744                     });
4745         tcuTextureUtil.fillWithGrid(accessSub, 4, colorA, colorB
4746         );
4748         buf = this.m_context.createBuffer();
4749         this.m_context.bindBuffer(gl.PIXEL_UNPACK_BUFFER, buf);
4750         this.m_context.bufferData(
4751             gl.PIXEL_UNPACK_BUFFER, data, gl.STATIC_DRAW
4752         );
4754         this.m_context.pixelStorei(gl.UNPACK_IMAGE_HEIGHT, this.m_imageHeight);
4755         this.m_context.pixelStorei(gl.UNPACK_ROW_LENGTH, this.m_rowLength);
4756         this.m_context.pixelStorei(gl.UNPACK_SKIP_IMAGES, this.m_skipImages);
4757         this.m_context.pixelStorei(gl.UNPACK_SKIP_ROWS, this.m_skipRows);
4758         this.m_context.pixelStorei(gl.UNPACK_SKIP_PIXELS, this.m_skipPixels);
4759         this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
4760         this.m_context.texSubImage3D(
4761             gl.TEXTURE_3D, 0, this.m_subX, this.m_subY, this.m_subZ,
4762             this.m_subW, this.m_subH, this.m_subD, transferFmt.format,
4763             transferFmt.dataType, this.m_offset
4764         );
4765     };
4767     // TexImage2D() depth case.
4768     /**
4769      * @constructor
4770      * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
4771      * @param {string} name
4772      * @param {string} desc
4773      * @param {number} internalFormat
4774      * @param {number} imageWidth
4775      * @param {number} imageHeight
4776      */
4777     es3fTextureSpecificationTests.TexImage2DDepthCase = function(
4778         name, desc, internalFormat, imageWidth, imageHeight
4779     ) {
4780         es3fTextureSpecificationTests.Texture2DSpecCase.call(
4781             this, name, desc, gluTextureUtil.mapGLInternalFormat(
4782                 internalFormat
4783             ), imageWidth, imageHeight,
4784             es3fTextureSpecificationTests.maxLevelCount(
4785                 imageWidth, imageHeight
4786             )
4787         );
4789         this.m_internalFormat = internalFormat;
4790         // we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
4791         this.m_texFormatInfo.lookupBias = [0.25, 0.0, 0.0, 1.0];
4792         this.m_texFormatInfo.lookupScale = [0.5, 1.0, 1.0, 0.0];
4793     };
4795     es3fTextureSpecificationTests.TexImage2DDepthCase.prototype =
4796         Object.create(
4797             es3fTextureSpecificationTests.Texture2DSpecCase.prototype
4798         );
4800     es3fTextureSpecificationTests.
4801     TexImage2DDepthCase.prototype.constructor =
4802         es3fTextureSpecificationTests.TexImage2DDepthCase;
4804     /**
4805      * createTexture
4806      */
4807     es3fTextureSpecificationTests.TexImage2DDepthCase.prototype.createTexture =
4808     function() {
4809         var fmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
4810         var tex = null;
4811         var levelData = new tcuTexture.TextureLevel(
4812             this.m_texFormat, this.m_width, this.m_height
4813         );
4815         tex = this.m_context.createTexture();
4816         this.m_context.bindTexture(gl.TEXTURE_2D, tex);
4817         this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
4819         for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
4820             var levelW = Math.max(1, this.m_width >> ndx);
4821             var levelH = Math.max(1, this.m_height >> ndx);
4822             var gMin = [-1.5, -2.0, 1.7, -1.5];
4823             var gMax = [2.0, 1.5, -1.0, 2.0];
4825             levelData.setSize(levelW, levelH);
4826             tcuTextureUtil.fillWithComponentGradients(
4827                 levelData.getAccess(), gMin, gMax
4828             );
4830             this.m_context.texImage2D(
4831                 gl.TEXTURE_2D, ndx, this.m_internalFormat, levelW, levelH, 0,
4832                 fmt.format, fmt.dataType, levelData.getAccess().getDataPtr()
4833             );
4834         }
4835     };
4837     // TexImage3D() depth case.
4838     /**
4839      * @constructor
4840      * @extends {es3fTextureSpecificationTests.Texture2DArraySpecCase}
4841      * @param {string} name
4842      * @param {string} desc
4843      * @param {number} internalFormat
4844      * @param {number} imageWidth
4845      * @param {number} imageHeight
4846      * @param {number} numLayers
4847      */
4848     es3fTextureSpecificationTests.TexImage2DArrayDepthCase = function(
4849         name, desc, internalFormat, imageWidth, imageHeight, numLayers
4850     ) {
4851         es3fTextureSpecificationTests.Texture2DArraySpecCase.call(
4852             this, name, desc, gluTextureUtil.mapGLInternalFormat(
4853                 internalFormat
4854             ), imageWidth, imageHeight, numLayers,
4855             es3fTextureSpecificationTests.maxLevelCount(
4856                 imageWidth, imageHeight
4857             )
4858         );
4860         this.m_internalFormat = internalFormat;
4861         // we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
4862         this.m_texFormatInfo.lookupBias = [0.25, 0.0, 0.0, 1.0];
4863         this.m_texFormatInfo.lookupScale = [0.5, 1.0, 1.0, 0.0];
4864     };
4866     es3fTextureSpecificationTests.TexImage2DArrayDepthCase.prototype =
4867         Object.create(
4868             es3fTextureSpecificationTests.Texture2DArraySpecCase.prototype
4869         );
4871     es3fTextureSpecificationTests.
4872     TexImage2DArrayDepthCase.prototype.constructor =
4873         es3fTextureSpecificationTests.TexImage2DArrayDepthCase;
4875     /**
4876      * createTexture
4877      */
4878     es3fTextureSpecificationTests.
4879     TexImage2DArrayDepthCase.prototype.createTexture = function() {
4880         var fmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
4881         var tex = null;
4882         var levelData = new tcuTexture.TextureLevel(
4883             this.m_texFormat, this.m_width, this.m_height
4884         );
4886         tex = this.m_context.createTexture();
4887         this.m_context.bindTexture(gl.TEXTURE_2D_ARRAY, tex);
4888         this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
4890         for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
4891             var levelW = Math.max(1, this.m_width >> ndx);
4892             var levelH = Math.max(1, this.m_height >> ndx);
4893             var gMin = [-1.5, -2.0, 1.7, -1.5];
4894             var gMax = [2.0, 1.5, -1.0, 2.0];
4896             levelData.setSize(levelW, levelH, this.m_numLayers);
4897             tcuTextureUtil.fillWithComponentGradients(
4898                 levelData.getAccess(), gMin, gMax
4899             );
4901             this.m_context.texImage3D(
4902                 gl.TEXTURE_2D_ARRAY, ndx, this.m_internalFormat, levelW, levelH,
4903                 this.m_numLayers, 0, fmt.format, fmt.dataType,
4904                 levelData.getAccess().getDataPtr()
4905             );
4906         }
4907     };
4909     // TexSubImage2D() depth case.
4910     /**
4911      * @constructor
4912      * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
4913      * @param {string} name
4914      * @param {string} desc
4915      * @param {number} internalFormat
4916      * @param {number} imageWidth
4917      * @param {number} imageHeight
4918      */
4919     es3fTextureSpecificationTests.TexSubImage2DDepthCase = function(
4920         name, desc, internalFormat, imageWidth, imageHeight
4921     ) {
4922         es3fTextureSpecificationTests.Texture2DSpecCase.call(
4923             this, name, desc, gluTextureUtil.mapGLInternalFormat(
4924                 internalFormat
4925             ), imageWidth, imageHeight,
4926             es3fTextureSpecificationTests.maxLevelCount(
4927                 imageWidth, imageHeight
4928             )
4929         );
4931         this.m_internalFormat = internalFormat;
4932         // we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
4933         this.m_texFormatInfo.lookupBias = [0.25, 0.0, 0.0, 1.0];
4934         this.m_texFormatInfo.lookupScale = [0.5, 1.0, 1.0, 0.0];
4935     };
4937     es3fTextureSpecificationTests.TexSubImage2DDepthCase.prototype =
4938         Object.create(
4939             es3fTextureSpecificationTests.Texture2DSpecCase.prototype
4940         );
4942     es3fTextureSpecificationTests.
4943     TexSubImage2DDepthCase.prototype.constructor =
4944         es3fTextureSpecificationTests.TexSubImage2DDepthCase;
4946     /**
4947      * createTexture
4948      */
4949     es3fTextureSpecificationTests.
4950     TexSubImage2DDepthCase.prototype.createTexture = function() {
4951         var fmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
4952         var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
4953         var tex = null;
4954         var levelData = new tcuTexture.TextureLevel(
4955             this.m_texFormat, this.m_width, this.m_height
4956         );
4958         tex = this.m_context.createTexture();
4959         this.m_context.bindTexture(gl.TEXTURE_2D, tex);
4960         this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
4962         // First specify full texture.
4963         for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
4964             var levelW = Math.max(1, this.m_width >> ndx);
4965             var levelH = Math.max(1, this.m_height >> ndx);
4966             var gMin = [-1.5, -2.0, 1.7, -1.5];
4967             var gMax = [2.0, 1.5, -1.0, 2.0];
4969             levelData.setSize(levelW, levelH);
4970             tcuTextureUtil.fillWithComponentGradients(
4971                 levelData.getAccess(), gMin, gMax
4972             );
4974             this.m_context.texImage2D(
4975                 gl.TEXTURE_2D, ndx, this.m_internalFormat, levelW, levelH, 0,
4976                 fmt.format, fmt.dataType, levelData.getAccess().getDataPtr()
4977             );
4978         }
4980         // Re-specify parts of each level.
4981         for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
4982             var levelW = Math.max(1, this.m_width >> ndx);
4983             var levelH = Math.max(1, this.m_height >> ndx);
4985             var w = rnd.getInt(1, levelW);
4986             var h = rnd.getInt(1, levelH);
4987             var x = rnd.getInt(0, levelW - w);
4988             var y = rnd.getInt(0, levelH - h);
4990              var colorA = [2.0, 1.5, -1.0, 2.0];
4991              var colorB = [-1.5, -2.0, 1.7, -1.5];
4992              var cellSize = rnd.getInt(2, 16);
4994             levelData.setSize(w, h);
4995             tcuTextureUtil.fillWithGrid(
4996                 levelData.getAccess(), cellSize, colorA, colorB
4997             );
4999             this.m_context.texSubImage2D(
5000                 gl.TEXTURE_2D, ndx, x, y, w, h, fmt.format, fmt.dataType,
5001                 levelData.getAccess().getDataPtr()
5002             );
5003         }
5004     };
5006     // TexSubImage3D() depth case.
5007     /**
5008      * @constructor
5009      * @extends {es3fTextureSpecificationTests.Texture2DArraySpecCase}
5010      * @param {string} name
5011      * @param {string} desc
5012      * @param {number} internalFormat
5013      * @param {number} imageWidth
5014      * @param {number} imageHeight
5015      * @param {number} numLayers
5016      */
5017     es3fTextureSpecificationTests.TexSubImage2DArrayDepthCase = function(
5018         name, desc, internalFormat, imageWidth, imageHeight, numLayers
5019     ) {
5020         es3fTextureSpecificationTests.Texture2DArraySpecCase.call(
5021             this, name, desc, gluTextureUtil.mapGLInternalFormat(
5022                 internalFormat
5023             ), imageWidth, imageHeight, numLayers,
5024             es3fTextureSpecificationTests.maxLevelCount(
5025                 imageWidth, imageHeight
5026             )
5027         );
5029         this.m_internalFormat = internalFormat;
5030         // we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
5031         this.m_texFormatInfo.lookupBias = [0.25, 0.0, 0.0, 1.0];
5032         this.m_texFormatInfo.lookupScale = [0.5, 1.0, 1.0, 0.0];
5033     };
5035     es3fTextureSpecificationTests.TexSubImage2DArrayDepthCase.prototype =
5036         Object.create(
5037             es3fTextureSpecificationTests.Texture2DArraySpecCase.prototype
5038         );
5040     es3fTextureSpecificationTests.
5041     TexSubImage2DArrayDepthCase.prototype.constructor =
5042         es3fTextureSpecificationTests.TexSubImage2DArrayDepthCase;
5044     /**
5045      * createTexture
5046      */
5047     es3fTextureSpecificationTests.
5048     TexSubImage2DArrayDepthCase.prototype.createTexture = function() {
5049         var fmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
5050         var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
5051         var tex = null;
5052         var levelData = new tcuTexture.TextureLevel(
5053             this.m_texFormat, this.m_width, this.m_height
5054         );
5056         tex = this.m_context.createTexture();
5057         this.m_context.bindTexture(gl.TEXTURE_2D_ARRAY, tex);
5058         this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
5060         // First specify full texture.
5061         for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
5062             var levelW = Math.max(1, this.m_width >> ndx);
5063             var levelH = Math.max(1, this.m_height >> ndx);
5064             var gMin = [-1.5, -2.0, 1.7, -1.5];
5065             var gMax = [2.0, 1.5, -1.0, 2.0];
5067             levelData.setSize(levelW, levelH, this.m_numLayers);
5068             tcuTextureUtil.fillWithComponentGradients(
5069                 levelData.getAccess(), gMin, gMax
5070             );
5071             this.m_context.texImage3D(
5072                 gl.TEXTURE_2D_ARRAY, ndx, this.m_internalFormat, levelW, levelH,
5073                 this.m_numLayers, 0, fmt.format, fmt.dataType,
5074                 levelData.getAccess().getDataPtr()
5075             );
5076         }
5078         // Re-specify parts of each level.
5079         for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
5080             var levelW = Math.max(1, this.m_width >> ndx);
5081             var levelH = Math.max(1, this.m_height >> ndx);
5083             var w = rnd.getInt(1, levelW);
5084             var h = rnd.getInt(1, levelH);
5085             var d = rnd.getInt(1, this.m_numLayers);
5086             var x = rnd.getInt(0, levelW - w);
5087             var y = rnd.getInt(0, levelH - h);
5088             var z = rnd.getInt(0, this.m_numLayers - d);
5090              var colorA = [2.0, 1.5, -1.0, 2.0];
5091              var colorB = [-1.5, -2.0, 1.7, -1.5];
5092              var cellSize = rnd.getInt(2, 16);
5094             levelData.setSize(w, h, d);
5095             tcuTextureUtil.fillWithGrid(
5096                 levelData.getAccess(), cellSize, colorA, colorB
5097             );
5099             this.m_context.texSubImage3D(
5100                 gl.TEXTURE_2D_ARRAY, ndx, x, y, z, w, h, d, fmt.format,
5101                 fmt.dataType, levelData.getAccess().getDataPtr()
5102             );
5103         }
5104     };
5106     // TexImage2D() depth case with pbo.
5107     /**
5108      * @constructor
5109      * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
5110      * @param {string} name
5111      * @param {string} desc
5112      * @param {number} internalFormat
5113      * @param {number} imageWidth
5114      * @param {number} imageHeight
5115      */
5116     es3fTextureSpecificationTests.TexImage2DDepthBufferCase = function(
5117         name, desc, internalFormat, imageWidth, imageHeight
5118     ) {
5119         es3fTextureSpecificationTests.Texture2DSpecCase.call(
5120             this, name, desc, gluTextureUtil.mapGLInternalFormat(
5121                 internalFormat
5122             ), imageWidth, imageHeight, 1
5123         );
5125         this.m_internalFormat = internalFormat;
5126         // we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
5127         this.m_texFormatInfo.lookupBias = [0.25, 0.0, 0.0, 1.0];
5128         this.m_texFormatInfo.lookupScale = [0.5, 1.0, 1.0, 0.0];
5129     };
5131     es3fTextureSpecificationTests.TexImage2DDepthBufferCase.prototype =
5132         Object.create(
5133             es3fTextureSpecificationTests.Texture2DSpecCase.prototype
5134         );
5136     es3fTextureSpecificationTests.
5137     TexImage2DDepthBufferCase.prototype.constructor =
5138         es3fTextureSpecificationTests.TexImage2DDepthBufferCase;
5140     /**
5141      * createTexture
5142      */
5143     es3fTextureSpecificationTests.
5144     TexImage2DDepthBufferCase.prototype.createTexture = function() {
5145         var transferFmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
5146         var pixelSize = this.m_texFormat.getPixelSize();
5147         var rowLength = this.m_width;
5148         var alignment = 4;
5149         var rowPitch = deMath.deAlign32(rowLength * pixelSize, alignment);
5150         var height = this.m_height;
5151         var buf = null;
5152         var tex = null;
5153         var data = new ArrayBuffer(rowPitch * height);
5155         assertMsgOptions(
5156             this.m_numLevels == 1, 'Number of levels is different than 1',
5157             false, true
5158         );
5160         // Fill data with gradient
5161         var gMin = [-1.5, -2.0, 1.7, -1.5];
5162         var gMax = [2.0, 1.5, -1.0, 2.0];
5164         var access = new tcuTexture.PixelBufferAccess({
5165                         format: this.m_texFormat,
5166                         width: this.m_width,
5167                         height: this.m_height,
5168                         rowPitch: rowPitch,
5169                         data: data
5170                     });
5171         tcuTextureUtil.fillWithComponentGradients(access, gMin, gMax);
5173         // Create buffer and upload.
5174         buf = this.m_context.createBuffer();
5175         this.m_context.bindBuffer(gl.PIXEL_UNPACK_BUFFER, buf);
5176         this.m_context.bufferData(
5177             gl.PIXEL_UNPACK_BUFFER, access.getBuffer(), gl.STATIC_DRAW
5178         );
5180         this.m_context.pixelStorei(gl.UNPACK_ROW_LENGTH, rowLength);
5181         this.m_context.pixelStorei(gl.UNPACK_SKIP_ROWS, 0);
5182         this.m_context.pixelStorei(gl.UNPACK_SKIP_PIXELS, 0);
5183         this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, alignment);
5185         tex = this.m_context.createTexture();
5186         this.m_context.bindTexture(gl.TEXTURE_2D, tex);
5187         this.m_context.texImage2D(
5188             gl.TEXTURE_2D, 0, this.m_internalFormat, this.m_width,
5189             this.m_height, 0, transferFmt.format, transferFmt.dataType, 0
5190         );
5191         this.m_context.deleteBuffer(buf);
5192     };
5194     // TexImage3D() depth case with pbo.
5195     /**
5196      * @constructor
5197      * @extends {es3fTextureSpecificationTests.Texture2DArraySpecCase}
5198      * @param {string} name
5199      * @param {string} desc
5200      * @param {number} internalFormat
5201      * @param {number} imageWidth
5202      * @param {number} imageHeight
5203      */
5204     es3fTextureSpecificationTests.TexImage2DArrayDepthBufferCase = function(
5205         name, desc, internalFormat, imageWidth, imageHeight, numLayers
5206     ) {
5207         es3fTextureSpecificationTests.Texture2DArraySpecCase.call(
5208             this, name, desc, gluTextureUtil.mapGLInternalFormat(
5209                 internalFormat
5210             ), imageWidth, imageHeight, numLayers, 1
5211         );
5213         this.m_internalFormat = internalFormat;
5214         // we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
5215         this.m_texFormatInfo.lookupBias = [0.25, 0.0, 0.0, 1.0];
5216         this.m_texFormatInfo.lookupScale = [0.5, 1.0, 1.0, 0.0];
5217     };
5219     es3fTextureSpecificationTests.TexImage2DArrayDepthBufferCase.prototype =
5220         Object.create(
5221             es3fTextureSpecificationTests.Texture2DArraySpecCase.prototype
5222         );
5224     es3fTextureSpecificationTests.
5225     TexImage2DArrayDepthBufferCase.prototype.constructor =
5226         es3fTextureSpecificationTests.TexImage2DArrayDepthBufferCase;
5228     /**
5229      * createTexture
5230      */
5231     es3fTextureSpecificationTests.
5232     TexImage2DArrayDepthBufferCase.prototype.createTexture = function() {
5233         var transferFmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
5234         var pixelSize = this.m_texFormat.getPixelSize();
5235         var rowLength = this.m_width;
5236         var alignment = 4;
5237         var rowPitch = deMath.deAlign32(rowLength * pixelSize, alignment);
5238         var imageHeight = this.m_height;
5239         var slicePitch = imageHeight * rowPitch;
5240         var tex = null;
5241         var buf = null;
5242         var data = new ArrayBuffer(slicePitch * this.m_numLayers);
5244         assertMsgOptions(
5245             this.m_numLevels == 1, 'Number of levels is different than 1',
5246             false, true
5247         );
5249         // Fill data with gradient
5250         var gMin = [-1.5, -2.0, 1.7, -1.5];
5251         var gMax = [2.0, 1.5, -1.0, 2.0];
5253         var access = new tcuTexture.PixelBufferAccess({
5254                         format: this.m_texFormat,
5255                         width: this.m_width,
5256                         height: this.m_height,
5257                         depth: this.m_numLayers,
5258                         rowPitch: rowPitch,
5259                         slicePitch: slicePitch,
5260                         data: data
5261                     });
5262         tcuTextureUtil.fillWithComponentGradients(access, gMin, gMax);
5264         buf = this.m_context.createBuffer();
5265         this.m_context.bindBuffer(gl.PIXEL_UNPACK_BUFFER, buf);
5266         this.m_context.bufferData(
5267             gl.PIXEL_UNPACK_BUFFER, access.getBuffer(), gl.STATIC_DRAW
5268         );
5270         this.m_context.pixelStorei(gl.UNPACK_IMAGE_HEIGHT, rowLength);
5271         this.m_context.pixelStorei(gl.UNPACK_ROW_LENGTH, rowLength);
5272         this.m_context.pixelStorei(gl.UNPACK_SKIP_IMAGES, 0);
5273         this.m_context.pixelStorei(gl.UNPACK_SKIP_ROWS, 0);
5274         this.m_context.pixelStorei(gl.UNPACK_SKIP_PIXELS, 0);
5275         this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, alignment);
5277         tex = this.m_context.createTexture();
5278         this.m_context.bindTexture(gl.TEXTURE_2D_ARRAY, tex);
5279         this.m_context.texImage3D(
5280             gl.TEXTURE_2D_ARRAY, 0, this.m_internalFormat, this.m_width,
5281             this.m_height, this.m_numLayers, 0, transferFmt.format,
5282             transferFmt.dataType, 0
5283         );
5284         this.m_context.deleteBuffer(buf);
5285     };
5287     /**
5288      * @constructor
5289      * @extends {tcuTestCase.DeqpTest}
5290      */
5291     es3fTextureSpecificationTests.TextureSpecificationTests = function() {
5292         tcuTestCase.DeqpTest.call(
5293             this, 'specification', 'Texture Specification Tests'
5294         );
5295     };
5297     es3fTextureSpecificationTests.TextureSpecificationTests.prototype =
5298         Object.create(tcuTestCase.DeqpTest.prototype);
5299     es3fTextureSpecificationTests.TextureSpecificationTests.prototype.constructor =
5300         es3fTextureSpecificationTests.TextureSpecificationTests;
5302     es3fTextureSpecificationTests.TextureSpecificationTests.prototype.init = function() {
5303         /**
5304          * @type {Array<number>}
5305          */
5306         es3fTextureSpecificationTests.s_cubeMapFaces = [
5307             gl.TEXTURE_CUBE_MAP_NEGATIVE_X,
5308             gl.TEXTURE_CUBE_MAP_POSITIVE_X,
5309             gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,
5310             gl.TEXTURE_CUBE_MAP_POSITIVE_Y,
5311             gl.TEXTURE_CUBE_MAP_NEGATIVE_Z,
5312             gl.TEXTURE_CUBE_MAP_POSITIVE_Z
5313         ];
5315         /** @type {Array<{name: string, format: number, dataType: number}>} */
5316         var unsizedFormats = [{
5317                 name: 'alpha_unsigned_byte',
5318                 format: gl.ALPHA,
5319                 dataType: gl.UNSIGNED_BYTE
5320             }, {
5321                 name: 'luminance_unsigned_byte',
5322                 format: gl.LUMINANCE,
5323                 dataType: gl.UNSIGNED_BYTE
5324             }, {
5325                 name: 'luminance_alpha_unsigned_byte',
5326                 format: gl.LUMINANCE_ALPHA,
5327                 dataType: gl.UNSIGNED_BYTE
5328             }, {
5329                 name: 'rgb_unsigned_short_5_6_5',
5330                 format: gl.RGB,
5331                 dataType: gl.UNSIGNED_SHORT_5_6_5
5332             }, {
5333                 name: 'rgb_unsigned_byte',
5334                 format: gl.RGB,
5335                 dataType: gl.UNSIGNED_BYTE
5336             }, {
5337                 name: 'rgba_unsigned_short_4_4_4_4',
5338                 format: gl.RGBA,
5339                 dataType: gl.UNSIGNED_SHORT_4_4_4_4
5340             }, {
5341                 name: 'rgba_unsigned_short_5_5_5_1',
5342                 format: gl.RGBA,
5343                 dataType: gl.UNSIGNED_SHORT_5_5_5_1
5344             }, {
5345                 name: 'rgba_unsigned_byte',
5346                 format: gl.RGBA,
5347                 dataType: gl.UNSIGNED_BYTE
5348             }
5349         ];
5351         /** @type {Array<{name: string, internalFormat: number}>} */
5352         var colorFormats = [{
5353                 name: 'rgba32f', internalFormat: gl.RGBA32F
5354             }, {
5355                 name: 'rgba32i', internalFormat: gl.RGBA32I
5356             }, {
5357                 name: 'rgba32ui', internalFormat: gl.RGBA32UI
5358             }, {
5359                 name: 'rgba16f', internalFormat: gl.RGBA16F
5360             }, {
5361                 name: 'rgba16i', internalFormat: gl.RGBA16I
5362             }, {
5363                 name: 'rgba16ui', internalFormat: gl.RGBA16UI
5364             }, {
5365                 name: 'rgba8', internalFormat: gl.RGBA8
5366             }, {
5367                 name: 'rgba8i', internalFormat: gl.RGBA8I
5368             }, {
5369                 name: 'rgba8ui', internalFormat: gl.RGBA8UI
5370             }, {
5371                 name: 'srgb8_alpha8', internalFormat: gl.SRGB8_ALPHA8
5372             }, {
5373                 name: 'rgb10_a2', internalFormat: gl.RGB10_A2
5374             }, {
5375                 name: 'rgb10_a2ui', internalFormat: gl.RGB10_A2UI
5376             }, {
5377                 name: 'rgba4', internalFormat: gl.RGBA4
5378             }, {
5379                 name: 'rgb5_a1', internalFormat: gl.RGB5_A1
5380             }, {
5381                 name: 'rgba8_snorm', internalFormat: gl.RGBA8_SNORM
5382             }, {
5383                 name: 'rgb8', internalFormat: gl.RGB8
5384             }, {
5385                 name: 'rgb565', internalFormat: gl.RGB565
5386             }, {
5387                 name: 'r11f_g11f_b10f', internalFormat: gl.R11F_G11F_B10F
5388             }, {
5389                 name: 'rgb32f', internalFormat: gl.RGB32F
5390             }, {
5391                 name: 'rgb32i', internalFormat: gl.RGB32I
5392             }, {
5393                 name: 'rgb32ui', internalFormat: gl.RGB32UI
5394             }, {
5395                 name: 'rgb16f', internalFormat: gl.RGB16F
5396             }, {
5397                 name: 'rgb16i', internalFormat: gl.RGB16I
5398             }, {
5399                 name: 'rgb16ui', internalFormat: gl.RGB16UI
5400             }, {
5401                 name: 'rgb8_snorm', internalFormat: gl.RGB8_SNORM
5402             }, {
5403                 name: 'rgb8i', internalFormat: gl.RGB8I
5404             }, {
5405                 name: 'rgb8ui', internalFormat: gl.RGB8UI
5406             }, {
5407                 name: 'srgb8', internalFormat: gl.SRGB8
5408             }, {
5409                 name: 'rgb9_e5', internalFormat: gl.RGB9_E5
5410             }, {
5411                 name: 'rg32f', internalFormat: gl.RG32F
5412             }, {
5413                 name: 'rg32i', internalFormat: gl.RG32I
5414             }, {
5415                 name: 'rg32ui', internalFormat: gl.RG32UI
5416             }, {
5417                 name: 'rg16f', internalFormat: gl.RG16F
5418             }, {
5419                 name: 'rg16i', internalFormat: gl.RG16I
5420             }, {
5421                 name: 'rg16ui', internalFormat: gl.RG16UI
5422             }, {
5423                 name: 'rg8', internalFormat: gl.RG8
5424             }, {
5425                 name: 'rg8i', internalFormat: gl.RG8I
5426             }, {
5427                 name: 'rg8ui', internalFormat: gl.RG8UI
5428             }, {
5429                 name: 'rg8_snorm', internalFormat: gl.RG8_SNORM
5430             }, {
5431                 name: 'r32f', internalFormat: gl.R32F
5432             }, {
5433                 name: 'r32i', internalFormat: gl.R32I
5434             }, {
5435                 name: 'r32ui', internalFormat: gl.R32UI
5436             }, {
5437                 name: 'r16f', internalFormat: gl.R16F
5438             }, {
5439                 name: 'r16i', internalFormat: gl.R16I
5440             }, {
5441                 name: 'r16ui', internalFormat: gl.R16UI
5442             }, {
5443                 name: 'r8', internalFormat: gl.R8
5444             }, {
5445                 name: 'r8i', internalFormat: gl.R8I
5446             }, {
5447                 name: 'r8ui', internalFormat: gl.R8UI
5448             }, {
5449                 name: 'r8_snorm', internalFormat: gl.R8_SNORM
5450             }
5451         ];
5453         // Depth and stencil formats
5454         /** @type {Array<{name: string, internalFormat: number}>} */
5455         var depthStencilFormats = [{
5456                 name: 'depth_component32f',
5457                 internalFormat: gl.DEPTH_COMPONENT32F
5458             }, {
5459                 name: 'depth_component24',
5460                 internalFormat: gl.DEPTH_COMPONENT24
5461             }, {
5462                 name: 'depth_component16',
5463                 internalFormat: gl.DEPTH_COMPONENT16
5464             }, {
5465                 name: 'depth32f_stencil8',
5466                 internalFormat: gl.DEPTH32F_STENCIL8
5467             }, {
5468                 name: 'depth24_stencil8',
5469                 internalFormat: gl.DEPTH24_STENCIL8
5470             }
5471         ];
5473         // Basic TexImage2D usage.
5474         var splitBasicTex2D = 2, splitBasicTexCube = 5;
5475         /** @type {Array<{tcuTestCase.DeqpTest}>} */
5476         var basicTexImageGroup2D = [];
5477         for (var ii = 0; ii < splitBasicTex2D; ++ii) {
5478             basicTexImageGroup2D.push(
5479                 new tcuTestCase.DeqpTest('basic_teximage2d', 'Basic glTexImage2D() usage')
5480             );
5481             this.addChild(basicTexImageGroup2D[ii]);
5482         }
5483         /** @type {Array<{tcuTestCase.DeqpTest}>} */
5484         var basicTexImageGroupCube = [];
5485         for (var ii = 0; ii < splitBasicTexCube; ++ii) {
5486             basicTexImageGroupCube.push(
5487                 new tcuTestCase.DeqpTest('basic_teximage2d', 'Basic glTexImage2D() usage')
5488             );
5489             this.addChild(basicTexImageGroupCube[ii]);
5490         }
5491         for (var formatNdx = 0; formatNdx < colorFormats.length; formatNdx++) {
5492             /** @type {string} */
5493             var fmtName = colorFormats[formatNdx].name;
5494             /** @type {number} */
5495             var format = colorFormats[formatNdx].internalFormat;
5496             /** @type {number} */
5497             var tex2DWidth = 64;
5498             /** @type {number} */
5499             var tex2DHeight = 128;
5500             /** @type {number} */
5501             var texCubeSize = 64;
5503             basicTexImageGroup2D[formatNdx % splitBasicTex2D].addChild(
5504                 es3fTextureSpecificationTests.newBasicTexImage2DCaseInternal(
5505                     fmtName + '_2d', '', format, tex2DWidth, tex2DHeight
5506                 )
5507             );
5508             basicTexImageGroupCube[formatNdx % splitBasicTexCube].addChild(
5509                 es3fTextureSpecificationTests.newBasicTexImageCubeCaseInternal(
5510                     fmtName + '_cube', '', format, texCubeSize
5511                 )
5512             );
5513         }
5515         // Randomized TexImage2D order.
5516         /** @type {tcuTestCase.DeqpTest} */
5517         var randomTexImageGroup = new tcuTestCase.DeqpTest(
5518             'random_teximage2d', 'Randomized glTexImage2D() usage'
5519         );
5520         this.addChild(randomTexImageGroup);
5521         var rnd = new deRandom.Random(9);
5523         // 2D cases.
5524         for (var ndx = 0; ndx < 10; ndx++) {
5525             var formatNdx = rnd.getInt(0, colorFormats.length - 1);
5526             var width = 1 << rnd.getInt(2, 8);
5527             var height = 1 << rnd.getInt(2, 8);
5529             randomTexImageGroup.addChild(
5530                 es3fTextureSpecificationTests.newRandomOrderTexImage2DCaseInternal(
5531                     '2d.' + colorFormats[formatNdx].name, '',
5532                     colorFormats[formatNdx].internalFormat, width, height
5533                 )
5534             );
5535         }
5537         // Cubemap cases.
5538         randomTexImageGroup = new tcuTestCase.DeqpTest(
5539             'random_teximage2d', 'Randomized glTexImage2D() usage'
5540         );
5541         this.addChild(randomTexImageGroup);
5543         for (var ndx = 0; ndx < 10; ndx++) {
5544             formatNdx = rnd.getInt(0, colorFormats.length - 1);
5545             /** @type {number} */ var size = 1 << rnd.getInt(2, 8);
5547             randomTexImageGroup.addChild(
5548                 es3fTextureSpecificationTests.newRandomOrderTexImageCubeCaseInternal(
5549                     'cube.' + colorFormats[formatNdx].name, '',
5550                     colorFormats[formatNdx].internalFormat, size
5551                 )
5552             );
5553         }
5555         // TexImage2D unpack alignment.
5556         /** @type {tcuTestCase.DeqpTest} */
5557         var alignGroup = new tcuTestCase.DeqpTest(
5558             'teximage2d_align', 'glTexImage2D() unpack alignment tests'
5559         );
5560         this.addChild(alignGroup);
5562         alignGroup.addChild(
5563             es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
5564                 '2d_r8_4_8', '', gl.R8, 4, 8, 4, 8
5565             )
5566         );
5567         alignGroup.addChild(
5568             es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
5569                 '2d_r8_63_1', '', gl.R8, 63, 30, 1, 1
5570             )
5571         );
5572         alignGroup.addChild(
5573             es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
5574                 '2d_r8_63_2', '', gl.R8, 63, 30, 1, 2
5575             )
5576         );
5577         alignGroup.addChild(
5578             es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
5579                 '2d_r8_63_4', '', gl.R8, 63, 30, 1, 4
5580             )
5581         );
5582         alignGroup.addChild(
5583             es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
5584                 '2d_r8_63_8', '', gl.R8, 63, 30, 1, 8
5585             )
5586         );
5587         alignGroup.addChild(
5588             es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
5589                 '2d_rgba4_51_1', '', gl.RGBA4, 51, 30, 1, 1
5590             )
5591         );
5592         alignGroup.addChild(
5593             es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
5594                 '2d_rgba4_51_2', '', gl.RGBA4, 51, 30, 1, 2
5595             )
5596         );
5597         alignGroup.addChild(
5598             es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
5599                 '2d_rgba4_51_4', '', gl.RGBA4, 51, 30, 1, 4
5600             )
5601         );
5602         alignGroup.addChild(
5603             es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
5604                 '2d_rgba4_51_8', '', gl.RGBA4, 51, 30, 1, 8
5605             )
5606         );
5607         alignGroup.addChild(
5608             es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
5609                 '2d_rgb8_39_1', '', gl.RGB8, 39, 43, 1, 1
5610             )
5611         );
5612         alignGroup.addChild(
5613             es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
5614                 '2d_rgb8_39_2', '', gl.RGB8, 39, 43, 1, 2
5615             )
5616         );
5617         alignGroup.addChild(
5618             es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
5619                 '2d_rgb8_39_4', '', gl.RGB8, 39, 43, 1, 4
5620             )
5621         );
5622         alignGroup.addChild(
5623             es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
5624                 '2d_rgb8_39_8', '', gl.RGB8, 39, 43, 1, 8
5625             )
5626         );
5627         alignGroup.addChild(
5628             es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
5629                 '2d_rgba8_47_1', '', gl.RGBA8, 47, 27, 1, 1
5630             )
5631         );
5632         alignGroup.addChild(
5633             es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
5634                 '2d_rgba8_47_2', '', gl.RGBA8, 47, 27, 1, 2
5635             )
5636         );
5637         alignGroup.addChild(
5638             es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
5639                 '2d_rgba8_47_4', '', gl.RGBA8, 47, 27, 1, 4
5640             )
5641         );
5642         alignGroup.addChild(
5643             es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
5644                 '2d_rgba8_47_8', '', gl.RGBA8, 47, 27, 1, 8
5645             )
5646         );
5647         alignGroup.addChild(
5648             es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
5649                 'cube_r8_4_8', '', gl.R8, 4, 3, 8
5650             )
5651         );
5652         alignGroup.addChild(
5653             es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
5654                 'cube_r8_63_1', '', gl.R8, 63, 1, 1
5655             )
5656         );
5657         alignGroup.addChild(
5658             es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
5659                 'cube_r8_63_2', '', gl.R8, 63, 1, 2
5660             )
5661         );
5662         alignGroup.addChild(
5663             es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
5664                 'cube_r8_63_4', '', gl.R8, 63, 1, 4
5665             )
5666         );
5667         alignGroup.addChild(
5668             es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
5669                 'cube_r8_63_8', '', gl.R8, 63, 1, 8
5670             )
5671         );
5672         alignGroup.addChild(
5673             es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
5674                 'cube_rgba4_51_1', '', gl.RGBA4, 51, 1, 1
5675             )
5676         );
5677         alignGroup.addChild(
5678             es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
5679                 'cube_rgba4_51_2', '', gl.RGBA4, 51, 1, 2
5680             )
5681         );
5682         alignGroup.addChild(
5683             es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
5684                 'cube_rgba4_51_4', '', gl.RGBA4, 51, 1, 4
5685             )
5686         );
5687         alignGroup.addChild(
5688             es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
5689                 'cube_rgba4_51_8', '', gl.RGBA4, 51, 1, 8
5690             )
5691         );
5692         alignGroup.addChild(
5693             es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
5694                 'cube_rgb8_39_1', '', gl.RGB8, 39, 1, 1
5695             )
5696         );
5697         alignGroup.addChild(
5698             es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
5699                 'cube_rgb8_39_2', '', gl.RGB8, 39, 1, 2
5700             )
5701         );
5702         alignGroup.addChild(
5703             es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
5704                 'cube_rgb8_39_4', '', gl.RGB8, 39, 1, 4
5705             )
5706         );
5707         alignGroup.addChild(
5708             es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
5709                 'cube_rgb8_39_8', '', gl.RGB8, 39, 1, 8
5710             )
5711         );
5712         alignGroup.addChild(
5713             es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
5714                 'cube_rgba8_47_1', '', gl.RGBA8, 47, 1, 1
5715             )
5716         );
5717         alignGroup.addChild(
5718             es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
5719                 'cube_rgba8_47_2', '', gl.RGBA8, 47, 1, 2
5720             )
5721         );
5722         alignGroup.addChild(
5723             es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
5724                 'cube_rgba8_47_4', '', gl.RGBA8, 47, 1, 4
5725             )
5726         );
5727         alignGroup.addChild(
5728             es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
5729                 'cube_rgba8_47_8', '', gl.RGBA8, 47, 1, 8
5730             )
5731         );
5733         // glTexImage2D() unpack parameter cases.
5734         /** @type {tcuTestCase.DeqpTest} */
5735         var paramGroup = new tcuTestCase.DeqpTest(
5736             'teximage2d_unpack_params',
5737             'glTexImage2D() pixel transfer mode cases'
5738         );
5739         this.addChild(paramGroup);
5741         var cases = [{
5742                 name: 'rgb8_alignment', format: gl.RGB8, width: 31,
5743                 height: 30, rowLength: 0, skipRows: 0, skipPixels: 0,
5744                 alignment: 2
5745             }, {
5746                 name: 'rgb8_row_length', format: gl.RGB8, width: 31,
5747                 height: 30, rowLength: 50, skipRows: 0, skipPixels: 0,
5748                 alignment: 4
5749             }, {
5750                 name: 'rgb8_skip_rows', format: gl.RGB8, width: 31,
5751                 height: 30, rowLength: 0, skipRows: 3, skipPixels: 0,
5752                 alignment: 4
5753             }, {
5754                 name: 'rgb8_skip_pixels', format: gl.RGB8, width: 31,
5755                 height: 30, rowLength: 36, skipRows: 0, skipPixels: 5,
5756                 alignment: 4
5757             }, {
5758                 name: 'r8_complex1', format: gl.R8, width: 31,
5759                 height: 30, rowLength: 64, skipRows: 1, skipPixels: 3,
5760                 alignment: 1
5761             }, {
5762                 name: 'r8_complex2', format: gl.R8, width: 31,
5763                 height: 30, rowLength: 64, skipRows: 1, skipPixels: 3,
5764                 alignment: 2
5765             }, {
5766                 name: 'r8_complex3', format: gl.R8, width: 31,
5767                 height: 30, rowLength: 64, skipRows: 1, skipPixels: 3,
5768                 alignment: 4
5769             }, {
5770                 name: 'r8_complex4', format: gl.R8, width: 31,
5771                 height: 30, rowLength: 64, skipRows: 1, skipPixels: 3,
5772                 alignment: 8
5773             }, {
5774                 name: 'rgba8_complex1', format: gl.RGBA8, width: 56,
5775                 height: 61, rowLength: 69, skipRows: 0, skipPixels: 0,
5776                 alignment: 8
5777             }, {
5778                 name: 'rgba8_complex2', format: gl.RGBA8, width: 56,
5779                 height: 61, rowLength: 69, skipRows: 0, skipPixels: 7,
5780                 alignment: 8
5781             }, {
5782                 name: 'rgba8_complex3', format: gl.RGBA8, width: 56,
5783                 height: 61, rowLength: 69, skipRows: 3, skipPixels: 0,
5784                 alignment: 8
5785             }, {
5786                 name: 'rgba8_complex4', format: gl.RGBA8, width: 56,
5787                 height: 61, rowLength: 69, skipRows: 3, skipPixels: 7,
5788                 alignment: 8
5789             }, {
5790                 name: 'rgba32f_complex', format: gl.RGBA32F, width: 19,
5791                 height: 10, rowLength: 27, skipRows: 1, skipPixels: 7,
5792                 alignment: 8
5793             }
5794         ];
5796         for (var ndx = 0; ndx < cases.length; ndx++)
5797             paramGroup.addChild(
5798                 new es3fTextureSpecificationTests.TexImage2DParamsCase(
5799                     cases[ndx].name, '', cases[ndx].format, cases[ndx].width,
5800                     cases[ndx].height, cases[ndx].rowLength,
5801                     cases[ndx].skipRows, cases[ndx].skipPixels,
5802                     cases[ndx].alignment
5803                 )
5804             );
5806         // glTexImage2D() pbo cases.
5807         var splitPboTex2D = 2, splitPboTexCube = 5;
5808         /** @type {Array<{tcuTestCase.DeqpTest}>} */ var pboGroup2D = [];
5809         for (var ii = 0; ii < splitPboTex2D; ++ii) {
5810             pboGroup2D.push(new tcuTestCase.DeqpTest('teximage2d_pbo', 'glTexImage2D() from PBO'));
5811             this.addChild(pboGroup2D[ii]);
5812         }
5813         /** @type {Array<{tcuTestCase.DeqpTest}>} */ var pboGroupCube = [];
5814         for (var ii = 0; ii < splitPboTexCube; ++ii) {
5815             pboGroupCube.push(new tcuTestCase.DeqpTest('teximage2d_pbo', 'glTexImage2D() from PBO'));
5816            this.addChild(pboGroupCube[ii]);
5817         }
5818         for (var formatNdx = 0; formatNdx < colorFormats.length; formatNdx++) {
5819             fmtName = colorFormats[formatNdx].name;
5820             format = colorFormats[formatNdx].internalFormat;
5821             tex2DWidth = 65;
5822             tex2DHeight = 37;
5823             texCubeSize = 64;
5825             pboGroup2D[formatNdx % splitPboTex2D].addChild(
5826                 new es3fTextureSpecificationTests.TexImage2DBufferCase(
5827                     fmtName + '_2d', '', format,
5828                     tex2DWidth, tex2DHeight, 0, 0, 0, 4, 0
5829                 )
5830             );
5831             pboGroupCube[formatNdx % splitPboTexCube].addChild(
5832                 new es3fTextureSpecificationTests.TexImageCubeBufferCase(
5833                     fmtName + '_cube', '', format,
5834                     texCubeSize, 0, 0, 0, 4, 0
5835                 )
5836             );
5837         }
5839         // Parameter cases
5840         var pboGroupParams = new tcuTestCase.DeqpTest(
5841             'teximage2d_pbo', 'glTexImage2D() from PBO'
5842         );
5843         this.addChild(pboGroupParams);
5844         /**
5845          * @type {Array<{name: string, format: number, width: number,
5846          * height: number, rowLength: number, skipRows: number,
5847          * skipPixels: number, alignment: number, offset: number}>}
5848          */
5849         var parameterCases = [{
5850                 name: 'rgb8_offset', format: gl.RGB8, width: 31,
5851                 height: 30, rowLength: 0, skipRows: 0, skipPixels: 0,
5852                 alignment: 4, offset: 67
5853             }, {
5854                 name: 'rgb8_alignment', format: gl.RGB8, width: 31,
5855                 height: 30, rowLength: 0, skipRows: 0, skipPixels: 0,
5856                 alignment: 2, offset: 0
5857             }, {
5858                 name: 'rgb8_row_length', format: gl.RGB8, width: 31,
5859                 height: 30, rowLength: 50, skipRows: 0, skipPixels: 0,
5860                 alignment: 4, offset: 0
5861             }, {
5862                 name: 'rgb8_skip_rows', format: gl.RGB8, width: 31,
5863                 height: 30, rowLength: 0, skipRows: 3, skipPixels: 0,
5864                 alignment: 4, offset: 0
5865             }, {
5866                 name: 'rgb8_skip_pixels', format: gl.RGB8, width: 31,
5867                 height: 30, rowLength: 36, skipRows: 0, skipPixels: 5,
5868                 alignment: 4, offset: 0
5869             }
5870         ];
5871         for (var ndx = 0; ndx < parameterCases.length; ndx++) {
5872             pboGroupParams.addChild(
5873                 new es3fTextureSpecificationTests.TexImage2DBufferCase(
5874                     parameterCases[ndx].name + '_2d', '',
5875                     parameterCases[ndx].format, parameterCases[ndx].width,
5876                     parameterCases[ndx].height, parameterCases[ndx].rowLength,
5877                     parameterCases[ndx].skipRows,
5878                     parameterCases[ndx].skipPixels,
5879                     parameterCases[ndx].alignment,
5880                     parameterCases[ndx].offset
5881                 )
5882             );
5883             pboGroupParams.addChild(
5884                 new es3fTextureSpecificationTests.TexImageCubeBufferCase(
5885                     parameterCases[ndx].name + '_cube', '',
5886                     parameterCases[ndx].format, parameterCases[ndx].width,
5887                     parameterCases[ndx].rowLength, parameterCases[ndx].skipRows,
5888                     parameterCases[ndx].skipPixels,
5889                     parameterCases[ndx].alignment, parameterCases[ndx].offset
5890                 )
5891             );
5892         }
5894         // glTexImage2D() depth cases.
5895         /** @type {tcuTestCase.DeqpTest} */
5896         var shadow2dGroup = new tcuTestCase.DeqpTest(
5897             'teximage2d_depth',
5898             'glTexImage2D() with depth or depth/stencil format'
5899         );
5900         this.addChild(shadow2dGroup);
5902         for (var ndx = 0; ndx < depthStencilFormats.length; ndx++) {
5903             // WebGL 2 specific constraint.
5904             if (depthStencilFormats[ndx].internalFormat == gl.DEPTH32F_STENCIL8)
5905                 continue;
5906             var tex2DWidth = 64;
5907             var tex2DHeight = 128;
5909             shadow2dGroup.addChild(
5910                 new es3fTextureSpecificationTests.TexImage2DDepthCase(
5911                     depthStencilFormats[ndx].name, '',
5912                     depthStencilFormats[ndx].internalFormat,
5913                     tex2DWidth, tex2DHeight
5914                 )
5915             );
5916         }
5918         // glTexImage2D() depth cases with pbo.
5919         shadow2dGroup = new tcuTestCase.DeqpTest(
5920             'teximage2d_depth_pbo',
5921             'glTexImage2D() with depth or depth/stencil format with pbo'
5922         );
5923         this.addChild(shadow2dGroup);
5925         for (var ndx = 0; ndx < depthStencilFormats.length; ndx++) {
5926             tex2DWidth = 64;
5927             tex2DHeight = 128;
5929             shadow2dGroup.addChild(
5930                 new es3fTextureSpecificationTests.TexImage2DDepthBufferCase(
5931                     depthStencilFormats[ndx].name, '',
5932                     depthStencilFormats[ndx].internalFormat,
5933                     tex2DWidth, tex2DHeight
5934                 )
5935             );
5936         }
5938         // Basic TexSubImage2D usage.
5939         splitBasicTex2D = 3;
5940         splitBasicTexCube = 5;
5941         /** @type {Array<{tcuTestCase.DeqpTest}>} */
5942         var basicTexSubImageGroup2D = [];
5943         for (var ii = 0; ii < splitBasicTex2D; ++ii) {
5944             basicTexSubImageGroup2D.push(
5945                 new tcuTestCase.DeqpTest('basic_texsubimage2d', 'Basic glTexSubImage2D() usage')
5946             );
5947             this.addChild(basicTexSubImageGroup2D[ii]);
5948         }
5949         /** @type {Array<{tcuTestCase.DeqpTest}>} */
5950         var basicTexSubImageGroupCube = [];
5951         for (var ii = 0; ii < splitBasicTexCube; ++ii) {
5952             basicTexSubImageGroupCube.push(
5953                 new tcuTestCase.DeqpTest('basic_texsubimage2d', 'Basic glTexSubImage2D() usage')
5954             );
5955             this.addChild(basicTexSubImageGroupCube[ii]);
5956         }
5957         for (var formatNdx = 0; formatNdx < colorFormats.length; formatNdx++) {
5958             fmtName = colorFormats[formatNdx].name;
5959             format = colorFormats[formatNdx].internalFormat;
5960             tex2DWidth = 64;
5961             tex2DHeight = 128;
5962             texCubeSize = 64;
5964             basicTexSubImageGroup2D[formatNdx % splitBasicTex2D].addChild(
5965                 es3fTextureSpecificationTests.newBasicTexSubImage2DCaseInternal(
5966                     fmtName + '_2d', '', format, tex2DWidth, tex2DHeight
5967                 )
5968             );
5969             basicTexSubImageGroupCube[formatNdx % splitBasicTexCube].addChild(
5970                 es3fTextureSpecificationTests.newBasicTexImageCubeCaseInternal(
5971                     fmtName + '_cube', '', format, texCubeSize
5972                 )
5973             );
5974         }
5976         // TexSubImage2D to empty texture.
5977         /** @type {tcuTestCase.DeqpTest} */
5978         var texSubImageEmptyTexGroup = new tcuTestCase.DeqpTest(
5979             'texsubimage2d_empty_tex',
5980             'glTexSubImage2D() to texture that has storage but no data'
5981         );
5982         this.addChild(texSubImageEmptyTexGroup);
5983         for (var formatNdx = 0; formatNdx < unsizedFormats.length; formatNdx++) {
5984             fmtName = unsizedFormats[formatNdx].name;
5985             format = unsizedFormats[formatNdx].format;
5986             /** @type {number} */
5987             var dataType = unsizedFormats[formatNdx].dataType;
5988             tex2DWidth = 64;
5989             tex2DHeight = 32;
5990             texCubeSize = 32;
5992             texSubImageEmptyTexGroup.addChild(
5993                 new es3fTextureSpecificationTests.TexSubImage2DEmptyTexCase(
5994                     fmtName + '_2d', '', format, dataType, tex2DWidth, tex2DHeight
5995                 )
5996             );
5997             texSubImageEmptyTexGroup.addChild(
5998                 new es3fTextureSpecificationTests.TexSubImageCubeEmptyTexCase(
5999                     fmtName + '_cube', '', format, dataType, texCubeSize
6000                 )
6001             );
6002         }
6004         // TexSubImage2D alignment cases.
6005         alignGroup = new tcuTestCase.DeqpTest(
6006             'texsubimage2d_align', 'glTexSubImage2D() unpack alignment tests'
6007         );
6008         this.addChild(alignGroup);
6010         alignGroup.addChild(
6011             es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
6012                 '2d_r8_1_1', '', gl.R8, 64, 64, 13, 17, 1, 6, 1
6013             )
6014         );
6015         alignGroup.addChild(
6016             es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
6017                 '2d_r8_1_2', '', gl.R8, 64, 64, 13, 17, 1, 6, 2
6018             )
6019         );
6020         alignGroup.addChild(
6021             es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
6022                 '2d_r8_1_4', '', gl.R8, 64, 64, 13, 17, 1, 6, 4
6023             )
6024         );
6025         alignGroup.addChild(
6026             es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
6027                 '2d_r8_1_8', '', gl.R8, 64, 64, 13, 17, 1, 6, 8
6028             )
6029         );
6030         alignGroup.addChild(
6031             es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
6032                 '2d_r8_63_1', '', gl.R8, 64, 64, 1, 9, 63, 30, 1
6033             )
6034         );
6035         alignGroup.addChild(
6036             es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
6037                 '2d_r8_63_2', '', gl.R8, 64, 64, 1, 9, 63, 30, 2
6038             )
6039         );
6040         alignGroup.addChild(
6041             es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
6042                 '2d_r8_63_4', '', gl.R8, 64, 64, 1, 9, 63, 30, 4
6043             )
6044         );
6045         alignGroup.addChild(
6046             es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
6047                 '2d_r8_63_8', '', gl.R8, 64, 64, 1, 9, 63, 30, 8
6048             )
6049         );
6050         alignGroup.addChild(
6051             es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
6052                 '2d_rgba4_51_1', '', gl.RGBA4, 64, 64, 7, 29, 51, 30, 1
6053             )
6054         );
6055         alignGroup.addChild(
6056             es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
6057                 '2d_rgba4_51_2', '', gl.RGBA4, 64, 64, 7, 29, 51, 30, 2
6058             )
6059         );
6060         alignGroup.addChild(
6061             es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
6062                 '2d_rgba4_51_4', '', gl.RGBA4, 64, 64, 7, 29, 51, 30, 4
6063             )
6064         );
6065         alignGroup.addChild(
6066             es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
6067                 '2d_rgba4_51_8', '', gl.RGBA4, 64, 64, 7, 29, 51, 30, 8
6068             )
6069         );
6070         alignGroup.addChild(
6071             es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
6072                 '2d_rgb8_39_1', '', gl.RGB8, 64, 64, 11, 8, 39, 43, 1
6073             )
6074         );
6075         alignGroup.addChild(
6076             es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
6077                 '2d_rgb8_39_2', '', gl.RGB8, 64, 64, 11, 8, 39, 43, 2
6078             )
6079         );
6080         alignGroup.addChild(
6081             es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
6082                 '2d_rgb8_39_4', '', gl.RGB8, 64, 64, 11, 8, 39, 43, 4
6083             )
6084         );
6085         alignGroup.addChild(
6086             es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
6087                 '2d_rgb8_39_8', '', gl.RGB8, 64, 64, 11, 8, 39, 43, 8
6088             )
6089         );
6090         alignGroup.addChild(
6091             es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
6092                 '2d_rgba8_47_1', '', gl.RGBA8, 64, 64, 10, 1, 47, 27, 1
6093             )
6094         );
6095         alignGroup.addChild(
6096             es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
6097                 '2d_rgba8_47_2', '', gl.RGBA8, 64, 64, 10, 1, 47, 27, 2
6098             )
6099         );
6100         alignGroup.addChild(
6101             es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
6102                 '2d_rgba8_47_4', '', gl.RGBA8, 64, 64, 10, 1, 47, 27, 4
6103             )
6104         );
6105         alignGroup.addChild(
6106             es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
6107                 '2d_rgba8_47_8', '', gl.RGBA8, 64, 64, 10, 1, 47, 27, 8
6108             )
6109         );
6111         alignGroup.addChild(
6112             es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
6113                 'cube_r8_1_1', '', gl.R8, 64, 13, 17, 1, 6, 1
6114             )
6115         );
6116         alignGroup.addChild(
6117             es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
6118                 'cube_r8_1_2', '', gl.R8, 64, 13, 17, 1, 6, 2
6119             )
6120         );
6121         alignGroup.addChild(
6122             es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
6123                 'cube_r8_1_4', '', gl.R8, 64, 13, 17, 1, 6, 4
6124             )
6125         );
6126         alignGroup.addChild(
6127             es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
6128                 'cube_r8_1_8', '', gl.R8, 64, 13, 17, 1, 6, 8
6129             )
6130         );
6131         alignGroup.addChild(
6132             es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
6133                 'cube_r8_63_1', '', gl.R8, 64, 1, 9, 63, 30, 1
6134             )
6135         );
6136         alignGroup.addChild(
6137             es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
6138                 'cube_r8_63_2', '', gl.R8, 64, 1, 9, 63, 30, 2
6139             )
6140         );
6141         alignGroup.addChild(
6142             es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
6143                 'cube_r8_63_4', '', gl.R8, 64, 1, 9, 63, 30, 4
6144             )
6145         );
6146         alignGroup.addChild(
6147             es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
6148                 'cube_r8_63_8', '', gl.R8, 64, 1, 9, 63, 30, 8
6149             )
6150         );
6151         alignGroup.addChild(
6152             es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
6153                 'cube_rgba4_51_1', '', gl.RGBA4, 64, 7, 29, 51, 30, 1
6154             )
6155         );
6156         alignGroup.addChild(
6157             es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
6158                 'cube_rgba4_51_2', '', gl.RGBA4, 64, 7, 29, 51, 30, 2
6159             )
6160         );
6161         alignGroup.addChild(
6162             es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
6163                 'cube_rgba4_51_4', '', gl.RGBA4, 64, 7, 29, 51, 30, 4
6164             )
6165         );
6166         alignGroup.addChild(
6167             es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
6168                 'cube_rgba4_51_8', '', gl.RGBA4, 64, 7, 29, 51, 30, 8
6169             )
6170         );
6171         alignGroup.addChild(
6172             es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
6173                 'cube_rgb8_39_1', '', gl.RGB8, 64, 11, 8, 39, 43, 1
6174             )
6175         );
6176         alignGroup.addChild(
6177             es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
6178                 'cube_rgb8_39_2', '', gl.RGB8, 64, 11, 8, 39, 43, 2
6179             )
6180         );
6181         alignGroup.addChild(
6182             es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
6183                 'cube_rgb8_39_4', '', gl.RGB8, 64, 11, 8, 39, 43, 4
6184             )
6185         );
6186         alignGroup.addChild(
6187             es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
6188                 'cube_rgb8_39_8', '', gl.RGB8, 64, 11, 8, 39, 43, 8
6189             )
6190         );
6191         alignGroup.addChild(
6192             es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
6193                 'cube_rgba8_47_1', '', gl.RGBA8, 64, 10, 1, 47, 27, 1
6194             )
6195         );
6196         alignGroup.addChild(
6197             es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
6198                 'cube_rgba8_47_2', '', gl.RGBA8, 64, 10, 1, 47, 27, 2
6199             )
6200         );
6201         alignGroup.addChild(
6202             es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
6203                 'cube_rgba8_47_4', '', gl.RGBA8, 64, 10, 1, 47, 27, 4
6204             )
6205         );
6206         alignGroup.addChild(
6207             es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
6208                 'cube_rgba8_47_8', '', gl.RGBA8, 64, 10, 1, 47, 27, 8
6209             )
6210         );
6212         // glTexSubImage2D() pixel transfer mode cases.
6213         paramGroup = new tcuTestCase.DeqpTest(
6214             'texsubimage2d_unpack_params',
6215             'glTexSubImage2D() pixel transfer mode cases'
6216         );
6217         this.addChild(paramGroup);
6219         cases = [{
6220                 name: 'rgb8_alignment', format: gl.RGB8, width: 54,
6221                 height: 60, subX: 11, subY: 7, subW: 31, subH: 30,
6222                 rowLength: 0, skipRows: 0, skipPixels: 0, alignment: 2
6223             }, {
6224                 name: 'rgb8_row_length', format: gl.RGB8, width: 54,
6225                 height: 60, subX: 11, subY: 7, subW: 31, subH: 30,
6226                 rowLength: 50, skipRows: 0, skipPixels: 0, alignment: 4
6227             }, {
6228                 name: 'rgb8_skip_rows', format: gl.RGB8, width: 54,
6229                 height: 60, subX: 11, subY: 7, subW: 31, subH: 30,
6230                 rowLength: 0, skipRows: 3, skipPixels: 0, alignment: 4
6231             }, {
6232                 name: 'rgb8_skip_pixels', format: gl.RGB8, width: 54,
6233                 height: 60, subX: 11, subY: 7, subW: 31, subH: 30,
6234                 rowLength: 36, skipRows: 0, skipPixels: 5, alignment: 4
6235             }, {
6236                 name: 'r8_complex1', format: gl.R8, width: 54,
6237                 height: 60, subX: 11, subY: 7, subW: 31, subH: 30,
6238                 rowLength: 64, skipRows: 1, skipPixels: 3, alignment: 1
6239             }, {
6240                 name: 'r8_complex2', format: gl.R8, width: 54,
6241                 height: 60, subX: 11, subY: 7, subW: 31, subH: 30,
6242                 rowLength: 64, skipRows: 1, skipPixels: 3, alignment: 2
6243             }, {
6244                 name: 'r8_complex3', format: gl.R8, width: 54,
6245                 height: 60, subX: 11, subY: 7, subW: 31, subH: 30,
6246                 rowLength: 64, skipRows: 1, skipPixels: 3, alignment: 4
6247             }, {
6248                 name: 'r8_complex4', format: gl.R8, width: 54,
6249                 height: 60, subX: 11, subY: 7, subW: 31, subH: 30,
6250                 rowLength: 64, skipRows: 1, skipPixels: 3, alignment: 8
6251             }, {
6252                 name: 'rgba8_complex1', format: gl.RGBA8, width: 92,
6253                 height: 84, subX: 13, subY: 19, subW: 56, subH: 61,
6254                 rowLength: 69, skipRows: 0, skipPixels: 0, alignment: 8
6255             }, {
6256                 name: 'rgba8_complex2', format: gl.RGBA8, width: 92,
6257                 height: 84, subX: 13, subY: 19, subW: 56, subH: 61,
6258                 rowLength: 69, skipRows: 0, skipPixels: 7, alignment: 8
6259             }, {
6260                 name: 'rgba8_complex3', format: gl.RGBA8, width: 92,
6261                 height: 84, subX: 13, subY: 19, subW: 56, subH: 61,
6262                 rowLength: 69, skipRows: 3, skipPixels: 0, alignment: 8
6263             }, {
6264                 name: 'rgba8_complex4', format: gl.RGBA8, width: 92,
6265                 height: 84, subX: 13, subY: 19, subW: 56, subH: 61,
6266                 rowLength: 69, skipRows: 3, skipPixels: 7, alignment: 8
6267             }, {
6268                 name: 'rgba32f_complex', format: gl.RGBA32F, width: 92,
6269                 height: 84, subX: 13, subY: 19, subW: 56, subH: 61,
6270                 rowLength: 69, skipRows: 3, skipPixels: 7, alignment: 8
6271             }
6272         ];
6274         for (var ndx = 0; ndx < cases.length; ndx++)
6275             paramGroup.addChild(
6276                 new es3fTextureSpecificationTests.TexSubImage2DParamsCase(
6277                     cases[ndx].name, '', cases[ndx].format, cases[ndx].width,
6278                     cases[ndx].height, cases[ndx].subX, cases[ndx].subY,
6279                     cases[ndx].subW, cases[ndx].subH, cases[ndx].rowLength,
6280                     cases[ndx].skipRows, cases[ndx].skipPixels,
6281                     cases[ndx].alignment
6282                 )
6283             );
6285         // glTexSubImage2D() PBO cases.
6286         splitPboTex2D = 2;
6287         splitPboTexCube = 5;
6288         pboGroup2D = [];
6289         for (var ii = 0; ii < splitPboTex2D; ++ii) {
6290             pboGroup2D.push(new tcuTestCase.DeqpTest(
6291                 'texsubimage2d_pbo',
6292                 'glTexSubImage2D() pixel buffer object tests'
6293             ));
6294             this.addChild(pboGroup2D[ii]);
6295         }
6296         pboGroupCube = [];
6297         for (var ii = 0; ii < splitPboTexCube; ++ii) {
6298             pboGroupCube.push(new tcuTestCase.DeqpTest(
6299                 'texsubimage2d_pbo',
6300                 'glTexSubImage2D() pixel buffer object tests'
6301             ));
6302             this.addChild(pboGroupCube[ii]);
6303         }
6305         for (var ndx = 0; ndx < colorFormats.length; ndx++) {
6306             pboGroup2D[ndx % splitPboTex2D].addChild(
6307                 new es3fTextureSpecificationTests.TexSubImage2DBufferCase(
6308                     colorFormats[ndx].name + '_2d', '',
6309                     colorFormats[ndx].internalFormat,
6310                     54, // Width
6311                     60, // Height
6312                     11, // Sub X
6313                     7, // Sub Y
6314                     31, // Sub W
6315                     30, // Sub H
6316                     0, // Row len
6317                     0, // Skip rows
6318                     0, // Skip pixels
6319                     4, // Alignment
6320                     0 /* offset */
6321                 )
6322             );
6323             pboGroupCube[ndx % splitPboTexCube].addChild(
6324                 new es3fTextureSpecificationTests.TexSubImageCubeBufferCase(
6325                     colorFormats[ndx].name + '_cube', '',
6326                     colorFormats[ndx].internalFormat,
6327                     64, // Size
6328                     11, // Sub X
6329                     7, // Sub Y
6330                     31, // Sub W
6331                     30, // Sub H
6332                     0, // Row len
6333                     0, // Skip rows
6334                     0, // Skip pixels
6335                     4, // Alignment
6336                     0 /* offset */
6337                 )
6338             );
6339         }
6341         pboGroupParams = new tcuTestCase.DeqpTest(
6342             'texsubimage2d_pbo',
6343             'glTexSubImage2D() pixel buffer object tests'
6344         );
6345         this.addChild(pboGroupParams);
6346         /** @type {Array<{name: string, format: number, width: number,
6347          * height: number, subX: number, subY: number,
6348          * subW: number, subH: number, rowLength: number, skipRows: number,
6349          * skipPixels: number, alignment: number, offset: number}>}
6350          */
6351         var paramCases = [{
6352                 name: 'rgb8_offset', format: gl.RGB8, width: 54,
6353                 height: 60, subX: 11, subY: 7, subW: 31, subH: 30,
6354                 rowLength: 0, skipRows: 0, skipPixels: 0,
6355                 alignment: 4, offset: 67
6356             }, {
6357                 name: 'rgb8_alignment', format: gl.RGB8, width: 54,
6358                 height: 60, subX: 11, subY: 7, subW: 31, subH: 30,
6359                 rowLength: 0, skipRows: 0, skipPixels: 0,
6360                 alignment: 2, offset: 0
6361             }, {
6362                 name: 'rgb8_row_length', format: gl.RGB8, width: 54,
6363                 height: 60, subX: 11, subY: 7, subW: 31, subH: 30,
6364                 rowLength: 50, skipRows: 0, skipPixels: 0,
6365                 alignment: 4, offset: 0
6366             }, {
6367                 name: 'rgb8_skip_rows', format: gl.RGB8, width: 54,
6368                 height: 60, subX: 11, subY: 7, subW: 31, subH: 30,
6369                 rowLength: 0, skipRows: 3, skipPixels: 0,
6370                 alignment: 4, offset: 0
6371             }, {
6372                 name: 'rgb8_skip_pixels', format: gl.RGB8, width: 54,
6373                 height: 60, subX: 11, subY: 7, subW: 31, subH: 30,
6374                 rowLength: 36, skipRows: 0, skipPixels: 5,
6375                 alignment: 4, offset: 0
6376             }
6377         ];
6379         for (var ndx = 0; ndx < paramCases.length; ndx++) {
6380             pboGroupParams.addChild(
6381                 new es3fTextureSpecificationTests.TexSubImage2DBufferCase(
6382                     paramCases[ndx].name + '_2d', '',
6383                     paramCases[ndx].format,
6384                     paramCases[ndx].width,
6385                     paramCases[ndx].height,
6386                     paramCases[ndx].subX,
6387                     paramCases[ndx].subY,
6388                     paramCases[ndx].subW,
6389                     paramCases[ndx].subH,
6390                     paramCases[ndx].rowLength,
6391                     paramCases[ndx].skipRows,
6392                     paramCases[ndx].skipPixels,
6393                     paramCases[ndx].alignment,
6394                     paramCases[ndx].offset));
6395             pboGroupParams.addChild(
6396                 new es3fTextureSpecificationTests.TexSubImageCubeBufferCase(
6397                     paramCases[ndx].name + '_cube', '',
6398                     paramCases[ndx].format,
6399                     paramCases[ndx].width,
6400                     paramCases[ndx].subX,
6401                     paramCases[ndx].subY,
6402                     paramCases[ndx].subW,
6403                     paramCases[ndx].subH,
6404                     paramCases[ndx].rowLength,
6405                     paramCases[ndx].skipRows,
6406                     paramCases[ndx].skipPixels,
6407                     paramCases[ndx].alignment,
6408                     paramCases[ndx].offset
6409                 )
6410             );
6411         }
6413         // glTexSubImage2D() depth cases.
6414         shadow2dGroup = new tcuTestCase.DeqpTest(
6415             'texsubimage2d_depth',
6416             'glTexSubImage2D() with depth or depth/stencil format'
6417         );
6418         this.addChild(shadow2dGroup);
6420         for (var ndx = 0; ndx < depthStencilFormats.length; ndx++) {
6421             // WebGL 2 specific constraint.
6422             if (depthStencilFormats[ndx].internalFormat == gl.DEPTH32F_STENCIL8)
6423                 continue;
6424             tex2DWidth = 64;
6425             tex2DHeight = 32;
6427             shadow2dGroup.addChild(
6428                 new es3fTextureSpecificationTests.TexSubImage2DDepthCase(
6429                     depthStencilFormats[ndx].name, '',
6430                     depthStencilFormats[ndx].internalFormat,
6431                     tex2DWidth, tex2DHeight
6432                 )
6433             );
6434         }
6436         // Basic glCopyTexImage2D() cases
6437         /** @type {tcuTestCase.DeqpTest} */
6438         var copyTexImageGroup = new tcuTestCase.DeqpTest(
6439             'basic_copyteximage2d', 'Basic glCopyTexImage2D() usage'
6440         );
6441         this.addChild(copyTexImageGroup);
6443         copyTexImageGroup.addChild(
6444             new es3fTextureSpecificationTests.BasicCopyTexImage2DCase(
6445                 '2d_alpha', '', gl.ALPHA, 128, 64
6446             )
6447         );
6448         copyTexImageGroup.addChild(
6449             new es3fTextureSpecificationTests.BasicCopyTexImage2DCase(
6450                 '2d_luminance', '', gl.LUMINANCE, 128, 64
6451             )
6452         );
6453         copyTexImageGroup.addChild(
6454             new es3fTextureSpecificationTests.BasicCopyTexImage2DCase(
6455                 '2d_luminance_alpha', '', gl.LUMINANCE_ALPHA, 128, 64
6456             )
6457         );
6458         copyTexImageGroup.addChild(
6459             new es3fTextureSpecificationTests.BasicCopyTexImage2DCase(
6460                 '2d_rgb', '', gl.RGB, 128, 64
6461             )
6462         );
6463         copyTexImageGroup.addChild(
6464             new es3fTextureSpecificationTests.BasicCopyTexImage2DCase(
6465                 '2d_rgba', '', gl.RGBA, 128, 64
6466             )
6467         );
6469         copyTexImageGroup.addChild(
6470             new es3fTextureSpecificationTests.BasicCopyTexImageCubeCase(
6471                 'cube_alpha', '', gl.ALPHA, 64
6472             )
6473         );
6474         copyTexImageGroup.addChild(
6475             new es3fTextureSpecificationTests.BasicCopyTexImageCubeCase(
6476                 'cube_luminance', '', gl.LUMINANCE, 64
6477             )
6478         );
6479         copyTexImageGroup.addChild(
6480             new es3fTextureSpecificationTests.BasicCopyTexImageCubeCase(
6481                 'cube_luminance_alpha', '', gl.LUMINANCE_ALPHA, 64
6482             )
6483         );
6484         copyTexImageGroup.addChild(
6485             new es3fTextureSpecificationTests.BasicCopyTexImageCubeCase(
6486                 'cube_rgb', '', gl.RGB, 64
6487             )
6488         );
6489         copyTexImageGroup.addChild(
6490             new es3fTextureSpecificationTests.BasicCopyTexImageCubeCase(
6491                 'cube_rgba', '', gl.RGBA, 64
6492             )
6493         );
6495         // Basic glCopyTexSubImage2D() cases
6496         /** @type {tcuTestCase.DeqpTest} */
6497         var copyTexSubImageGroup = new tcuTestCase.DeqpTest(
6498             'basic_copytexsubimage2d', 'Basic glCopyTexSubImage2D() usage'
6499         );
6500         this.addChild(copyTexSubImageGroup);
6502         copyTexSubImageGroup.addChild(
6503             new es3fTextureSpecificationTests.BasicCopyTexSubImage2DCase(
6504                 '2d_alpha', '', gl.ALPHA, gl.UNSIGNED_BYTE, 128, 64
6505             )
6506         );
6507         copyTexSubImageGroup.addChild(
6508             new es3fTextureSpecificationTests.BasicCopyTexSubImage2DCase(
6509                 '2d_luminance', '', gl.LUMINANCE, gl.UNSIGNED_BYTE, 128, 64
6510             )
6511         );
6512         copyTexSubImageGroup.addChild(
6513             new es3fTextureSpecificationTests.BasicCopyTexSubImage2DCase(
6514                 '2d_luminance_alpha', '', gl.LUMINANCE_ALPHA, gl.UNSIGNED_BYTE, 128, 64
6515             )
6516         );
6517         copyTexSubImageGroup.addChild(
6518             new es3fTextureSpecificationTests.BasicCopyTexSubImage2DCase(
6519                 '2d_rgb', '', gl.RGB, gl.UNSIGNED_BYTE, 128, 64
6520             )
6521         );
6522         copyTexSubImageGroup.addChild(
6523             new es3fTextureSpecificationTests.BasicCopyTexSubImage2DCase(
6524                 '2d_rgba', '', gl.RGBA, gl.UNSIGNED_BYTE, 128, 64
6525             )
6526         );
6528         copyTexSubImageGroup.addChild(
6529             new es3fTextureSpecificationTests.BasicCopyTexSubImageCubeCase(
6530                 'cube_alpha', '', gl.ALPHA, gl.UNSIGNED_BYTE, 64
6531             )
6532         );
6533         copyTexSubImageGroup.addChild(
6534             new es3fTextureSpecificationTests.BasicCopyTexSubImageCubeCase(
6535                 'cube_luminance', '', gl.LUMINANCE, gl.UNSIGNED_BYTE, 64
6536             )
6537         );
6538         copyTexSubImageGroup.addChild(
6539             new es3fTextureSpecificationTests.BasicCopyTexSubImageCubeCase(
6540                 'cube_luminance_alpha', '', gl.LUMINANCE_ALPHA, gl.UNSIGNED_BYTE, 64
6541             )
6542         );
6543         copyTexSubImageGroup.addChild(
6544             new es3fTextureSpecificationTests.BasicCopyTexSubImageCubeCase(
6545                 'cube_rgb', '', gl.RGB, gl.UNSIGNED_BYTE, 64
6546             )
6547         );
6548         copyTexSubImageGroup.addChild(
6549             new es3fTextureSpecificationTests.BasicCopyTexSubImageCubeCase(
6550                 'cube_rgba', '', gl.RGBA, gl.UNSIGNED_BYTE, 64
6551             )
6552         );
6554         // Basic TexImage3D usage.
6555         var splitBasicTex2DArray = 3, splitBasicTex3D = 5;
6556         /** @type {Array<{tcuTestCase.DeqpTest}>} */
6557         var basicTexImageGroup2DArray = [];
6558         for (var ii = 0; ii < splitBasicTex2DArray; ++ii) {
6559             basicTexImageGroup2DArray.push(
6560                 new tcuTestCase.DeqpTest('basic_teximage3d', 'Basic glTexImage3D() usage')
6561             );
6562             this.addChild(basicTexImageGroup2DArray[ii]);
6563         }
6564         /** @type {Array<{tcuTestCase.DeqpTest}>} */
6565         var basicTexImageGroup3D = [];
6566         for (var ii = 0; ii < splitBasicTex3D; ++ii) {
6567             basicTexImageGroup3D.push(
6568                 new tcuTestCase.DeqpTest('basic_teximage3d', 'Basic glTexImage3D() usage')
6569             );
6570             this.addChild(basicTexImageGroup3D[ii]);
6571         }
6572         for (var formatNdx = 0; formatNdx < colorFormats.length; formatNdx++) {
6573             fmtName = colorFormats[formatNdx].name;
6574             format = colorFormats[formatNdx].internalFormat;
6575             /** @type {number} */ var tex2DArrayWidth = 57;
6576             /** @type {number} */ var tex2DArrayHeight = 44;
6577             /** @type {number} */ var tex2DArrayLevels = 5;
6578             /** @type {number} */ var tex3DWidth = 63;
6579             /** @type {number} */ var tex3DHeight = 29;
6580             /** @type {number} */ var tex3DDepth = 11;
6582             basicTexImageGroup2DArray[formatNdx % splitBasicTex2DArray].addChild(
6583                 new es3fTextureSpecificationTests.BasicTexImage2DArrayCase(
6584                     fmtName + '_2d_array', '', format,
6585                     tex2DArrayWidth, tex2DArrayHeight, tex2DArrayLevels
6586                 )
6587             );
6588             basicTexImageGroup3D[formatNdx % splitBasicTex3D].addChild(
6589                 new es3fTextureSpecificationTests.BasicTexImage3DCase(
6590                     fmtName + '_3d', '', format,
6591                     tex3DWidth, tex3DHeight, tex3DDepth
6592                 )
6593             );
6594         }
6596         // glTexImage3D() unpack params cases.
6597         paramGroup = new tcuTestCase.DeqpTest(
6598             'teximage3d_unpack_params', 'glTexImage3D() unpack parameters'
6599         );
6600         this.addChild(paramGroup);
6602         cases = [{
6603                 name: 'rgb8_image_height', format: gl.RGB8, width: 23,
6604                 height: 19, depth: 8, imageHeight: 26, rowLength: 0,
6605                 skipImages: 0, skipRows: 0, skipPixels: 0, alignment: 4
6606             }, {
6607                 name: 'rgb8_row_length', format: gl.RGB8, width: 23,
6608                 height: 19, depth: 8, imageHeight: 0, rowLength: 27,
6609                 skipImages: 0, skipRows: 0, skipPixels: 0, alignment: 4
6610             }, {
6611                 name: 'rgb8_skip_images', format: gl.RGB8, width: 23,
6612                 height: 19, depth: 8, imageHeight: 0, rowLength: 0,
6613                 skipImages: 3, skipRows: 0, skipPixels: 0, alignment: 4
6614             }, {
6615                 name: 'rgb8_skip_rows', format: gl.RGB8, width: 23,
6616                 height: 19, depth: 8, imageHeight: 22, rowLength: 0,
6617                 skipImages: 0, skipRows: 3, skipPixels: 0, alignment: 4
6618             }, {
6619                 name: 'rgb8_skip_pixels', format: gl.RGB8, width: 23,
6620                 height: 19, depth: 8, imageHeight: 0, rowLength: 25,
6621                 skipImages: 0, skipRows: 0, skipPixels: 2, alignment: 4
6622             }, {
6623                 name: 'r8_complex1', format: gl.R8, width: 13,
6624                 height: 17, depth: 11, imageHeight: 23, rowLength: 15,
6625                 skipImages: 2, skipRows: 3, skipPixels: 1, alignment: 1
6626             }, {
6627                 name: 'r8_complex2', format: gl.R8, width: 13,
6628                 height: 17, depth: 11, imageHeight: 23, rowLength: 15,
6629                 skipImages: 2, skipRows: 3, skipPixels: 1, alignment: 2
6630             }, {
6631                 name: 'r8_complex3', format: gl.R8, width: 13,
6632                 height: 17, depth: 11, imageHeight: 23, rowLength: 15,
6633                 skipImages: 2, skipRows: 3, skipPixels: 1, alignment: 4
6634             }, {
6635                 name: 'r8_complex4', format: gl.R8, width: 13,
6636                 height: 17, depth: 11, imageHeight: 23, rowLength: 15,
6637                 skipImages: 2, skipRows: 3, skipPixels: 1, alignment: 8
6638             }, {
6639                 name: 'rgba8_complex1', format: gl.RGBA8, width: 11,
6640                 height: 20, depth: 8, imageHeight: 25, rowLength: 14,
6641                 skipImages: 0, skipRows: 0, skipPixels: 0, alignment: 8
6642             }, {
6643                 name: 'rgba8_complex2', format: gl.RGBA8, width: 11,
6644                 height: 20, depth: 8, imageHeight: 25, rowLength: 14,
6645                 skipImages: 0, skipRows: 2, skipPixels: 0, alignment: 8
6646             }, {
6647                 name: 'rgba8_complex3', format: gl.RGBA8, width: 11,
6648                 height: 20, depth: 8, imageHeight: 25, rowLength: 14,
6649                 skipImages: 0, skipRows: 0, skipPixels: 3, alignment: 8
6650             }, {
6651                 name: 'rgba8_complex4', format: gl.RGBA8, width: 11,
6652                 height: 20, depth: 8, imageHeight: 25, rowLength: 14,
6653                 skipImages: 0, skipRows: 2, skipPixels: 3, alignment: 8
6654             }, {
6655                 name: 'rgba32f_complex', format: gl.RGBA32F, width: 11,
6656                 height: 20, depth: 8, imageHeight: 25, rowLength: 14,
6657                 skipImages: 0, skipRows: 2, skipPixels: 3, alignment: 8
6658              }
6659         ];
6661         for (var ndx = 0; ndx < cases.length; ndx++)
6662             paramGroup.addChild(
6663                 new es3fTextureSpecificationTests.TexImage3DParamsCase(
6664                     cases[ndx].name, '', cases[ndx].format, cases[ndx].width,
6665                     cases[ndx].height, cases[ndx].depth, cases[ndx].imageHeight,
6666                     cases[ndx].rowLength, cases[ndx].skipImages,
6667                     cases[ndx].skipRows, cases[ndx].skipPixels,
6668                     cases[ndx].alignment
6669                 )
6670             );
6672         // glTexImage3D() pbo cases.
6673         var splitTex2DArray = 2, splitTex3D = 2;
6674         /** @type {Array<{tcuTestCase.DeqpTest}>} */ var pboGroup2DArray = [];
6675         for (var ii = 0; ii < splitTex2DArray; ++ii) {
6676             pboGroup2DArray.push(
6677                 new tcuTestCase.DeqpTest('teximage3d_pbo', 'glTexImage3D() from PBO')
6678             );
6679             this.addChild(pboGroup2DArray[ii]);
6680         }
6681         /** @type {Array<{tcuTestCase.DeqpTest}>} */ var pboGroup3D = [];
6682         for (var ii = 0; ii < splitTex3D; ++ii) {
6683             pboGroup3D.push(
6684                 new tcuTestCase.DeqpTest('teximage3d_pbo', 'glTexImage3D() from PBO')
6685             );
6686             this.addChild(pboGroup3D[ii]);
6687         }
6689         for (var formatNdx = 0; formatNdx < colorFormats.length; formatNdx++) {
6690             fmtName = colorFormats[formatNdx].name;
6691             format = colorFormats[formatNdx].internalFormat;
6692             tex3DWidth = 11;
6693             tex3DHeight = 20;
6694             tex3DDepth = 8;
6696             pboGroup2DArray[formatNdx % splitTex2DArray].addChild(
6697                 new es3fTextureSpecificationTests.TexImage2DArrayBufferCase(
6698                     fmtName + '_2d_array', '', format, tex3DWidth, tex3DHeight,
6699                     tex3DDepth, 0, 0, 0, 0, 0, 4, 0
6700                 )
6701             );
6702             pboGroup3D[formatNdx % splitTex3D].addChild(
6703                 new es3fTextureSpecificationTests.TexImage3DBufferCase(
6704                     fmtName + '_3d', '', format, tex3DWidth, tex3DHeight,
6705                     tex3DDepth, 0, 0, 0, 0, 0, 4, 0
6706                 )
6707             );
6708         }
6710         // Parameter cases
6711         parameterCases = [{
6712                 name: 'rgb8_offset', format: gl.RGB8, width: 23,
6713                 height: 19, depth: 8, imageHeight: 0, rowLength: 0,
6714                 skipImages: 0, skipRows: 0, skipPixels: 0, alignment: 1,
6715                 offset: 67
6716             }, {
6717                 name: 'rgb8_alignment', format: gl.RGB8, width: 23,
6718                 height: 19, depth: 8, imageHeight: 0, rowLength: 0,
6719                 skipImages: 0, skipRows: 0, skipPixels: 0, alignment: 2,
6720                 offset: 0
6721             }, {
6722                 name: 'rgb8_image_height', format: gl.RGB8, width: 23,
6723                 height: 19, depth: 8, imageHeight: 26, rowLength: 0,
6724                 skipImages: 0, skipRows: 0, skipPixels: 0, alignment: 4,
6725                 offset: 0
6726             }, {
6727                 name: 'rgb8_row_length', format: gl.RGB8, width: 23,
6728                 height: 19, depth: 8, imageHeight: 0, rowLength: 27,
6729                 skipImages: 0, skipRows: 0, skipPixels: 0, alignment: 4,
6730                 offset: 0
6731             }, {
6732                 name: 'rgb8_skip_images', format: gl.RGB8, width: 23,
6733                 height: 19, depth: 8, imageHeight: 0, rowLength: 0,
6734                 skipImages: 3, skipRows: 0, skipPixels: 0, alignment: 4,
6735                 offset: 0
6736             }, {
6737                 name: 'rgb8_skip_rows', format: gl.RGB8, width: 23,
6738                 height: 19, depth: 8, imageHeight: 22, rowLength: 0,
6739                 skipImages: 0, skipRows: 3, skipPixels: 0, alignment: 4,
6740                 offset: 0
6741             }, {
6742                 name: 'rgb8_skip_pixels', format: gl.RGB8, width: 23,
6743                 height: 19, depth: 8, imageHeight: 0, rowLength: 25,
6744                 skipImages: 0, skipRows: 0, skipPixels: 2, alignment: 4,
6745                 offset: 0
6746             }
6747         ];
6749         pboGroupParams = new tcuTestCase.DeqpTest('teximage3d_pbo', 'glTexImage3D() from PBO');
6750         this.addChild(pboGroupParams);
6751         for (var ndx = 0; ndx < parameterCases.length; ndx++) {
6752             pboGroupParams.addChild(
6753                 new es3fTextureSpecificationTests.TexImage2DArrayBufferCase(
6754                     parameterCases[ndx].name + '_2d_array', '',
6755                     parameterCases[ndx].format, parameterCases[ndx].width,
6756                     parameterCases[ndx].height, parameterCases[ndx].depth,
6757                     parameterCases[ndx].imageHeight,
6758                     parameterCases[ndx].rowLength,
6759                     parameterCases[ndx].skipImages,
6760                     parameterCases[ndx].skipRows,
6761                     parameterCases[ndx].skipPixels,
6762                     parameterCases[ndx].alignment, parameterCases[ndx].offset
6763                 )
6764             );
6765             pboGroupParams.addChild(
6766                 new es3fTextureSpecificationTests.TexImage3DBufferCase(
6767                     parameterCases[ndx].name + '_3d', '',
6768                     parameterCases[ndx].format, parameterCases[ndx].width,
6769                     parameterCases[ndx].height, parameterCases[ndx].depth,
6770                     parameterCases[ndx].imageHeight,
6771                     parameterCases[ndx].rowLength,
6772                     parameterCases[ndx].skipImages,
6773                     parameterCases[ndx].skipRows,
6774                     parameterCases[ndx].skipPixels,
6775                     parameterCases[ndx].alignment, parameterCases[ndx].offset
6776                 )
6777             );
6778         }
6780         // glTexImage3D() depth cases.
6781         /** @type {tcuTestCase.DeqpTest} */
6782         var shadow3dGroup = new tcuTestCase.DeqpTest(
6783             'teximage3d_depth',
6784             'glTexImage3D() with depth or depth/stencil format'
6785         );
6786         this.addChild(shadow3dGroup);
6788         for (var ndx = 0; ndx < depthStencilFormats.length; ndx++) {
6789             // WebGL 2 specific constraint.
6790             if (depthStencilFormats[ndx].internalFormat == gl.DEPTH32F_STENCIL8)
6791                 continue;
6792             tex3DWidth = 32;
6793             tex3DHeight = 64;
6794             tex3DDepth = 8;
6796             shadow3dGroup.addChild(
6797                 new es3fTextureSpecificationTests.TexImage2DArrayDepthCase(
6798                     depthStencilFormats[ndx].name + '_2d_array', '',
6799                     depthStencilFormats[ndx].internalFormat,
6800                     tex3DWidth, tex3DHeight, tex3DDepth
6801                 )
6802             );
6803         }
6805         // glTexImage3D() depth cases with pbo.
6806         shadow3dGroup = new tcuTestCase.DeqpTest(
6807             'teximage3d_depth_pbo',
6808             'glTexImage3D() with depth or depth/stencil format with pbo'
6809         );
6810         this.addChild(shadow3dGroup);
6812         for (var ndx = 0; ndx < depthStencilFormats.length; ndx++) {
6813             tex3DWidth = 32;
6814             tex3DHeight = 64;
6815             tex3DDepth = 8;
6817             shadow3dGroup.addChild(
6818                 new es3fTextureSpecificationTests.TexImage2DArrayDepthBufferCase(
6819                     depthStencilFormats[ndx].name + '_2d_array', '',
6820                     depthStencilFormats[ndx].internalFormat,
6821                     tex3DWidth, tex3DHeight, tex3DDepth
6822                 )
6823             );
6824         }
6826         // Basic TexSubImage3D usage.
6827         splitTex3D = 5;
6828         /** @type {Array<{tcuTestCase.DeqpTest}>} */ var basicTexSubImageGroup = [];
6829         for (var ii = 0; ii < splitTex3D; ++ii) {
6830             basicTexSubImageGroup.push(
6831                 new tcuTestCase.DeqpTest('basic_texsubimage3d', 'Basic glTexSubImage3D() usage')
6832             );
6833             this.addChild(basicTexSubImageGroup[ii]);
6834         }
6836         for (var formatNdx = 0; formatNdx < colorFormats.length; formatNdx++) {
6837             fmtName = colorFormats[formatNdx].name;
6838             format = colorFormats[formatNdx].internalFormat;
6839             tex3DWidth = 32;
6840             tex3DHeight = 64;
6841             tex3DDepth = 8;
6843             basicTexSubImageGroup[formatNdx % splitTex3D].addChild(
6844                 new es3fTextureSpecificationTests.BasicTexSubImage3DCase(
6845                     fmtName + '_3d', '', format,
6846                     tex3DWidth, tex3DHeight, tex3DDepth
6847                 )
6848             );
6849         }
6851         // glTexSubImage3D() unpack params cases.
6852         paramGroup = new tcuTestCase.DeqpTest(
6853             'texsubimage3d_unpack_params', 'glTexSubImage3D() unpack parameters'
6854         );
6855         this.addChild(paramGroup);
6857         /** @type {Array<{name: string, format: number, width: number,
6858          * height: number, depth: number, subX: number, subY: number,
6859          * subZ: number, subW: number, subH: number, subD: number,
6860          * imageHeight: number, rowLength: number, skipImages: number,
6861          * skipRows: number, skipPixels: number, alignment: number}>}
6862          */
6863         var casesSubImage3D = [{
6864                 name: 'rgb8_image_height', format: gl.RGB8, width: 26,
6865                 height: 25, depth: 10, subX: 1, subY: 2, subZ: 1, subW: 23,
6866                 subH: 19, subD: 8, imageHeight: 26, rowLength: 0,
6867                 skipImages: 0, skipRows: 0, skipPixels: 0, alignment: 4
6868             }, {
6869                 name: 'rgb8_row_length', format: gl.RGB8, width: 26,
6870                 height: 25, depth: 10, subX: 1, subY: 2, subZ: 1, subW: 23,
6871                 subH: 19, subD: 8, imageHeight: 0, rowLength: 27,
6872                 skipImages: 0, skipRows: 0, skipPixels: 0, alignment: 4
6873             }, {
6874                 name: 'rgb8_skip_images', format: gl.RGB8, width: 26,
6875                 height: 25, depth: 10, subX: 1, subY: 2, subZ: 1, subW: 23,
6876                 subH: 19, subD: 8, imageHeight: 0, rowLength: 0,
6877                 skipImages: 3, skipRows: 0, skipPixels: 0, alignment: 4
6878             }, {
6879                 name: 'rgb8_skip_rows', format: gl.RGB8, width: 26,
6880                 height: 25, depth: 10, subX: 1, subY: 2, subZ: 1, subW: 23,
6881                 subH: 19, subD: 8, imageHeight: 22, rowLength: 0,
6882                 skipImages: 0, skipRows: 3, skipPixels: 0, alignment: 4
6883             }, {
6884                 name: 'rgb8_skip_pixels', format: gl.RGB8, width: 26,
6885                 height: 25, depth: 10, subX: 1, subY: 2, subZ: 1, subW: 23,
6886                 subH: 19, subD: 8, imageHeight: 0, rowLength: 25,
6887                 skipImages: 0, skipRows: 0, skipPixels: 2, alignment: 4
6888             }, {
6889                 name: 'r8_complex1', format: gl.R8, width: 15,
6890                 height: 20, depth: 11, subX: 1, subY: 1, subZ: 0, subW: 13,
6891                 subH: 17, subD: 11, imageHeight: 23, rowLength: 15,
6892                 skipImages: 2, skipRows: 3, skipPixels: 1, alignment: 1
6893             }, {
6894                 name: 'r8_complex2', format: gl.R8, width: 15,
6895                 height: 20, depth: 11, subX: 1, subY: 1, subZ: 0, subW: 13,
6896                 subH: 17, subD: 11, imageHeight: 23, rowLength: 15,
6897                 skipImages: 2, skipRows: 3, skipPixels: 1, alignment: 2
6898             }, {
6899                 name: 'r8_complex3', format: gl.R8, width: 15,
6900                 height: 20, depth: 11, subX: 1, subY: 1, subZ: 0, subW: 13,
6901                 subH: 17, subD: 11, imageHeight: 23, rowLength: 15,
6902                 skipImages: 2, skipRows: 3, skipPixels: 1, alignment: 4
6903             }, {
6904                 name: 'r8_complex4', format: gl.R8, width: 15,
6905                 height: 20, depth: 11, subX: 1, subY: 1, subZ: 0, subW: 13,
6906                 subH: 17, subD: 11, imageHeight: 23, rowLength: 15,
6907                 skipImages: 2, skipRows: 3, skipPixels: 1, alignment: 8
6908             }, {
6909                 name: 'rgba8_complex1', format: gl.RGBA8, width: 15,
6910                 height: 25, depth: 10, subX: 0, subY: 5, subZ: 1, subW: 11,
6911                 subH: 20, subD: 8, imageHeight: 25, rowLength: 14,
6912                 skipImages: 0, skipRows: 0, skipPixels: 0, alignment: 8
6913             }, {
6914                 name: 'rgba8_complex2', format: gl.RGBA8, width: 15,
6915                 height: 25, depth: 10, subX: 0, subY: 5, subZ: 1, subW: 11,
6916                 subH: 20, subD: 8, imageHeight: 25, rowLength: 14,
6917                 skipImages: 0, skipRows: 2, skipPixels: 0, alignment: 8
6918             }, {
6919                 name: 'rgba8_complex3', format: gl.RGBA8, width: 15,
6920                 height: 25, depth: 10, subX: 0, subY: 5, subZ: 1, subW: 11,
6921                 subH: 20, subD: 8, imageHeight: 25, rowLength: 14,
6922                 skipImages: 0, skipRows: 0, skipPixels: 3, alignment: 8
6923             }, {
6924                 name: 'rgba8_complex4', format: gl.RGBA8, width: 15,
6925                 height: 25, depth: 10, subX: 0, subY: 5, subZ: 1, subW: 11,
6926                 subH: 20, subD: 8, imageHeight: 25, rowLength: 14,
6927                 skipImages: 0, skipRows: 2, skipPixels: 3, alignment: 8
6928             }, {
6929                 name: 'rgba32f_complex', format: gl.RGBA32F, width: 15,
6930                 height: 25, depth: 10, subX: 0, subY: 5, subZ: 1, subW: 11,
6931                 subH: 20, subD: 8, imageHeight: 25, rowLength: 14,
6932                 skipImages: 0, skipRows: 2, skipPixels: 3, alignment: 8
6933             }
6934         ];
6936         for (var ndx = 0; ndx < casesSubImage3D.length; ndx++)
6937             paramGroup.addChild(
6938                 new es3fTextureSpecificationTests.TexSubImage3DParamsCase(
6939                     casesSubImage3D[ndx].name, '', casesSubImage3D[ndx].format,
6940                     casesSubImage3D[ndx].width, casesSubImage3D[ndx].height, casesSubImage3D[ndx].depth,
6941                     casesSubImage3D[ndx].subX, casesSubImage3D[ndx].subY, casesSubImage3D[ndx].subZ,
6942                     casesSubImage3D[ndx].subW, casesSubImage3D[ndx].subH, casesSubImage3D[ndx].subD,
6943                     casesSubImage3D[ndx].imageHeight, casesSubImage3D[ndx].rowLength,
6944                     casesSubImage3D[ndx].skipImages, casesSubImage3D[ndx].skipRows,
6945                     casesSubImage3D[ndx].skipPixels, casesSubImage3D[ndx].alignment
6946                 )
6947             );
6949         // glTexSubImage3D() PBO cases.
6950         splitTex2DArray = 2;
6951         pboGroup2DArray = [];
6952         for (var ii = 0; ii < splitTex2DArray; ++ii) {
6953             pboGroup2DArray.push(
6954                 new tcuTestCase.DeqpTest('texsubimage3d_pbo', 'glTexSubImage3D() pixel buffer object tests')
6955             );
6956             this.addChild(pboGroup2DArray[ii]);
6957         }
6959         splitTex3D = 2;
6960         pboGroup3D = [];
6961         for (var ii = 0; ii < splitTex3D; ++ii) {
6962             pboGroup3D.push(
6963                 new tcuTestCase.DeqpTest('texsubimage3d_pbo', 'glTexSubImage3D() pixel buffer object tests')
6964             );
6965             this.addChild(pboGroup3D[ii]);
6966         }
6968         for (var ndx = 0; ndx < colorFormats.length; ndx++) {
6969             pboGroup2DArray[ndx % splitTex2DArray].addChild(
6970                 new es3fTextureSpecificationTests.TexSubImage2DArrayBufferCase(
6971                     colorFormats[ndx].name + '_2d_array', '',
6972                     colorFormats[ndx].internalFormat,
6973                     26, // Width
6974                     25, // Height
6975                     10, // Depth
6976                     1, // Sub X
6977                     2, // Sub Y
6978                     0, // Sub Z
6979                     23, // Sub W
6980                     19, // Sub H
6981                     8, // Sub D
6982                     0, // Image height
6983                     0, // Row length
6984                     0, // Skip images
6985                     0, // Skip rows
6986                     0, // Skip pixels
6987                     4, // Alignment
6988                     0 // offset
6989                 )
6990             );
6991             pboGroup3D[ndx % splitTex3D].addChild(
6992                 new es3fTextureSpecificationTests.TexSubImage3DBufferCase(
6993                     colorFormats[ndx].name + '_3d', '',
6994                     colorFormats[ndx].internalFormat,
6995                     26, // Width
6996                     25, // Height
6997                     10, // Depth
6998                     1, // Sub X
6999                     2, // Sub Y
7000                     0, // Sub Z
7001                     23, // Sub W
7002                     19, // Sub H
7003                     8, // Sub D
7004                     0, // Image height
7005                     0, // Row length
7006                     0, // Skip images
7007                     0, // Skip rows
7008                     0, // Skip pixels
7009                     4, // Alignment
7010                     0 // offset
7011                 )
7012             );
7013         }
7015         paramCases = [{
7016                 name: 'rgb8_offset', format: gl.RGB8, width: 26,
7017                 height: 25, depth: 10, subX: 1, subY: 2, subZ: 1, subW: 23,
7018                 subH: 19, subD: 8, imageHeight: 0, rowLength: 0, skipImages: 0,
7019                 skipRows: 0, skipPixels: 0, alignment: 4, offset: 67
7020             }, {
7021                 name: 'rgb8_image_height', format: gl.RGB8, width: 26,
7022                 height: 25, depth: 10, subX: 1, subY: 2, subZ: 1, subW: 23,
7023                 subH: 19, subD: 8, imageHeight: 26, rowLength: 0, skipImages: 0,
7024                 skipRows: 0, skipPixels: 0, alignment: 4, offset: 0
7025             }, {
7026                 name: 'rgb8_row_length', format: gl.RGB8, width: 26,
7027                 height: 25, depth: 10, subX: 1, subY: 2, subZ: 1, subW: 23,
7028                 subH: 19, subD: 8, imageHeight: 0, rowLength: 27, skipImages: 0,
7029                 skipRows: 0, skipPixels: 0, alignment: 4, offset: 0
7030             }, {
7031                 name: 'rgb8_skip_images', format: gl.RGB8, width: 26,
7032                 height: 25, depth: 10, subX: 1, subY: 2, subZ: 1, subW: 23,
7033                 subH: 19, subD: 8, imageHeight: 0, rowLength: 0, skipImages: 3,
7034                 skipRows: 0, skipPixels: 0, alignment: 4, offset: 0
7035             }, {
7036                 name: 'rgb8_skip_rows', format: gl.RGB8, width: 26,
7037                 height: 25, depth: 10, subX: 1, subY: 2, subZ: 1, subW: 23,
7038                 subH: 19, subD: 8, imageHeight: 22, rowLength: 0, skipImages: 0,
7039                 skipRows: 3, skipPixels: 0, alignment: 4, offset: 0
7040             }, {
7041                 name: 'rgb8_skip_pixels', format: gl.RGB8, width: 26,
7042                 height: 25, depth: 10, subX: 1, subY: 2, subZ: 1, subW: 23,
7043                 subH: 19, subD: 8, imageHeight: 0, rowLength: 25, skipImages: 0,
7044                 skipRows: 0, skipPixels: 2, alignment: 4, offset: 0
7045             }
7046         ];
7048         pboGroupParams = new tcuTestCase.DeqpTest(
7049             'texsubimage3d_pbo', 'glTexSubImage3D() pixel buffer object tests'
7050         );
7051         this.addChild(pboGroupParams);
7053         for (var ndx = 0; ndx < paramCases.length; ndx++) {
7054             pboGroupParams.addChild(
7055                 new es3fTextureSpecificationTests.TexSubImage2DArrayBufferCase(
7056                     paramCases[ndx].name + '_2d_array', '',
7057                     paramCases[ndx].format, paramCases[ndx].width,
7058                     paramCases[ndx].height, paramCases[ndx].depth,
7059                     paramCases[ndx].subX, paramCases[ndx].subY,
7060                     paramCases[ndx].subZ, paramCases[ndx].subW,
7061                     paramCases[ndx].subH, paramCases[ndx].subD,
7062                     paramCases[ndx].imageHeight, paramCases[ndx].rowLength,
7063                     paramCases[ndx].skipImages, paramCases[ndx].skipRows,
7064                     paramCases[ndx].skipPixels, paramCases[ndx].alignment,
7065                     paramCases[ndx].offset
7066                 )
7067             );
7068             pboGroupParams.addChild(
7069                 new es3fTextureSpecificationTests.TexSubImage3DBufferCase(
7070                     paramCases[ndx].name + '_3d', '',
7071                     paramCases[ndx].format, paramCases[ndx].width,
7072                     paramCases[ndx].height, paramCases[ndx].depth,
7073                     paramCases[ndx].subX, paramCases[ndx].subY,
7074                     paramCases[ndx].subZ, paramCases[ndx].subW,
7075                     paramCases[ndx].subH, paramCases[ndx].subD,
7076                     paramCases[ndx].imageHeight, paramCases[ndx].rowLength,
7077                     paramCases[ndx].skipImages, paramCases[ndx].skipRows,
7078                     paramCases[ndx].skipPixels, paramCases[ndx].alignment,
7079                     paramCases[ndx].offset
7080                 )
7081             );
7082         }
7084         // glTexSubImage3D() depth cases.
7085         shadow3dGroup = new tcuTestCase.DeqpTest(
7086             'texsubimage3d_depth',
7087             'glTexSubImage3D() with depth or depth/stencil format'
7088         );
7089         this.addChild(shadow3dGroup);
7091         for (var ndx = 0; ndx < depthStencilFormats.length; ndx++) {
7092             // WebGL 2 specific constraint.
7093             if (depthStencilFormats[ndx].internalFormat == gl.DEPTH32F_STENCIL8)
7094                 continue;
7095             tex2DArrayWidth = 57;
7096             tex2DArrayHeight = 44;
7097             tex2DArrayLevels = 5;
7099             shadow3dGroup.addChild(
7100                 new es3fTextureSpecificationTests.TexSubImage2DArrayDepthCase(
7101                     depthStencilFormats[ndx].name + '_2d_array', '',
7102                     depthStencilFormats[ndx].internalFormat, tex2DArrayWidth,
7103                     tex2DArrayHeight, tex2DArrayLevels
7104                 )
7105             );
7106         }
7108         // glTexStorage2D() cases.
7110         // Color formats
7111         var splitStorage2D = 3, splitStorageCube = 5;
7112         /** @type {Array<{tcuTestCase.DeqpTest}>} */ var colorFormatGroup2D = [];
7113         for (var ii = 0; ii < splitStorage2D; ++ii) {
7114             colorFormatGroup2D.push(
7115                 new tcuTestCase.DeqpTest('texstorage2d.format', 'glTexStorage2D() with all formats')
7116             );
7117             this.addChild(colorFormatGroup2D[ii]);
7118         }
7119         /** @type {Array<{tcuTestCase.DeqpTest}>} */ var colorFormatGroupCube = [];
7120         for (var ii = 0; ii < splitStorageCube; ++ii) {
7121             colorFormatGroupCube.push(
7122                 new tcuTestCase.DeqpTest('texstorage2d.format', 'glTexStorage2D() with all formats')
7123             );
7124             this.addChild(colorFormatGroupCube[ii]);
7125         }
7127         for (var formatNdx = 0; formatNdx < colorFormats.length; formatNdx++) {
7128             fmtName = colorFormats[formatNdx].name;
7129             /** @type {number} */ var internalFormat = colorFormats[formatNdx].internalFormat;
7130             var tex2DWidth = 117;
7131             var tex2DHeight = 97;
7132             var tex2DLevels = es3fTextureSpecificationTests.maxLevelCount(tex2DWidth, tex2DHeight);
7133             /** @type {number} */ var cubeSize = 57;
7134             /** @type {number} */
7135             var cubeLevels = es3fTextureSpecificationTests.maxLevelCount(
7136                 cubeSize, cubeSize
7137             );
7139             colorFormatGroup2D[formatNdx % splitStorage2D].addChild(
7140                 new es3fTextureSpecificationTests.BasicTexStorage2DCase(
7141                     fmtName + '_2d', '', internalFormat,
7142                     tex2DWidth, tex2DHeight, tex2DLevels
7143                 )
7144             );
7145             colorFormatGroupCube[formatNdx % splitStorageCube].addChild(
7146                 new es3fTextureSpecificationTests.BasicTexStorageCubeCase(
7147                     fmtName + '_cube', '', internalFormat, cubeSize, cubeLevels
7148                 )
7149             );
7150         }
7152         // Depth / stencil formats.
7153         /** @type {tcuTestCase.DeqpTest} */
7154         var storageGroup = new tcuTestCase.DeqpTest(
7155             'texstorage2d.format',
7156             'glTexStorage2D() with all formats'
7157         );
7158         this.addChild(storageGroup);
7160         for (var formatNdx = 0; formatNdx < depthStencilFormats.length; formatNdx++) {
7161             fmtName = depthStencilFormats[formatNdx].name;
7162             internalFormat = depthStencilFormats[formatNdx].internalFormat;
7163             // WebGL 2 specific constraint.
7164             if (internalFormat == gl.DEPTH32F_STENCIL8)
7165                 continue;
7167             tex2DWidth = 117;
7168             tex2DHeight = 97;
7169             tex2DLevels = es3fTextureSpecificationTests.maxLevelCount(
7170                 tex2DWidth, tex2DHeight
7171             );
7172             cubeSize = 57;
7173             cubeLevels = es3fTextureSpecificationTests.maxLevelCount(
7174                 cubeSize, cubeSize
7175             );
7177             storageGroup.addChild(
7178                 new es3fTextureSpecificationTests.BasicTexStorage2DCase(
7179                     fmtName + '_2d', '', internalFormat,
7180                     tex2DWidth, tex2DHeight, tex2DLevels
7181                 )
7182             );
7183             storageGroup.addChild(
7184                 new es3fTextureSpecificationTests.BasicTexStorageCubeCase(
7185                     fmtName + '_cube', '', internalFormat, cubeSize, cubeLevels
7186                 )
7187             );
7188         }
7190         // Sizes.
7191         storageGroup = new tcuTestCase.DeqpTest(
7192             'texstorage2d.size',
7193             'glTexStorage2D() with various sizes'
7194         );
7195         this.addChild(storageGroup);
7197         //    W H L
7198         /** @type {Array<{width: number, height: number, levels: number}>} */
7199         var tex2DSizes = [{
7200                 width: 1, height: 1, levels: 1
7201             }, {
7202                 width: 2, height: 2, levels: 2
7203             }, {
7204                 width: 64, height: 32, levels: 7
7205             }, {
7206                 width: 32, height: 64, levels: 4
7207             }, {
7208                 width: 57, height: 63, levels: 1
7209             }, {
7210                 width: 57, height: 63, levels: 2
7211             }, {
7212                 width: 57, height: 63, levels: 6
7213             }
7214         ];
7216         //    S L
7217         /** @type {Array<{sizes: number, levels: number}>} */
7218         var cubeSizes = [{
7219                 sizes: 1, levels: 1
7220             }, {
7221                 sizes: 2, levels: 2
7222             }, {
7223                 sizes: 57, levels: 1
7224             }, {
7225                 sizes: 57, levels: 2
7226             }, {
7227                 sizes: 57, levels: 6
7228             }, {
7229                 sizes: 64, levels: 4
7230             }, {
7231                 sizes: 64, levels: 7
7232             }
7233         ];
7235         for (var ndx = 0; ndx < tex2DSizes.length; ndx++) {
7236             format = gl.RGBA8;
7237             /** @type {number} */ var width = tex2DSizes[ndx].width;
7238             /** @type {number} */ var height = tex2DSizes[ndx].height;
7239             /** @type {number} */ var levels = tex2DSizes[ndx].levels;
7240             /** @type {string} */
7241             var name = '2d_' + width + 'x' + height + '_' + levels + '_levels';
7243             storageGroup.addChild(
7244                 new es3fTextureSpecificationTests.BasicTexStorage2DCase(
7245                     name, '', format, width, height, levels
7246                 )
7247             );
7248         }
7250         for (var ndx = 0; ndx < cubeSizes.length; ndx++) {
7251             format = gl.RGBA8;
7252             size = cubeSizes[ndx].sizes;
7253             levels = cubeSizes[ndx].levels;
7254             name = 'cube_' + size + 'x' + size + '_' + levels + '_levels';
7256             storageGroup.addChild(
7257                 new es3fTextureSpecificationTests.BasicTexStorageCubeCase(
7258                     name, '', format, size, levels
7259                 )
7260             );
7261         }
7263         // glTexStorage3D() cases.
7265         // Color formats.
7266         var splitStorage2DArray = 3, splitStorage3D = 4;
7267         /** @type {Array<{tcuTestCase.DeqpTest}>} */ var colorFormatGroup2DArray = [];
7268         for (var ii = 0; ii < splitStorage2DArray; ++ii) {
7269             colorFormatGroup2DArray.push(
7270                 new tcuTestCase.DeqpTest('texstorage3d.format', 'glTexStorage3D() with all formats')
7271             );
7272             this.addChild(colorFormatGroup2DArray[ii]);
7273         }
7274         /** @type {Array<{tcuTestCase.DeqpTest}>} */ var colorFormatGroup3D = [];
7275         for (var ii = 0; ii < splitStorage3D; ++ii) {
7276             colorFormatGroup3D.push(
7277                 new tcuTestCase.DeqpTest('texstorage3d.format', 'glTexStorage3D() with all formats')
7278             );
7279             this.addChild(colorFormatGroup3D[ii]);
7280         }
7282         // Color formats.
7283         for (var formatNdx = 0; formatNdx < colorFormats.length; formatNdx++) {
7284             fmtName = colorFormats[formatNdx].name;
7285             internalFormat = colorFormats[formatNdx].internalFormat;
7286             tex2DArrayWidth = 57;
7287             tex2DArrayHeight = 13;
7288             var tex2DArrayLayers = 7;
7289             tex2DArrayLevels = es3fTextureSpecificationTests.maxLevelCount(
7290                 tex2DArrayWidth, tex2DArrayHeight
7291             );
7292             tex3DWidth = 59;
7293             tex3DHeight = 37;
7294             tex3DDepth = 11;
7295             var tex3DLevels = es3fTextureSpecificationTests.maxLevelCount(
7296                 tex3DWidth, tex3DHeight, tex3DDepth
7297             );
7299             colorFormatGroup2DArray[formatNdx % splitStorage2DArray].addChild(
7300                 new es3fTextureSpecificationTests.BasicTexStorage2DArrayCase(
7301                     fmtName + '_2d_array', '', internalFormat, tex2DArrayWidth,
7302                     tex2DArrayHeight, tex2DArrayLayers, tex2DArrayLevels
7303                 )
7304             );
7305             colorFormatGroup3D[formatNdx % splitStorage3D].addChild(
7306                 new es3fTextureSpecificationTests.BasicTexStorage3DCase(
7307                     fmtName + '_3d', '', internalFormat, tex3DWidth,
7308                     tex3DHeight, tex3DDepth, tex3DLevels
7309                 )
7310             );
7311         }
7313         storageGroup = new tcuTestCase.DeqpTest(
7314             'texstorage3d.format',
7315             'glTexStorage3D() with all formats'
7316         );
7317         this.addChild(storageGroup);
7319         // Depth/stencil formats (only 2D texture array is supported).
7320         for (var formatNdx = 0;
7321             formatNdx < depthStencilFormats.length;
7322             formatNdx++) {
7323             fmtName = depthStencilFormats[formatNdx].name;
7324             internalFormat = depthStencilFormats[formatNdx].internalFormat;
7325             // WebGL 2 specific constraint.
7326             if (internalFormat == gl.DEPTH32F_STENCIL8)
7327                 continue;
7329             tex2DArrayWidth = 57;
7330             tex2DArrayHeight = 13;
7331             tex2DArrayLayers = 7;
7332             tex2DArrayLevels = es3fTextureSpecificationTests.maxLevelCount(
7333                 tex2DArrayWidth, tex2DArrayHeight
7334             );
7336             storageGroup.addChild(
7337                 new es3fTextureSpecificationTests.BasicTexStorage2DArrayCase(
7338                     fmtName + '_2d_array', '', internalFormat, tex2DArrayWidth,
7339                     tex2DArrayHeight, tex2DArrayLayers, tex2DArrayLevels
7340                 )
7341             );
7342         }
7344         // Sizes.
7345         //    W H La Le
7346         /**
7347          * @type {Array<{width: number, height: number,
7348          * layers: number, levels: number}>}
7349          */
7350         var tex2DArraySizes = [{
7351                 width: 1, height: 1, layers: 1, levels: 1
7352             }, {
7353                 width: 2, height: 2, layers: 2, levels: 2
7354             }, {
7355                 width: 64, height: 32, layers: 3, levels: 7
7356             }, {
7357                 width: 32, height: 64, layers: 3, levels: 4
7358             }, {
7359                 width: 57, height: 63, layers: 5, levels: 1
7360             }, {
7361                 width: 57, height: 63, layers: 5, levels: 2
7362             }, {
7363                 width: 57, height: 63, layers: 5, levels: 6
7364             }
7365         ];
7367         //    W H D L
7368         /**
7369          * @type {Array<{width: number, height: number,
7370          * depth: number, levels: number}>}
7371          */
7372         var tex3DSizes = [{
7373                 width: 1, height: 1, depth: 1, levels: 1
7374             }, {
7375                 width: 2, height: 2, depth: 2, levels: 2
7376             }, {
7377                 width: 64, height: 32, depth: 16, levels: 7
7378             }, {
7379                 width: 32, height: 64, depth: 16, levels: 4
7380             }, {
7381                 width: 32, height: 16, depth: 64, levels: 4
7382             }, {
7383                 width: 57, height: 63, depth: 11, levels: 1
7384             }, {
7385                 width: 57, height: 63, depth: 11, levels: 2
7386             }, {
7387                 width: 57, height: 63, depth: 11, levels: 6
7388             }
7389         ];
7391         storageGroup = new tcuTestCase.DeqpTest(
7392             'texstorage3d.size', 'glTexStorage3D() with various sizes'
7393         );
7394         this.addChild(storageGroup);
7396         for (var ndx = 0; ndx < tex2DArraySizes.length; ndx++) {
7397             format = gl.RGBA8;
7398             width = tex2DArraySizes[ndx].width;
7399             height = tex2DArraySizes[ndx].height;
7400             /** @type {number} */ var layers = tex2DArraySizes[ndx].layers;
7401             levels = tex2DArraySizes[ndx].levels;
7402             name = '2d_array_' + width + 'x' + height + 'x' +
7403                 layers + '_' + levels + '_levels';
7405             storageGroup.addChild(
7406                 new es3fTextureSpecificationTests.BasicTexStorage2DArrayCase(
7407                     name, '', format, width, height, layers, levels
7408                 )
7409             );
7410         }
7412         for (var ndx = 0; ndx < tex3DSizes.length; ndx++) {
7413             format = gl.RGBA8;
7414             width = tex3DSizes[ndx].width;
7415             height = tex3DSizes[ndx].height;
7416             var depth = tex3DSizes[ndx].depth;
7417             levels = tex3DSizes[ndx].levels;
7418             name = '3d_' + width + 'x' + height + 'x' +
7419                 depth + '_' + levels + '_levels';
7421             storageGroup.addChild(
7422                 new es3fTextureSpecificationTests.BasicTexStorage3DCase(
7423                     name, '', format, width, height, depth, levels
7424                 )
7425             );
7426         }
7427     };
7429     /**
7430     * Run test
7431     * @param {WebGL2RenderingContext} context
7432     * @param {Array<number>=} range Test range
7433     */
7434     es3fTextureSpecificationTests.run = function(context, range) {
7435         gl = context;
7436         //Set up Test Root parameters
7437         var state = tcuTestCase.runner;
7438         state.setRoot(new es3fTextureSpecificationTests.TextureSpecificationTests());
7439         if (range)
7440             state.setRange(range);
7442         //Set up name and description of this test series.
7443         setCurrentTestName(state.testCases.fullName());
7444         description(state.testCases.getDescription());
7446         try {
7447             //Run test cases
7448             tcuTestCase.runTestCases();
7449         }
7450         catch (err) {
7451             testFailedOptions('Failed to es3fTextureSpecificationTests.run tests', false);
7452             tcuTestCase.runner.terminate();
7453         }
7454     };