Merge "Fix out of bounds accesses in TexImage*DParamsCase." am: 60902d4e1b
[platform/upstream/VK-GL-CTS.git] / modules / gles3 / functional / es3fTextureSpecificationTests.cpp
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES 3.0 Module
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  *//*!
20  * \file
21  * \brief Texture specification tests.
22  *
23  * \todo [pyry] Following tests are missing:
24  *  - Specify mipmap incomplete texture, use without mipmaps, re-specify
25  *    as complete and render.
26  *  - Randomly re-specify levels to eventually reach mipmap-complete texture.
27  *//*--------------------------------------------------------------------*/
28
29 #include "es3fTextureSpecificationTests.hpp"
30 #include "tcuTestLog.hpp"
31 #include "tcuImageCompare.hpp"
32 #include "tcuTextureUtil.hpp"
33 #include "tcuVectorUtil.hpp"
34 #include "gluStrUtil.hpp"
35 #include "gluTexture.hpp"
36 #include "gluTextureUtil.hpp"
37 #include "sglrContextUtil.hpp"
38 #include "sglrContextWrapper.hpp"
39 #include "sglrGLContext.hpp"
40 #include "sglrReferenceContext.hpp"
41 #include "glsTextureTestUtil.hpp"
42 #include "deRandom.hpp"
43 #include "deStringUtil.hpp"
44
45 // \todo [2012-04-29 pyry] Should be named SglrUtil
46 #include "es3fFboTestUtil.hpp"
47
48 #include "glwEnums.hpp"
49
50 namespace deqp
51 {
52 namespace gles3
53 {
54 namespace Functional
55 {
56
57 using std::string;
58 using std::vector;
59 using std::pair;
60 using tcu::TestLog;
61 using tcu::Vec4;
62 using tcu::IVec4;
63 using tcu::UVec4;
64 using namespace FboTestUtil;
65
66 tcu::TextureFormat mapGLUnsizedInternalFormat (deUint32 internalFormat)
67 {
68         using tcu::TextureFormat;
69         switch (internalFormat)
70         {
71                 case GL_ALPHA:                          return TextureFormat(TextureFormat::A,          TextureFormat::UNORM_INT8);
72                 case GL_LUMINANCE:                      return TextureFormat(TextureFormat::L,          TextureFormat::UNORM_INT8);
73                 case GL_LUMINANCE_ALPHA:        return TextureFormat(TextureFormat::LA,         TextureFormat::UNORM_INT8);
74                 case GL_RGB:                            return TextureFormat(TextureFormat::RGB,        TextureFormat::UNORM_INT8);
75                 case GL_RGBA:                           return TextureFormat(TextureFormat::RGBA,       TextureFormat::UNORM_INT8);
76                 default:
77                         throw tcu::InternalError(string("Can't map GL unsized internal format (") + tcu::toHex(internalFormat).toString() + ") to texture format");
78         }
79 }
80
81 enum
82 {
83         VIEWPORT_WIDTH  = 256,
84         VIEWPORT_HEIGHT = 256
85 };
86
87 static inline int maxLevelCount (int width, int height)
88 {
89         return (int)deLog2Floor32(de::max(width, height))+1;
90 }
91
92 static inline int maxLevelCount (int width, int height, int depth)
93 {
94         return (int)deLog2Floor32(de::max(width, de::max(height, depth)))+1;
95 }
96
97 template <int Size>
98 static tcu::Vector<float, Size> randomVector (de::Random& rnd, const tcu::Vector<float, Size>& minVal = tcu::Vector<float, Size>(0.0f), const tcu::Vector<float, Size>& maxVal = tcu::Vector<float, Size>(1.0f))
99 {
100         tcu::Vector<float, Size> res;
101         for (int ndx = 0; ndx < Size; ndx++)
102                 res[ndx] = rnd.getFloat(minVal[ndx], maxVal[ndx]);
103         return res;
104 }
105
106 static const deUint32 s_cubeMapFaces[] =
107 {
108         GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
109         GL_TEXTURE_CUBE_MAP_POSITIVE_X,
110         GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
111         GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
112         GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
113         GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
114 };
115
116 static tcu::IVec4 getPixelFormatCompareDepth (const tcu::PixelFormat& pixelFormat, tcu::TextureFormat textureFormat)
117 {
118         switch (textureFormat.order)
119         {
120                 case tcu::TextureFormat::L:
121                 case tcu::TextureFormat::LA:
122                         return tcu::IVec4(pixelFormat.redBits, pixelFormat.redBits, pixelFormat.redBits, pixelFormat.alphaBits);
123                 default:
124                         return tcu::IVec4(pixelFormat.redBits, pixelFormat.greenBits, pixelFormat.blueBits, pixelFormat.alphaBits);
125         }
126 }
127
128 static IVec4 getEffectiveTextureFormatBitDepth (tcu::TextureFormat textureFormat)
129 {
130         if (textureFormat.order == tcu::TextureFormat::DS)
131         {
132                 // When sampling depth-stencil texture, we actually sample just
133                 // the depth component.
134                 return tcu::getTextureFormatBitDepth(tcu::getEffectiveDepthStencilTextureFormat(textureFormat, tcu::Sampler::MODE_DEPTH));
135         }
136         else
137                 return tcu::getTextureFormatBitDepth(textureFormat);
138 }
139
140 static tcu::UVec4 computeCompareThreshold (const tcu::PixelFormat& pixelFormat, tcu::TextureFormat textureFormat)
141 {
142         const IVec4             texFormatBits           = getEffectiveTextureFormatBitDepth(textureFormat);
143         const IVec4             pixelFormatBits         = getPixelFormatCompareDepth(pixelFormat, textureFormat);
144         const IVec4             accurateFmtBits         = min(pixelFormatBits, texFormatBits);
145         const IVec4             compareBits                     = select(accurateFmtBits, IVec4(8), greaterThan(accurateFmtBits, IVec4(0))) - 1;
146
147         return (IVec4(1) << (8-compareBits)).asUint();
148 }
149
150 class TextureSpecCase : public TestCase, public sglr::ContextWrapper
151 {
152 public:
153                                                         TextureSpecCase         (Context& context, const char* name, const char* desc);
154                                                         ~TextureSpecCase        (void);
155
156         IterateResult                   iterate                         (void);
157
158 protected:
159         virtual void                    createTexture           (void)                                                                                                                                  = DE_NULL;
160         virtual void                    verifyTexture           (sglr::GLContext& gles3Context, sglr::ReferenceContext& refContext)     = DE_NULL;
161
162         // Utilities.
163         void                                    renderTex                       (tcu::Surface& dst, deUint32 program, int width, int height);
164         void                                    readPixels                      (tcu::Surface& dst, int x, int y, int width, int height);
165
166 private:
167                                                         TextureSpecCase         (const TextureSpecCase& other);
168         TextureSpecCase&                operator=                       (const TextureSpecCase& other);
169 };
170
171 TextureSpecCase::TextureSpecCase (Context& context, const char* name, const char* desc)
172         : TestCase(context, name, desc)
173 {
174 }
175
176 TextureSpecCase::~TextureSpecCase (void)
177 {
178 }
179
180 TextureSpecCase::IterateResult TextureSpecCase::iterate (void)
181 {
182         glu::RenderContext&                     renderCtx                               = TestCase::m_context.getRenderContext();
183         const tcu::RenderTarget&        renderTarget                    = renderCtx.getRenderTarget();
184         tcu::TestLog&                           log                                             = m_testCtx.getLog();
185
186         if (renderTarget.getWidth() < VIEWPORT_WIDTH || renderTarget.getHeight() < VIEWPORT_HEIGHT)
187                 throw tcu::NotSupportedError("Too small viewport", "", __FILE__, __LINE__);
188
189         // Context size, and viewport for GLES3
190         de::Random              rnd                     (deStringHash(getName()));
191         int                             width           = deMin32(renderTarget.getWidth(),      VIEWPORT_WIDTH);
192         int                             height          = deMin32(renderTarget.getHeight(),     VIEWPORT_HEIGHT);
193         int                             x                       = rnd.getInt(0, renderTarget.getWidth()         - width);
194         int                             y                       = rnd.getInt(0, renderTarget.getHeight()        - height);
195
196         // Contexts.
197         sglr::GLContext                                 gles3Context    (renderCtx, log, sglr::GLCONTEXT_LOG_CALLS, tcu::IVec4(x, y, width, height));
198         sglr::ReferenceContextBuffers   refBuffers              (tcu::PixelFormat(8,8,8,renderTarget.getPixelFormat().alphaBits?8:0), 0 /* depth */, 0 /* stencil */, width, height);
199         sglr::ReferenceContext                  refContext              (sglr::ReferenceContextLimits(renderCtx), refBuffers.getColorbuffer(), refBuffers.getDepthbuffer(), refBuffers.getStencilbuffer());
200
201         // Clear color buffer.
202         for (int ndx = 0; ndx < 2; ndx++)
203         {
204                 setContext(ndx ? (sglr::Context*)&refContext : (sglr::Context*)&gles3Context);
205                 glClearColor(0.125f, 0.25f, 0.5f, 1.0f);
206                 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
207         }
208
209         // Construct texture using both GLES3 and reference contexts.
210         for (int ndx = 0; ndx < 2; ndx++)
211         {
212                 setContext(ndx ? (sglr::Context*)&refContext : (sglr::Context*)&gles3Context);
213                 createTexture();
214                 TCU_CHECK(glGetError() == GL_NO_ERROR);
215         }
216
217         // Initialize case result to pass.
218         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
219
220         // Disable logging.
221         gles3Context.enableLogging(0);
222
223         // Verify results.
224         verifyTexture(gles3Context, refContext);
225
226         return STOP;
227 }
228
229 void TextureSpecCase::renderTex (tcu::Surface& dst, deUint32 program, int width, int height)
230 {
231         int             targetW         = getWidth();
232         int             targetH         = getHeight();
233
234         float   w                       = (float)width  / (float)targetW;
235         float   h                       = (float)height / (float)targetH;
236
237         sglr::drawQuad(*getCurrentContext(), program, tcu::Vec3(-1.0f, -1.0f, 0.0f), tcu::Vec3(-1.0f + w*2.0f, -1.0f + h*2.0f, 0.0f));
238
239         // Read pixels back.
240         readPixels(dst, 0, 0, width, height);
241 }
242
243 void TextureSpecCase::readPixels (tcu::Surface& dst, int x, int y, int width, int height)
244 {
245         dst.setSize(width, height);
246         glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, dst.getAccess().getDataPtr());
247 }
248
249 class Texture2DSpecCase : public TextureSpecCase
250 {
251 public:
252                                                         Texture2DSpecCase       (Context& context, const char* name, const char* desc, const tcu::TextureFormat& format, int width, int height, int numLevels);
253                                                         ~Texture2DSpecCase      (void);
254
255 protected:
256         virtual void                    verifyTexture           (sglr::GLContext& gles3Context, sglr::ReferenceContext& refContext);
257
258         tcu::TextureFormat              m_texFormat;
259         tcu::TextureFormatInfo  m_texFormatInfo;
260         int                                             m_width;
261         int                                             m_height;
262         int                                             m_numLevels;
263 };
264
265 Texture2DSpecCase::Texture2DSpecCase (Context& context, const char* name, const char* desc, const tcu::TextureFormat& format, int width, int height, int numLevels)
266         : TextureSpecCase               (context, name, desc)
267         , m_texFormat                   (format)
268         , m_texFormatInfo               (tcu::getTextureFormatInfo(format))
269         , m_width                               (width)
270         , m_height                              (height)
271         , m_numLevels                   (numLevels)
272 {
273 }
274
275 Texture2DSpecCase::~Texture2DSpecCase (void)
276 {
277 }
278
279 void Texture2DSpecCase::verifyTexture (sglr::GLContext& gles3Context, sglr::ReferenceContext& refContext)
280 {
281         Texture2DShader shader                  (DataTypes() << glu::getSampler2DType(m_texFormat), glu::TYPE_FLOAT_VEC4);
282         deUint32                shaderIDgles    = gles3Context.createProgram(&shader);
283         deUint32                shaderIDRef             = refContext.createProgram(&shader);
284
285         shader.setTexScaleBias(0, m_texFormatInfo.lookupScale, m_texFormatInfo.lookupBias);
286
287         // Set state.
288         for (int ndx = 0; ndx < 2; ndx++)
289         {
290                 sglr::Context* ctx = ndx ? static_cast<sglr::Context*>(&refContext) : static_cast<sglr::Context*>(&gles3Context);
291
292                 setContext(ctx);
293
294                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,   GL_NEAREST_MIPMAP_NEAREST);
295                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,   GL_NEAREST);
296                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,               GL_CLAMP_TO_EDGE);
297                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,               GL_CLAMP_TO_EDGE);
298                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL,    m_numLevels-1);
299         }
300
301         for (int levelNdx = 0; levelNdx < m_numLevels; levelNdx++)
302         {
303                 int                             levelW          = de::max(1, m_width >> levelNdx);
304                 int                             levelH          = de::max(1, m_height >> levelNdx);
305                 tcu::Surface    reference;
306                 tcu::Surface    result;
307
308                 for (int ndx = 0; ndx < 2; ndx++)
309                 {
310                         tcu::Surface&   dst                     = ndx ? reference                                                                       : result;
311                         sglr::Context*  ctx                     = ndx ? static_cast<sglr::Context*>(&refContext)        : static_cast<sglr::Context*>(&gles3Context);
312                         deUint32                shaderID        = ndx ? shaderIDRef                                                                     : shaderIDgles;
313
314                         setContext(ctx);
315                         shader.setUniforms(*ctx, shaderID);
316                         renderTex(dst, shaderID, levelW, levelH);
317                 }
318
319                 UVec4                   threshold       = computeCompareThreshold(m_context.getRenderTarget().getPixelFormat(), m_texFormat);
320                 string                  levelStr        = de::toString(levelNdx);
321                 string                  name            = string("Level") + levelStr;
322                 string                  desc            = string("Level ") + levelStr;
323                 bool                    isOk            = tcu::intThresholdCompare(m_testCtx.getLog(), name.c_str(), desc.c_str(), reference.getAccess(), result.getAccess(), threshold,
324                                                                                                                            levelNdx == 0 ? tcu::COMPARE_LOG_RESULT : tcu::COMPARE_LOG_ON_ERROR);
325
326                 if (!isOk)
327                 {
328                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
329                         break;
330                 }
331         }
332 }
333
334 class TextureCubeSpecCase : public TextureSpecCase
335 {
336 public:
337                                                         TextureCubeSpecCase             (Context& context, const char* name, const char* desc, const tcu::TextureFormat& format, int size, int numLevels);
338                                                         ~TextureCubeSpecCase    (void);
339
340 protected:
341         virtual void                    verifyTexture                   (sglr::GLContext& gles3Context, sglr::ReferenceContext& refContext);
342
343         tcu::TextureFormat              m_texFormat;
344         tcu::TextureFormatInfo  m_texFormatInfo;
345         int                                             m_size;
346         int                                             m_numLevels;
347 };
348
349 TextureCubeSpecCase::TextureCubeSpecCase (Context& context, const char* name, const char* desc, const tcu::TextureFormat& format, int size, int numLevels)
350         : TextureSpecCase               (context, name, desc)
351         , m_texFormat                   (format)
352         , m_texFormatInfo               (tcu::getTextureFormatInfo(format))
353         , m_size                                (size)
354         , m_numLevels                   (numLevels)
355 {
356 }
357
358 TextureCubeSpecCase::~TextureCubeSpecCase (void)
359 {
360 }
361
362 void TextureCubeSpecCase::verifyTexture (sglr::GLContext& gles3Context, sglr::ReferenceContext& refContext)
363 {
364         TextureCubeShader       shader                  (glu::getSamplerCubeType(m_texFormat), glu::TYPE_FLOAT_VEC4);
365         deUint32                        shaderIDgles    = gles3Context.createProgram(&shader);
366         deUint32                        shaderIDRef             = refContext.createProgram(&shader);
367
368         shader.setTexScaleBias(m_texFormatInfo.lookupScale, m_texFormatInfo.lookupBias);
369
370         // Set state.
371         for (int ndx = 0; ndx < 2; ndx++)
372         {
373                 sglr::Context* ctx = ndx ? static_cast<sglr::Context*>(&refContext) : static_cast<sglr::Context*>(&gles3Context);
374
375                 setContext(ctx);
376
377                 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,     GL_NEAREST_MIPMAP_NEAREST);
378                 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER,     GL_NEAREST);
379                 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,         GL_CLAMP_TO_EDGE);
380                 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,         GL_CLAMP_TO_EDGE);
381                 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL,      m_numLevels-1);
382         }
383
384         for (int levelNdx = 0; levelNdx < m_numLevels; levelNdx++)
385         {
386                 int             levelSize       = de::max(1, m_size >> levelNdx);
387                 bool    isOk            = true;
388
389                 for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
390                 {
391                         tcu::Surface    reference;
392                         tcu::Surface    result;
393
394                         if (levelSize <= 2)
395                                 continue; // Fuzzy compare doesn't work for images this small.
396
397                         shader.setFace((tcu::CubeFace)face);
398
399                         for (int ndx = 0; ndx < 2; ndx++)
400                         {
401                                 tcu::Surface&   dst                     = ndx ? reference                                                                       : result;
402                                 sglr::Context*  ctx                     = ndx ? static_cast<sglr::Context*>(&refContext)        : static_cast<sglr::Context*>(&gles3Context);
403                                 deUint32                shaderID        = ndx ? shaderIDRef                                                                     : shaderIDgles;
404
405                                 setContext(ctx);
406                                 shader.setUniforms(*ctx, shaderID);
407                                 renderTex(dst, shaderID, levelSize, levelSize);
408                         }
409
410                         const float             threshold       = 0.02f;
411                         string                  faceStr         = de::toString((tcu::CubeFace)face);
412                         string                  levelStr        = de::toString(levelNdx);
413                         string                  name            = string("Level") + levelStr;
414                         string                  desc            = string("Level ") + levelStr + ", face " + faceStr;
415                         bool                    isFaceOk        = tcu::fuzzyCompare(m_testCtx.getLog(), name.c_str(), desc.c_str(), reference, result, threshold,
416                                                                                                                         levelNdx == 0 ? tcu::COMPARE_LOG_RESULT : tcu::COMPARE_LOG_ON_ERROR);
417
418                         if (!isFaceOk)
419                         {
420                                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
421                                 isOk = false;
422                                 break;
423                         }
424                 }
425
426                 if (!isOk)
427                         break;
428         }
429 }
430
431 class Texture2DArraySpecCase : public TextureSpecCase
432 {
433 public:
434                                                         Texture2DArraySpecCase  (Context& context, const char* name, const char* desc, const tcu::TextureFormat& format, int width, int height, int numLayers, int numLevels);
435                                                         ~Texture2DArraySpecCase (void);
436
437 protected:
438         virtual void                    verifyTexture                   (sglr::GLContext& gles3Context, sglr::ReferenceContext& refContext);
439
440         tcu::TextureFormat              m_texFormat;
441         tcu::TextureFormatInfo  m_texFormatInfo;
442         int                                             m_width;
443         int                                             m_height;
444         int                                             m_numLayers;
445         int                                             m_numLevels;
446 };
447
448 Texture2DArraySpecCase::Texture2DArraySpecCase (Context& context, const char* name, const char* desc, const tcu::TextureFormat& format, int width, int height, int numLayers, int numLevels)
449         : TextureSpecCase               (context, name, desc)
450         , m_texFormat                   (format)
451         , m_texFormatInfo               (tcu::getTextureFormatInfo(format))
452         , m_width                               (width)
453         , m_height                              (height)
454         , m_numLayers                   (numLayers)
455         , m_numLevels                   (numLevels)
456 {
457 }
458
459 Texture2DArraySpecCase::~Texture2DArraySpecCase (void)
460 {
461 }
462
463 void Texture2DArraySpecCase::verifyTexture (sglr::GLContext& gles3Context, sglr::ReferenceContext& refContext)
464 {
465         Texture2DArrayShader    shader                  (glu::getSampler2DArrayType(m_texFormat), glu::TYPE_FLOAT_VEC4);
466         deUint32                                shaderIDgles    = gles3Context.createProgram(&shader);
467         deUint32                                shaderIDRef             = refContext.createProgram(&shader);
468
469         shader.setTexScaleBias(m_texFormatInfo.lookupScale, m_texFormatInfo.lookupBias);
470
471         // Set state.
472         for (int ndx = 0; ndx < 2; ndx++)
473         {
474                 sglr::Context* ctx = ndx ? static_cast<sglr::Context*>(&refContext) : static_cast<sglr::Context*>(&gles3Context);
475
476                 setContext(ctx);
477
478                 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER,     GL_NEAREST_MIPMAP_NEAREST);
479                 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER,     GL_NEAREST);
480                 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S,         GL_CLAMP_TO_EDGE);
481                 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T,         GL_CLAMP_TO_EDGE);
482                 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_R,         GL_CLAMP_TO_EDGE);
483                 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL,      m_numLevels-1);
484         }
485
486         for (int layerNdx = 0; layerNdx < m_numLayers; layerNdx++)
487         {
488                 bool layerOk = true;
489
490                 shader.setLayer(layerNdx);
491
492                 for (int levelNdx = 0; levelNdx < m_numLevels; levelNdx++)
493                 {
494                         int                             levelW          = de::max(1, m_width    >> levelNdx);
495                         int                             levelH          = de::max(1, m_height   >> levelNdx);
496                         tcu::Surface    reference;
497                         tcu::Surface    result;
498
499                         for (int ndx = 0; ndx < 2; ndx++)
500                         {
501                                 tcu::Surface&   dst                     = ndx ? reference                                                                       : result;
502                                 sglr::Context*  ctx                     = ndx ? static_cast<sglr::Context*>(&refContext)        : static_cast<sglr::Context*>(&gles3Context);
503                                 deUint32                shaderID        = ndx ? shaderIDRef                                                                     : shaderIDgles;
504
505                                 setContext(ctx);
506                                 shader.setUniforms(*ctx, shaderID);
507                                 renderTex(dst, shaderID, levelW, levelH);
508                         }
509
510                         UVec4                   threshold       = computeCompareThreshold(m_context.getRenderTarget().getPixelFormat(), m_texFormat);
511                         string                  levelStr        = de::toString(levelNdx);
512                         string                  layerStr        = de::toString(layerNdx);
513                         string                  name            = string("Layer") + layerStr + "Level" + levelStr;
514                         string                  desc            = string("Layer ") + layerStr + ", Level " + levelStr;
515                         bool                    depthOk         = tcu::intThresholdCompare(m_testCtx.getLog(), name.c_str(), desc.c_str(), reference.getAccess(), result.getAccess(), threshold,
516                                                                                                                                    (levelNdx == 0 && layerNdx == 0) ? tcu::COMPARE_LOG_RESULT : tcu::COMPARE_LOG_ON_ERROR);
517
518                         if (!depthOk)
519                         {
520                                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
521                                 layerOk = false;
522                                 break;
523                         }
524                 }
525
526                 if (!layerOk)
527                         break;
528         }
529 }
530
531 class Texture3DSpecCase : public TextureSpecCase
532 {
533 public:
534                                                         Texture3DSpecCase       (Context& context, const char* name, const char* desc, const tcu::TextureFormat& format, int width, int height, int depth, int numLevels);
535                                                         ~Texture3DSpecCase      (void);
536
537 protected:
538         virtual void                    verifyTexture           (sglr::GLContext& gles3Context, sglr::ReferenceContext& refContext);
539
540         tcu::TextureFormat              m_texFormat;
541         tcu::TextureFormatInfo  m_texFormatInfo;
542         int                                             m_width;
543         int                                             m_height;
544         int                                             m_depth;
545         int                                             m_numLevels;
546 };
547
548 Texture3DSpecCase::Texture3DSpecCase (Context& context, const char* name, const char* desc, const tcu::TextureFormat& format, int width, int height, int depth, int numLevels)
549         : TextureSpecCase               (context, name, desc)
550         , m_texFormat                   (format)
551         , m_texFormatInfo               (tcu::getTextureFormatInfo(format))
552         , m_width                               (width)
553         , m_height                              (height)
554         , m_depth                               (depth)
555         , m_numLevels                   (numLevels)
556 {
557 }
558
559 Texture3DSpecCase::~Texture3DSpecCase (void)
560 {
561 }
562
563 void Texture3DSpecCase::verifyTexture (sglr::GLContext& gles3Context, sglr::ReferenceContext& refContext)
564 {
565         Texture3DShader shader                  (glu::getSampler3DType(m_texFormat), glu::TYPE_FLOAT_VEC4);
566         deUint32                shaderIDgles    = gles3Context.createProgram(&shader);
567         deUint32                shaderIDRef             = refContext.createProgram(&shader);
568
569         shader.setTexScaleBias(m_texFormatInfo.lookupScale, m_texFormatInfo.lookupBias);
570
571         // Set state.
572         for (int ndx = 0; ndx < 2; ndx++)
573         {
574                 sglr::Context* ctx = ndx ? static_cast<sglr::Context*>(&refContext) : static_cast<sglr::Context*>(&gles3Context);
575
576                 setContext(ctx);
577
578                 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER,   GL_NEAREST_MIPMAP_NEAREST);
579                 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER,   GL_NEAREST);
580                 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S,               GL_CLAMP_TO_EDGE);
581                 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T,               GL_CLAMP_TO_EDGE);
582                 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R,               GL_CLAMP_TO_EDGE);
583                 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL,    m_numLevels-1);
584         }
585
586         for (int levelNdx = 0; levelNdx < m_numLevels; levelNdx++)
587         {
588                 int             levelW          = de::max(1, m_width    >> levelNdx);
589                 int             levelH          = de::max(1, m_height   >> levelNdx);
590                 int             levelD          = de::max(1, m_depth    >> levelNdx);
591                 bool    levelOk         = true;
592
593                 for (int depth = 0; depth < levelD; depth++)
594                 {
595                         tcu::Surface    reference;
596                         tcu::Surface    result;
597
598                         shader.setDepth(((float)depth + 0.5f) / (float)levelD);
599
600                         for (int ndx = 0; ndx < 2; ndx++)
601                         {
602                                 tcu::Surface&   dst                     = ndx ? reference                                                                       : result;
603                                 sglr::Context*  ctx                     = ndx ? static_cast<sglr::Context*>(&refContext)        : static_cast<sglr::Context*>(&gles3Context);
604                                 deUint32                shaderID        = ndx ? shaderIDRef                                                                     : shaderIDgles;
605
606                                 setContext(ctx);
607                                 shader.setUniforms(*ctx, shaderID);
608                                 renderTex(dst, shaderID, levelW, levelH);
609                         }
610
611                         UVec4                   threshold       = computeCompareThreshold(m_context.getRenderTarget().getPixelFormat(), m_texFormat);
612                         string                  levelStr        = de::toString(levelNdx);
613                         string                  sliceStr        = de::toString(depth);
614                         string                  name            = string("Level") + levelStr + "Slice" + sliceStr;
615                         string                  desc            = string("Level ") + levelStr + ", Slice " + sliceStr;
616                         bool                    depthOk         = tcu::intThresholdCompare(m_testCtx.getLog(), name.c_str(), desc.c_str(), reference.getAccess(), result.getAccess(), threshold,
617                                                                                                                                    (levelNdx == 0 && depth == 0) ? tcu::COMPARE_LOG_RESULT : tcu::COMPARE_LOG_ON_ERROR);
618
619                         if (!depthOk)
620                         {
621                                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
622                                 levelOk = false;
623                                 break;
624                         }
625                 }
626
627                 if (!levelOk)
628                         break;
629         }
630 }
631
632 // Basic TexImage2D() with 2D texture usage
633 class BasicTexImage2DCase : public Texture2DSpecCase
634 {
635 public:
636         // Unsized internal format.
637         BasicTexImage2DCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int width, int height)
638                 : Texture2DSpecCase     (context, name, desc, glu::mapGLTransferFormat(format, dataType), width, height, maxLevelCount(width, height))
639                 , m_internalFormat      (format)
640                 , m_format                      (format)
641                 , m_dataType            (dataType)
642         {
643         }
644
645         // Sized internal format.
646         BasicTexImage2DCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height)
647                 : Texture2DSpecCase     (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, maxLevelCount(width, height))
648                 , m_internalFormat      (internalFormat)
649                 , m_format                      (GL_NONE)
650                 , m_dataType            (GL_NONE)
651         {
652                 glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat);
653                 m_format        = fmt.format;
654                 m_dataType      = fmt.dataType;
655         }
656
657 protected:
658         void createTexture (void)
659         {
660                 deUint32                        tex                     = 0;
661                 tcu::TextureLevel       levelData       (glu::mapGLTransferFormat(m_format, m_dataType));
662                 de::Random                      rnd                     (deStringHash(getName()));
663
664                 glGenTextures(1, &tex);
665                 glBindTexture(GL_TEXTURE_2D, tex);
666                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
667
668                 for (int ndx = 0; ndx < m_numLevels; ndx++)
669                 {
670                         int             levelW          = de::max(1, m_width >> ndx);
671                         int             levelH          = de::max(1, m_height >> ndx);
672                         Vec4    gMin            = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
673                         Vec4    gMax            = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
674
675                         levelData.setSize(levelW, levelH);
676                         tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
677
678                         glTexImage2D(GL_TEXTURE_2D, ndx, m_internalFormat, levelW, levelH, 0, m_format, m_dataType, levelData.getAccess().getDataPtr());
679                 }
680         }
681
682         deUint32        m_internalFormat;
683         deUint32        m_format;
684         deUint32        m_dataType;
685 };
686
687 // Basic TexImage2D() with cubemap usage
688 class BasicTexImageCubeCase : public TextureCubeSpecCase
689 {
690 public:
691         // Unsized formats.
692         BasicTexImageCubeCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int size)
693                 : TextureCubeSpecCase   (context, name, desc, glu::mapGLTransferFormat(format, dataType), size, deLog2Floor32(size)+1)
694                 , m_internalFormat              (format)
695                 , m_format                              (format)
696                 , m_dataType                    (dataType)
697         {
698         }
699
700         // Sized internal formats.
701         BasicTexImageCubeCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int size)
702                 : TextureCubeSpecCase   (context, name, desc, glu::mapGLInternalFormat(internalFormat), size, deLog2Floor32(size)+1)
703                 , m_internalFormat              (internalFormat)
704                 , m_format                              (GL_NONE)
705                 , m_dataType                    (GL_NONE)
706         {
707                 glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat);
708                 m_format        = fmt.format;
709                 m_dataType      = fmt.dataType;
710         }
711
712 protected:
713         void createTexture (void)
714         {
715                 deUint32                        tex                     = 0;
716                 tcu::TextureLevel       levelData       (glu::mapGLTransferFormat(m_format, m_dataType));
717                 de::Random                      rnd                     (deStringHash(getName()));
718
719                 glGenTextures(1, &tex);
720                 glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
721                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
722
723                 for (int ndx = 0; ndx < m_numLevels; ndx++)
724                 {
725                         int levelSize = de::max(1, m_size >> ndx);
726
727                         levelData.setSize(levelSize, levelSize);
728
729                         for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
730                         {
731                                 Vec4 gMin = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
732                                 Vec4 gMax = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
733
734                                 tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
735
736                                 glTexImage2D(s_cubeMapFaces[face], ndx, m_internalFormat, levelSize, levelSize, 0, m_format, m_dataType, levelData.getAccess().getDataPtr());
737                         }
738                 }
739         }
740
741         deUint32        m_internalFormat;
742         deUint32        m_format;
743         deUint32        m_dataType;
744 };
745
746 // Basic TexImage3D() with 2D array texture usage
747 class BasicTexImage2DArrayCase : public Texture2DArraySpecCase
748 {
749 public:
750         BasicTexImage2DArrayCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height, int numLayers)
751                 : Texture2DArraySpecCase        (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, numLayers, maxLevelCount(width, height))
752                 , m_internalFormat                      (internalFormat)
753         {
754         }
755
756 protected:
757         void createTexture (void)
758         {
759                 deUint32                                tex                     = 0;
760                 de::Random                              rnd                     (deStringHash(getName()));
761                 glu::TransferFormat             transferFmt     = glu::getTransferFormat(m_texFormat);
762                 tcu::TextureLevel               levelData       (glu::mapGLTransferFormat(transferFmt.format, transferFmt.dataType));
763
764                 glGenTextures(1, &tex);
765                 glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
766                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
767
768                 for (int ndx = 0; ndx < m_numLevels; ndx++)
769                 {
770                         int             levelW          = de::max(1, m_width    >> ndx);
771                         int             levelH          = de::max(1, m_height   >> ndx);
772                         Vec4    gMin            = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
773                         Vec4    gMax            = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
774
775                         levelData.setSize(levelW, levelH, m_numLayers);
776                         tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
777
778                         glTexImage3D(GL_TEXTURE_2D_ARRAY, ndx, m_internalFormat, levelW, levelH, m_numLayers, 0, transferFmt.format, transferFmt.dataType, levelData.getAccess().getDataPtr());
779                 }
780         }
781
782         deUint32 m_internalFormat;
783 };
784
785 // Basic TexImage3D() with 3D texture usage
786 class BasicTexImage3DCase : public Texture3DSpecCase
787 {
788 public:
789         BasicTexImage3DCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height, int depth)
790                 : Texture3DSpecCase     (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, depth, maxLevelCount(width, height, depth))
791                 , m_internalFormat      (internalFormat)
792         {
793         }
794
795 protected:
796         void createTexture (void)
797         {
798                 deUint32                                tex                     = 0;
799                 de::Random                              rnd                     (deStringHash(getName()));
800                 glu::TransferFormat             transferFmt     = glu::getTransferFormat(m_texFormat);
801                 tcu::TextureLevel               levelData       (glu::mapGLTransferFormat(transferFmt.format, transferFmt.dataType));
802
803                 glGenTextures(1, &tex);
804                 glBindTexture(GL_TEXTURE_3D, tex);
805                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
806
807                 for (int ndx = 0; ndx < m_numLevels; ndx++)
808                 {
809                         int             levelW          = de::max(1, m_width    >> ndx);
810                         int             levelH          = de::max(1, m_height   >> ndx);
811                         int             levelD          = de::max(1, m_depth    >> ndx);
812                         Vec4    gMin            = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
813                         Vec4    gMax            = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
814
815                         levelData.setSize(levelW, levelH, levelD);
816                         tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
817
818                         glTexImage3D(GL_TEXTURE_3D, ndx, m_internalFormat, levelW, levelH, levelD, 0, transferFmt.format, transferFmt.dataType, levelData.getAccess().getDataPtr());
819                 }
820         }
821
822         deUint32 m_internalFormat;
823 };
824
825 // Randomized 2D texture specification using TexImage2D
826 class RandomOrderTexImage2DCase : public Texture2DSpecCase
827 {
828 public:
829         RandomOrderTexImage2DCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int width, int height)
830                 : Texture2DSpecCase     (context, name, desc, glu::mapGLTransferFormat(format, dataType), width, height, maxLevelCount(width, height))
831                 , m_internalFormat      (format)
832                 , m_format                      (format)
833                 , m_dataType            (dataType)
834         {
835         }
836
837         RandomOrderTexImage2DCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height)
838                 : Texture2DSpecCase     (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, maxLevelCount(width, height))
839                 , m_internalFormat      (internalFormat)
840                 , m_format                      (GL_NONE)
841                 , m_dataType            (GL_NONE)
842         {
843                 glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat);
844                 m_format        = fmt.format;
845                 m_dataType      = fmt.dataType;
846         }
847
848 protected:
849         void createTexture (void)
850         {
851                 deUint32                        tex                     = 0;
852                 tcu::TextureLevel       levelData       (glu::mapGLTransferFormat(m_format, m_dataType));
853                 de::Random                      rnd                     (deStringHash(getName()));
854
855                 glGenTextures(1, &tex);
856                 glBindTexture(GL_TEXTURE_2D, tex);
857                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
858
859                 vector<int>                     levels          (m_numLevels);
860
861                 for (int i = 0; i < m_numLevels; i++)
862                         levels[i] = i;
863                 rnd.shuffle(levels.begin(), levels.end());
864
865                 for (int ndx = 0; ndx < m_numLevels; ndx++)
866                 {
867                         int             levelNdx        = levels[ndx];
868                         int             levelW          = de::max(1, m_width    >> levelNdx);
869                         int             levelH          = de::max(1, m_height   >> levelNdx);
870                         Vec4    gMin            = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
871                         Vec4    gMax            = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
872
873                         levelData.setSize(levelW, levelH);
874                         tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
875
876                         glTexImage2D(GL_TEXTURE_2D, levelNdx, m_internalFormat, levelW, levelH, 0, m_format, m_dataType, levelData.getAccess().getDataPtr());
877                 }
878         }
879
880         deUint32        m_internalFormat;
881         deUint32        m_format;
882         deUint32        m_dataType;
883 };
884
885 // Randomized cubemap texture specification using TexImage2D
886 class RandomOrderTexImageCubeCase : public TextureCubeSpecCase
887 {
888 public:
889         RandomOrderTexImageCubeCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int size)
890                 : TextureCubeSpecCase   (context, name, desc, glu::mapGLTransferFormat(format, dataType), size, deLog2Floor32(size)+1)
891                 , m_internalFormat              (GL_NONE)
892                 , m_format                              (format)
893                 , m_dataType                    (dataType)
894         {
895         }
896
897         RandomOrderTexImageCubeCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int size)
898                 : TextureCubeSpecCase   (context, name, desc, glu::mapGLInternalFormat(internalFormat), size, deLog2Floor32(size)+1)
899                 , m_internalFormat              (internalFormat)
900                 , m_format                              (GL_NONE)
901                 , m_dataType                    (GL_NONE)
902         {
903                 glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat);
904                 m_format        = fmt.format;
905                 m_dataType      = fmt.dataType;
906         }
907
908 protected:
909         void createTexture (void)
910         {
911                 deUint32                        tex                     = 0;
912                 tcu::TextureLevel       levelData       (glu::mapGLTransferFormat(m_format, m_dataType));
913                 de::Random                      rnd                     (deStringHash(getName()));
914
915                 glGenTextures(1, &tex);
916                 glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
917                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
918
919                 // Level-face pairs.
920                 vector<pair<int, tcu::CubeFace> >       images  (m_numLevels*6);
921
922                 for (int ndx = 0; ndx < m_numLevels; ndx++)
923                         for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
924                                 images[ndx*6 + face] = std::make_pair(ndx, (tcu::CubeFace)face);
925
926                 rnd.shuffle(images.begin(), images.end());
927
928                 for (int ndx = 0; ndx < (int)images.size(); ndx++)
929                 {
930                         int                             levelNdx        = images[ndx].first;
931                         tcu::CubeFace   face            = images[ndx].second;
932                         int                             levelSize       = de::max(1, m_size >> levelNdx);
933                         Vec4                    gMin            = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
934                         Vec4                    gMax            = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
935
936                         levelData.setSize(levelSize, levelSize);
937                         tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
938
939                         glTexImage2D(s_cubeMapFaces[face], levelNdx, m_internalFormat, levelSize, levelSize, 0, m_format, m_dataType, levelData.getAccess().getDataPtr());
940                 }
941         }
942
943         deUint32        m_internalFormat;
944         deUint32        m_format;
945         deUint32        m_dataType;
946 };
947
948 // TexImage2D() unpack alignment case.
949 class TexImage2DAlignCase : public Texture2DSpecCase
950 {
951 public:
952         TexImage2DAlignCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int width, int height, int numLevels, int alignment)
953                 : Texture2DSpecCase     (context, name, desc, glu::mapGLTransferFormat(format, dataType), width, height, numLevels)
954                 , m_internalFormat      (format)
955                 , m_format                      (format)
956                 , m_dataType            (dataType)
957                 , m_alignment           (alignment)
958         {
959         }
960
961         TexImage2DAlignCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height, int numLevels, int alignment)
962                 : Texture2DSpecCase     (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, numLevels)
963                 , m_internalFormat      (internalFormat)
964                 , m_format                      (GL_NONE)
965                 , m_dataType            (GL_NONE)
966                 , m_alignment           (alignment)
967         {
968                 glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat);
969                 m_format        = fmt.format;
970                 m_dataType      = fmt.dataType;
971         }
972
973 protected:
974         void createTexture (void)
975         {
976                 deUint32                        tex                     = 0;
977                 vector<deUint8>         data;
978
979                 glGenTextures(1, &tex);
980                 glBindTexture(GL_TEXTURE_2D, tex);
981                 glPixelStorei(GL_UNPACK_ALIGNMENT, m_alignment);
982
983                 for (int ndx = 0; ndx < m_numLevels; ndx++)
984                 {
985                         int             levelW          = de::max(1, m_width >> ndx);
986                         int             levelH          = de::max(1, m_height >> ndx);
987                         Vec4    colorA          = Vec4(1.0f, 0.0f, 0.0f, 1.0f)*(m_texFormatInfo.valueMax-m_texFormatInfo.valueMin) + m_texFormatInfo.valueMin;
988                         Vec4    colorB          = Vec4(0.0f, 1.0f, 0.0f, 1.0f)*(m_texFormatInfo.valueMax-m_texFormatInfo.valueMin) + m_texFormatInfo.valueMin;
989                         int             rowPitch        = deAlign32(levelW*m_texFormat.getPixelSize(), m_alignment);
990                         int             cellSize        = de::max(1, de::min(levelW >> 2, levelH >> 2));
991
992                         data.resize(rowPitch*levelH);
993                         tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, levelW, levelH, 1, rowPitch, 0, &data[0]), cellSize, colorA, colorB);
994
995                         glTexImage2D(GL_TEXTURE_2D, ndx, m_internalFormat, levelW, levelH, 0, m_format, m_dataType, &data[0]);
996                 }
997         }
998
999         deUint32        m_internalFormat;
1000         deUint32        m_format;
1001         deUint32        m_dataType;
1002         int                     m_alignment;
1003 };
1004
1005 // TexImage2D() unpack alignment case.
1006 class TexImageCubeAlignCase : public TextureCubeSpecCase
1007 {
1008 public:
1009         TexImageCubeAlignCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int size, int numLevels, int alignment)
1010                 : TextureCubeSpecCase   (context, name, desc, glu::mapGLTransferFormat(format, dataType), size, numLevels)
1011                 , m_internalFormat              (format)
1012                 , m_format                              (format)
1013                 , m_dataType                    (dataType)
1014                 , m_alignment                   (alignment)
1015         {
1016         }
1017
1018         TexImageCubeAlignCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int size, int numLevels, int alignment)
1019                 : TextureCubeSpecCase   (context, name, desc, glu::mapGLInternalFormat(internalFormat), size, numLevels)
1020                 , m_internalFormat              (internalFormat)
1021                 , m_format                              (GL_NONE)
1022                 , m_dataType                    (GL_NONE)
1023                 , m_alignment                   (alignment)
1024         {
1025                 glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat);
1026                 m_format        = fmt.format;
1027                 m_dataType      = fmt.dataType;
1028         }
1029
1030 protected:
1031         void createTexture (void)
1032         {
1033                 deUint32                        tex                     = 0;
1034                 vector<deUint8>         data;
1035
1036                 glGenTextures(1, &tex);
1037                 glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
1038                 glPixelStorei(GL_UNPACK_ALIGNMENT, m_alignment);
1039
1040                 for (int ndx = 0; ndx < m_numLevels; ndx++)
1041                 {
1042                         int             levelSize       = de::max(1, m_size >> ndx);
1043                         int             rowPitch        = deAlign32(m_texFormat.getPixelSize()*levelSize, m_alignment);
1044                         Vec4    colorA          = Vec4(1.0f, 0.0f, 0.0f, 1.0f)*(m_texFormatInfo.valueMax-m_texFormatInfo.valueMin) + m_texFormatInfo.valueMin;
1045                         Vec4    colorB          = Vec4(0.0f, 1.0f, 0.0f, 1.0f)*(m_texFormatInfo.valueMax-m_texFormatInfo.valueMin) + m_texFormatInfo.valueMin;
1046                         int             cellSize        = de::max(1, levelSize >> 2);
1047
1048                         data.resize(rowPitch*levelSize);
1049                         tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, levelSize, levelSize, 1, rowPitch, 0, &data[0]), cellSize, colorA, colorB);
1050
1051                         for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
1052                                 glTexImage2D(s_cubeMapFaces[face], ndx, m_internalFormat, levelSize, levelSize, 0, m_format, m_dataType, &data[0]);
1053                 }
1054         }
1055
1056         deUint32        m_internalFormat;
1057         deUint32        m_format;
1058         deUint32        m_dataType;
1059         int                     m_alignment;
1060 };
1061
1062 // TexImage2D() unpack parameters case.
1063 class TexImage2DParamsCase : public Texture2DSpecCase
1064 {
1065 public:
1066         TexImage2DParamsCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height, int rowLength, int skipRows, int skipPixels, int alignment)
1067                 : Texture2DSpecCase     (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, 1)
1068                 , m_internalFormat      (internalFormat)
1069                 , m_rowLength           (rowLength)
1070                 , m_skipRows            (skipRows)
1071                 , m_skipPixels          (skipPixels)
1072                 , m_alignment           (alignment)
1073         {
1074         }
1075
1076 protected:
1077         void createTexture (void)
1078         {
1079                 glu::TransferFormat             transferFmt             = glu::getTransferFormat(m_texFormat);
1080                 int                                             pixelSize               = m_texFormat.getPixelSize();
1081                 int                                             rowLength               = m_rowLength > 0 ? m_rowLength : m_width;
1082                 int                                             rowPitch                = deAlign32(rowLength*pixelSize, m_alignment);
1083                 deUint32                                tex                             = 0;
1084                 vector<deUint8>                 data;
1085
1086                 DE_ASSERT(m_numLevels == 1);
1087
1088                 // Fill data with grid.
1089                 data.resize(pixelSize * m_skipPixels + rowPitch * (m_height + m_skipRows));
1090                 {
1091                         Vec4    cScale          = m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
1092                         Vec4    cBias           = m_texFormatInfo.valueMin;
1093                         Vec4    colorA          = Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
1094                         Vec4    colorB          = Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
1095
1096                         tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, 1, rowPitch, 0, &data[0] + m_skipRows*rowPitch + m_skipPixels*pixelSize), 4, colorA, colorB);
1097                 }
1098
1099                 glPixelStorei(GL_UNPACK_ROW_LENGTH,             m_rowLength);
1100                 glPixelStorei(GL_UNPACK_SKIP_ROWS,              m_skipRows);
1101                 glPixelStorei(GL_UNPACK_SKIP_PIXELS,    m_skipPixels);
1102                 glPixelStorei(GL_UNPACK_ALIGNMENT,              m_alignment);
1103
1104                 glGenTextures(1, &tex);
1105                 glBindTexture(GL_TEXTURE_2D, tex);
1106                 glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_width, m_height, 0, transferFmt.format, transferFmt.dataType, &data[0]);
1107         }
1108
1109         deUint32        m_internalFormat;
1110         int                     m_rowLength;
1111         int                     m_skipRows;
1112         int                     m_skipPixels;
1113         int                     m_alignment;
1114 };
1115
1116 // TexImage3D() unpack parameters case.
1117 class TexImage3DParamsCase : public Texture3DSpecCase
1118 {
1119 public:
1120         TexImage3DParamsCase (Context&          context,
1121                                                    const char*  name,
1122                                                    const char*  desc,
1123                                                    deUint32             internalFormat,
1124                                                    int                  width,
1125                                                    int                  height,
1126                                                    int                  depth,
1127                                                    int                  imageHeight,
1128                                                    int                  rowLength,
1129                                                    int                  skipImages,
1130                                                    int                  skipRows,
1131                                                    int                  skipPixels,
1132                                                    int                  alignment)
1133                 : Texture3DSpecCase     (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, depth, 1)
1134                 , m_internalFormat      (internalFormat)
1135                 , m_imageHeight         (imageHeight)
1136                 , m_rowLength           (rowLength)
1137                 , m_skipImages          (skipImages)
1138                 , m_skipRows            (skipRows)
1139                 , m_skipPixels          (skipPixels)
1140                 , m_alignment           (alignment)
1141         {
1142         }
1143
1144 protected:
1145         void createTexture (void)
1146         {
1147                 glu::TransferFormat             transferFmt             = glu::getTransferFormat(m_texFormat);
1148                 int                                             pixelSize               = m_texFormat.getPixelSize();
1149                 int                                             rowLength               = m_rowLength > 0 ? m_rowLength : m_width;
1150                 int                                             rowPitch                = deAlign32(rowLength*pixelSize, m_alignment);
1151                 int                                             imageHeight             = m_imageHeight > 0 ? m_imageHeight : m_height;
1152                 int                                             slicePitch              = imageHeight*rowPitch;
1153                 deUint32                                tex                             = 0;
1154                 vector<deUint8>                 data;
1155
1156                 DE_ASSERT(m_numLevels == 1);
1157
1158                 // Fill data with grid.
1159                 data.resize(pixelSize * m_skipPixels + rowPitch * m_skipRows + slicePitch * (m_skipImages + m_depth));
1160                 {
1161                         Vec4    cScale          = m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
1162                         Vec4    cBias           = m_texFormatInfo.valueMin;
1163                         Vec4    colorA          = Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
1164                         Vec4    colorB          = Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
1165
1166                         tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, m_depth, rowPitch, slicePitch, &data[0] + m_skipImages*slicePitch + m_skipRows*rowPitch + m_skipPixels*pixelSize), 4, colorA, colorB);
1167                 }
1168
1169                 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT,   m_imageHeight);
1170                 glPixelStorei(GL_UNPACK_ROW_LENGTH,             m_rowLength);
1171                 glPixelStorei(GL_UNPACK_SKIP_IMAGES,    m_skipImages);
1172                 glPixelStorei(GL_UNPACK_SKIP_ROWS,              m_skipRows);
1173                 glPixelStorei(GL_UNPACK_SKIP_PIXELS,    m_skipPixels);
1174                 glPixelStorei(GL_UNPACK_ALIGNMENT,              m_alignment);
1175
1176                 glGenTextures(1, &tex);
1177                 glBindTexture(GL_TEXTURE_3D, tex);
1178                 glTexImage3D(GL_TEXTURE_3D, 0, m_internalFormat, m_width, m_height, m_depth, 0, transferFmt.format, transferFmt.dataType, &data[0]);
1179         }
1180
1181         deUint32        m_internalFormat;
1182         int                     m_imageHeight;
1183         int                     m_rowLength;
1184         int                     m_skipImages;
1185         int                     m_skipRows;
1186         int                     m_skipPixels;
1187         int                     m_alignment;
1188 };
1189
1190 // Basic TexSubImage2D() with 2D texture usage
1191 class BasicTexSubImage2DCase : public Texture2DSpecCase
1192 {
1193 public:
1194         BasicTexSubImage2DCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int width, int height)
1195                 : Texture2DSpecCase     (context, name, desc, glu::mapGLTransferFormat(format, dataType), width, height, maxLevelCount(width, height))
1196                 , m_internalFormat      (format)
1197                 , m_format                      (format)
1198                 , m_dataType            (dataType)
1199         {
1200         }
1201
1202         BasicTexSubImage2DCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height)
1203                 : Texture2DSpecCase     (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, maxLevelCount(width, height))
1204                 , m_internalFormat      (internalFormat)
1205                 , m_format                      (GL_NONE)
1206                 , m_dataType            (GL_NONE)
1207         {
1208                 glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat);
1209                 m_format        = fmt.format;
1210                 m_dataType      = fmt.dataType;
1211         }
1212
1213 protected:
1214         void createTexture (void)
1215         {
1216                 deUint32                        tex                     = 0;
1217                 tcu::TextureLevel       data            (m_texFormat);
1218                 de::Random                      rnd                     (deStringHash(getName()));
1219
1220                 glGenTextures(1, &tex);
1221                 glBindTexture(GL_TEXTURE_2D, tex);
1222                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1223
1224                 // First specify full texture.
1225                 for (int ndx = 0; ndx < m_numLevels; ndx++)
1226                 {
1227                         int             levelW          = de::max(1, m_width >> ndx);
1228                         int             levelH          = de::max(1, m_height >> ndx);
1229                         Vec4    gMin            = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
1230                         Vec4    gMax            = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
1231
1232                         data.setSize(levelW, levelH);
1233                         tcu::fillWithComponentGradients(data.getAccess(), gMin, gMax);
1234
1235                         glTexImage2D(GL_TEXTURE_2D, ndx, m_internalFormat, levelW, levelH, 0, m_format, m_dataType, data.getAccess().getDataPtr());
1236                 }
1237
1238                 // Re-specify parts of each level.
1239                 for (int ndx = 0; ndx < m_numLevels; ndx++)
1240                 {
1241                         int             levelW          = de::max(1, m_width >> ndx);
1242                         int             levelH          = de::max(1, m_height >> ndx);
1243
1244                         int             w                       = rnd.getInt(1, levelW);
1245                         int             h                       = rnd.getInt(1, levelH);
1246                         int             x                       = rnd.getInt(0, levelW-w);
1247                         int             y                       = rnd.getInt(0, levelH-h);
1248
1249                         Vec4    colorA          = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
1250                         Vec4    colorB          = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
1251                         int             cellSize        = rnd.getInt(2, 16);
1252
1253                         data.setSize(w, h);
1254                         tcu::fillWithGrid(data.getAccess(), cellSize, colorA, colorB);
1255
1256                         glTexSubImage2D(GL_TEXTURE_2D, ndx, x, y, w, h, m_format, m_dataType, data.getAccess().getDataPtr());
1257                 }
1258         }
1259
1260         deUint32        m_internalFormat;
1261         deUint32        m_format;
1262         deUint32        m_dataType;
1263 };
1264
1265 // Basic TexSubImage2D() with cubemap usage
1266 class BasicTexSubImageCubeCase : public TextureCubeSpecCase
1267 {
1268 public:
1269         BasicTexSubImageCubeCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int size)
1270                 : TextureCubeSpecCase   (context, name, desc, glu::mapGLTransferFormat(format, dataType), size, deLog2Floor32(size)+1)
1271                 , m_internalFormat              (format)
1272                 , m_format                              (format)
1273                 , m_dataType                    (dataType)
1274         {
1275         }
1276
1277         BasicTexSubImageCubeCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int size)
1278                 : TextureCubeSpecCase   (context, name, desc, glu::mapGLInternalFormat(internalFormat), size, deLog2Floor32(size)+1)
1279                 , m_internalFormat              (internalFormat)
1280                 , m_format                              (GL_NONE)
1281                 , m_dataType                    (GL_NONE)
1282         {
1283                 glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat);
1284                 m_format        = fmt.format;
1285                 m_dataType      = fmt.dataType;
1286         }
1287
1288 protected:
1289         void createTexture (void)
1290         {
1291                 deUint32                        tex                     = 0;
1292                 tcu::TextureLevel       data            (m_texFormat);
1293                 de::Random                      rnd                     (deStringHash(getName()));
1294
1295                 glGenTextures(1, &tex);
1296                 glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
1297                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1298
1299                 for (int ndx = 0; ndx < m_numLevels; ndx++)
1300                 {
1301                         int levelSize = de::max(1, m_size >> ndx);
1302
1303                         data.setSize(levelSize, levelSize);
1304
1305                         for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
1306                         {
1307                                 Vec4 gMin = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
1308                                 Vec4 gMax = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
1309
1310                                 tcu::fillWithComponentGradients(data.getAccess(), gMin, gMax);
1311
1312                                 glTexImage2D(s_cubeMapFaces[face], ndx, m_internalFormat, levelSize, levelSize, 0, m_format, m_dataType, data.getAccess().getDataPtr());
1313                         }
1314                 }
1315
1316                 // Re-specify parts of each face and level.
1317                 for (int ndx = 0; ndx < m_numLevels; ndx++)
1318                 {
1319                         int levelSize = de::max(1, m_size >> ndx);
1320
1321                         for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
1322                         {
1323                                 int             w                       = rnd.getInt(1, levelSize);
1324                                 int             h                       = rnd.getInt(1, levelSize);
1325                                 int             x                       = rnd.getInt(0, levelSize-w);
1326                                 int             y                       = rnd.getInt(0, levelSize-h);
1327
1328                                 Vec4    colorA          = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
1329                                 Vec4    colorB          = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
1330                                 int             cellSize        = rnd.getInt(2, 16);
1331
1332                                 data.setSize(w, h);
1333                                 tcu::fillWithGrid(data.getAccess(), cellSize, colorA, colorB);
1334
1335                                 glTexSubImage2D(s_cubeMapFaces[face], ndx, x, y, w, h, m_format, m_dataType, data.getAccess().getDataPtr());
1336                         }
1337                 }
1338         }
1339
1340         deUint32        m_internalFormat;
1341         deUint32        m_format;
1342         deUint32        m_dataType;
1343 };
1344
1345 // TexSubImage2D() unpack parameters case.
1346 class TexSubImage2DParamsCase : public Texture2DSpecCase
1347 {
1348 public:
1349         TexSubImage2DParamsCase (Context&               context,
1350                                                          const char*    name,
1351                                                          const char*    desc,
1352                                                          deUint32               internalFormat,
1353                                                          int                    width,
1354                                                          int                    height,
1355                                                          int                    subX,
1356                                                          int                    subY,
1357                                                          int                    subW,
1358                                                          int                    subH,
1359                                                          int                    rowLength,
1360                                                          int                    skipRows,
1361                                                          int                    skipPixels,
1362                                                          int                    alignment)
1363                 : Texture2DSpecCase     (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, 1)
1364                 , m_internalFormat      (internalFormat)
1365                 , m_subX                        (subX)
1366                 , m_subY                        (subY)
1367                 , m_subW                        (subW)
1368                 , m_subH                        (subH)
1369                 , m_rowLength           (rowLength)
1370                 , m_skipRows            (skipRows)
1371                 , m_skipPixels          (skipPixels)
1372                 , m_alignment           (alignment)
1373         {
1374         }
1375
1376 protected:
1377         void createTexture (void)
1378         {
1379                 glu::TransferFormat             transferFmt             = glu::getTransferFormat(m_texFormat);
1380                 int                                             pixelSize               = m_texFormat.getPixelSize();
1381                 deUint32                                tex                             = 0;
1382                 vector<deUint8>                 data;
1383
1384                 DE_ASSERT(m_numLevels == 1);
1385
1386                 glGenTextures(1, &tex);
1387                 glBindTexture(GL_TEXTURE_2D, tex);
1388
1389                 // First fill texture with gradient.
1390                 data.resize(deAlign32(m_width*pixelSize, 4)*m_height);
1391                 tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, 1, deAlign32(m_width*pixelSize, 4), 0, &data[0]), m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
1392                 glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_width, m_height, 0, transferFmt.format, transferFmt.dataType, &data[0]);
1393
1394                 // Fill data with grid.
1395                 {
1396                         int             rowLength       = m_rowLength > 0 ? m_rowLength : m_subW;
1397                         int             rowPitch        = deAlign32(rowLength*pixelSize, m_alignment);
1398                         int             height          = m_subH + m_skipRows;
1399                         Vec4    cScale          = m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
1400                         Vec4    cBias           = m_texFormatInfo.valueMin;
1401                         Vec4    colorA          = Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
1402                         Vec4    colorB          = Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
1403
1404                         data.resize(rowPitch*height);
1405                         tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, m_subW, m_subH, 1, rowPitch, 0, &data[0] + m_skipRows*rowPitch + m_skipPixels*pixelSize), 4, colorA, colorB);
1406                 }
1407
1408                 glPixelStorei(GL_UNPACK_ROW_LENGTH,             m_rowLength);
1409                 glPixelStorei(GL_UNPACK_SKIP_ROWS,              m_skipRows);
1410                 glPixelStorei(GL_UNPACK_SKIP_PIXELS,    m_skipPixels);
1411                 glPixelStorei(GL_UNPACK_ALIGNMENT,              m_alignment);
1412                 glTexSubImage2D(GL_TEXTURE_2D, 0, m_subX, m_subY, m_subW, m_subH, transferFmt.format, transferFmt.dataType, &data[0]);
1413         }
1414
1415         deUint32        m_internalFormat;
1416         int                     m_subX;
1417         int                     m_subY;
1418         int                     m_subW;
1419         int                     m_subH;
1420         int                     m_rowLength;
1421         int                     m_skipRows;
1422         int                     m_skipPixels;
1423         int                     m_alignment;
1424 };
1425
1426 // Basic TexSubImage3D() with 3D texture usage
1427 class BasicTexSubImage3DCase : public Texture3DSpecCase
1428 {
1429 public:
1430         BasicTexSubImage3DCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height, int depth)
1431                 : Texture3DSpecCase     (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, depth, maxLevelCount(width, height, depth))
1432                 , m_internalFormat      (internalFormat)
1433         {
1434         }
1435
1436 protected:
1437         void createTexture (void)
1438         {
1439                 deUint32                                tex                             = 0;
1440                 tcu::TextureLevel               data                    (m_texFormat);
1441                 de::Random                              rnd                             (deStringHash(getName()));
1442                 glu::TransferFormat             transferFmt             = glu::getTransferFormat(m_texFormat);
1443
1444                 glGenTextures(1, &tex);
1445                 glBindTexture(GL_TEXTURE_3D, tex);
1446                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1447
1448                 // First specify full texture.
1449                 for (int ndx = 0; ndx < m_numLevels; ndx++)
1450                 {
1451                         int             levelW          = de::max(1, m_width >> ndx);
1452                         int             levelH          = de::max(1, m_height >> ndx);
1453                         int             levelD          = de::max(1, m_depth >> ndx);
1454                         Vec4    gMin            = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
1455                         Vec4    gMax            = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
1456
1457                         data.setSize(levelW, levelH, levelD);
1458                         tcu::fillWithComponentGradients(data.getAccess(), gMin, gMax);
1459
1460                         glTexImage3D(GL_TEXTURE_3D, ndx, m_internalFormat, levelW, levelH, levelD, 0, transferFmt.format, transferFmt.dataType, data.getAccess().getDataPtr());
1461                 }
1462
1463                 // Re-specify parts of each level.
1464                 for (int ndx = 0; ndx < m_numLevels; ndx++)
1465                 {
1466                         int             levelW          = de::max(1, m_width >> ndx);
1467                         int             levelH          = de::max(1, m_height >> ndx);
1468                         int             levelD          = de::max(1, m_depth >> ndx);
1469
1470                         int             w                       = rnd.getInt(1, levelW);
1471                         int             h                       = rnd.getInt(1, levelH);
1472                         int             d                       = rnd.getInt(1, levelD);
1473                         int             x                       = rnd.getInt(0, levelW-w);
1474                         int             y                       = rnd.getInt(0, levelH-h);
1475                         int             z                       = rnd.getInt(0, levelD-d);
1476
1477                         Vec4    colorA          = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
1478                         Vec4    colorB          = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
1479                         int             cellSize        = rnd.getInt(2, 16);
1480
1481                         data.setSize(w, h, d);
1482                         tcu::fillWithGrid(data.getAccess(), cellSize, colorA, colorB);
1483
1484                         glTexSubImage3D(GL_TEXTURE_3D, ndx, x, y, z, w, h, d, transferFmt.format, transferFmt.dataType, data.getAccess().getDataPtr());
1485                 }
1486         }
1487
1488         deUint32 m_internalFormat;
1489 };
1490
1491 // TexSubImage2D() to texture initialized with empty data
1492 class TexSubImage2DEmptyTexCase : public Texture2DSpecCase
1493 {
1494 public:
1495         TexSubImage2DEmptyTexCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int width, int height)
1496                 : Texture2DSpecCase     (context, name, desc, glu::mapGLTransferFormat(format, dataType), width, height, maxLevelCount(width, height))
1497                 , m_internalFormat      (format)
1498                 , m_format                      (format)
1499                 , m_dataType            (dataType)
1500         {
1501         }
1502
1503         TexSubImage2DEmptyTexCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height)
1504                 : Texture2DSpecCase     (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, maxLevelCount(width, height))
1505                 , m_internalFormat      (internalFormat)
1506                 , m_format                      (GL_NONE)
1507                 , m_dataType            (GL_NONE)
1508         {
1509                 glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat);
1510                 m_format        = fmt.format;
1511                 m_dataType      = fmt.dataType;
1512         }
1513
1514 protected:
1515         void createTexture (void)
1516         {
1517                 deUint32                        tex                     = 0;
1518                 tcu::TextureLevel       data            (m_texFormat);
1519                 de::Random                      rnd                     (deStringHash(getName()));
1520
1521                 glGenTextures(1, &tex);
1522                 glBindTexture(GL_TEXTURE_2D, tex);
1523                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1524
1525                 // First allocate storage for each level.
1526                 for (int ndx = 0; ndx < m_numLevels; ndx++)
1527                 {
1528                         int             levelW          = de::max(1, m_width >> ndx);
1529                         int             levelH          = de::max(1, m_height >> ndx);
1530
1531                         glTexImage2D(GL_TEXTURE_2D, ndx, m_internalFormat, levelW, levelH, 0, m_format, m_dataType, DE_NULL);
1532                 }
1533
1534                 // Specify pixel data to all levels using glTexSubImage2D()
1535                 for (int ndx = 0; ndx < m_numLevels; ndx++)
1536                 {
1537                         int             levelW          = de::max(1, m_width >> ndx);
1538                         int             levelH          = de::max(1, m_height >> ndx);
1539                         Vec4    gMin            = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
1540                         Vec4    gMax            = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
1541
1542                         data.setSize(levelW, levelH);
1543                         tcu::fillWithComponentGradients(data.getAccess(), gMin, gMax);
1544
1545                         glTexSubImage2D(GL_TEXTURE_2D, ndx, 0, 0, levelW, levelH, m_format, m_dataType, data.getAccess().getDataPtr());
1546                 }
1547         }
1548
1549         deUint32        m_internalFormat;
1550         deUint32        m_format;
1551         deUint32        m_dataType;
1552 };
1553
1554 // TexSubImage2D() to empty cubemap texture
1555 class TexSubImageCubeEmptyTexCase : public TextureCubeSpecCase
1556 {
1557 public:
1558         TexSubImageCubeEmptyTexCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int size)
1559                 : TextureCubeSpecCase   (context, name, desc, glu::mapGLTransferFormat(format, dataType), size, deLog2Floor32(size)+1)
1560                 , m_internalFormat              (format)
1561                 , m_format                              (format)
1562                 , m_dataType                    (dataType)
1563         {
1564         }
1565
1566         TexSubImageCubeEmptyTexCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int size)
1567                 : TextureCubeSpecCase   (context, name, desc, glu::mapGLInternalFormat(internalFormat), size, deLog2Floor32(size)+1)
1568                 , m_internalFormat              (internalFormat)
1569                 , m_format                              (GL_NONE)
1570                 , m_dataType                    (GL_NONE)
1571         {
1572                 glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat);
1573                 m_format        = fmt.format;
1574                 m_dataType      = fmt.dataType;
1575         }
1576
1577 protected:
1578         void createTexture (void)
1579         {
1580                 deUint32                        tex                     = 0;
1581                 tcu::TextureLevel       data            (m_texFormat);
1582                 de::Random                      rnd                     (deStringHash(getName()));
1583
1584                 glGenTextures(1, &tex);
1585                 glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
1586                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1587
1588                 // Specify storage for each level.
1589                 for (int ndx = 0; ndx < m_numLevels; ndx++)
1590                 {
1591                         int levelSize = de::max(1, m_size >> ndx);
1592
1593                         for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
1594                                 glTexImage2D(s_cubeMapFaces[face], ndx, m_internalFormat, levelSize, levelSize, 0, m_format, m_dataType, DE_NULL);
1595                 }
1596
1597                 // Specify data using glTexSubImage2D()
1598                 for (int ndx = 0; ndx < m_numLevels; ndx++)
1599                 {
1600                         int levelSize = de::max(1, m_size >> ndx);
1601
1602                         data.setSize(levelSize, levelSize);
1603
1604                         for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
1605                         {
1606                                 Vec4 gMin = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
1607                                 Vec4 gMax = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
1608
1609                                 tcu::fillWithComponentGradients(data.getAccess(), gMin, gMax);
1610
1611                                 glTexSubImage2D(s_cubeMapFaces[face], ndx, 0, 0, levelSize, levelSize, m_format, m_dataType, data.getAccess().getDataPtr());
1612                         }
1613                 }
1614         }
1615
1616         deUint32        m_internalFormat;
1617         deUint32        m_format;
1618         deUint32        m_dataType;
1619 };
1620
1621 // TexSubImage2D() unpack alignment with 2D texture
1622 class TexSubImage2DAlignCase : public Texture2DSpecCase
1623 {
1624 public:
1625         TexSubImage2DAlignCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int width, int height, int subX, int subY, int subW, int subH, int alignment)
1626                 : Texture2DSpecCase     (context, name, desc, glu::mapGLTransferFormat(format, dataType), width, height, 1)
1627                 , m_internalFormat      (format)
1628                 , m_format                      (format)
1629                 , m_dataType            (dataType)
1630                 , m_subX                        (subX)
1631                 , m_subY                        (subY)
1632                 , m_subW                        (subW)
1633                 , m_subH                        (subH)
1634                 , m_alignment           (alignment)
1635         {
1636         }
1637
1638         TexSubImage2DAlignCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height, int subX, int subY, int subW, int subH, int alignment)
1639                 : Texture2DSpecCase     (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, 1)
1640                 , m_internalFormat      (internalFormat)
1641                 , m_format                      (GL_NONE)
1642                 , m_dataType            (GL_NONE)
1643                 , m_subX                        (subX)
1644                 , m_subY                        (subY)
1645                 , m_subW                        (subW)
1646                 , m_subH                        (subH)
1647                 , m_alignment           (alignment)
1648         {
1649                 glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat);
1650                 m_format        = fmt.format;
1651                 m_dataType      = fmt.dataType;
1652         }
1653
1654 protected:
1655         void createTexture (void)
1656         {
1657                 deUint32                        tex                     = 0;
1658                 vector<deUint8>         data;
1659
1660                 glGenTextures(1, &tex);
1661                 glBindTexture(GL_TEXTURE_2D, tex);
1662
1663                 // Specify base level.
1664                 data.resize(m_texFormat.getPixelSize()*m_width*m_height);
1665                 tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, 1, &data[0]), Vec4(0.0f), Vec4(1.0f));
1666
1667                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1668                 glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_width, m_height, 0, m_format, m_dataType, &data[0]);
1669
1670                 // Re-specify subrectangle.
1671                 int rowPitch = deAlign32(m_texFormat.getPixelSize()*m_subW, m_alignment);
1672                 data.resize(rowPitch*m_subH);
1673                 tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, m_subW, m_subH, 1, rowPitch, 0, &data[0]), 4, Vec4(1.0f, 0.0f, 0.0f, 1.0f), Vec4(0.0f, 1.0f, 0.0f, 1.0f));
1674
1675                 glPixelStorei(GL_UNPACK_ALIGNMENT, m_alignment);
1676                 glTexSubImage2D(GL_TEXTURE_2D, 0, m_subX, m_subY, m_subW, m_subH, m_format, m_dataType, &data[0]);
1677         }
1678
1679         deUint32        m_internalFormat;
1680         deUint32        m_format;
1681         deUint32        m_dataType;
1682         int                     m_subX;
1683         int                     m_subY;
1684         int                     m_subW;
1685         int                     m_subH;
1686         int                     m_alignment;
1687 };
1688
1689 // TexSubImage2D() unpack alignment with cubemap texture
1690 class TexSubImageCubeAlignCase : public TextureCubeSpecCase
1691 {
1692 public:
1693         TexSubImageCubeAlignCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int size, int subX, int subY, int subW, int subH, int alignment)
1694                 : TextureCubeSpecCase   (context, name, desc, glu::mapGLTransferFormat(format, dataType), size, 1)
1695                 , m_internalFormat              (format)
1696                 , m_format                              (format)
1697                 , m_dataType                    (dataType)
1698                 , m_subX                                (subX)
1699                 , m_subY                                (subY)
1700                 , m_subW                                (subW)
1701                 , m_subH                                (subH)
1702                 , m_alignment                   (alignment)
1703         {
1704         }
1705
1706         TexSubImageCubeAlignCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int size, int subX, int subY, int subW, int subH, int alignment)
1707                 : TextureCubeSpecCase   (context, name, desc, glu::mapGLInternalFormat(internalFormat), size, 1)
1708                 , m_internalFormat              (internalFormat)
1709                 , m_format                              (GL_NONE)
1710                 , m_dataType                    (GL_NONE)
1711                 , m_subX                                (subX)
1712                 , m_subY                                (subY)
1713                 , m_subW                                (subW)
1714                 , m_subH                                (subH)
1715                 , m_alignment                   (alignment)
1716         {
1717                 glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat);
1718                 m_format        = fmt.format;
1719                 m_dataType      = fmt.dataType;
1720         }
1721
1722 protected:
1723         void createTexture (void)
1724         {
1725                 deUint32                        tex                     = 0;
1726                 vector<deUint8>         data;
1727
1728                 glGenTextures(1, &tex);
1729                 glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
1730
1731                 // Specify base level.
1732                 data.resize(m_texFormat.getPixelSize()*m_size*m_size);
1733                 tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_size, m_size, 1, &data[0]), Vec4(0.0f), Vec4(1.0f));
1734
1735                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1736                 for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
1737                         glTexImage2D(s_cubeMapFaces[face], 0, m_internalFormat, m_size, m_size, 0, m_format, m_dataType, &data[0]);
1738
1739                 // Re-specify subrectangle.
1740                 int rowPitch = deAlign32(m_texFormat.getPixelSize()*m_subW, m_alignment);
1741                 data.resize(rowPitch*m_subH);
1742                 tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, m_subW, m_subH, 1, rowPitch, 0, &data[0]), 4, Vec4(1.0f, 0.0f, 0.0f, 1.0f), Vec4(0.0f, 1.0f, 0.0f, 1.0f));
1743
1744                 glPixelStorei(GL_UNPACK_ALIGNMENT, m_alignment);
1745                 for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
1746                         glTexSubImage2D(s_cubeMapFaces[face], 0, m_subX, m_subY, m_subW, m_subH, m_format, m_dataType, &data[0]);
1747         }
1748
1749         deUint32        m_internalFormat;
1750         deUint32        m_format;
1751         deUint32        m_dataType;
1752         int                     m_subX;
1753         int                     m_subY;
1754         int                     m_subW;
1755         int                     m_subH;
1756         int                     m_alignment;
1757 };
1758
1759 // TexSubImage3D() unpack parameters case.
1760 class TexSubImage3DParamsCase : public Texture3DSpecCase
1761 {
1762 public:
1763         TexSubImage3DParamsCase (Context&               context,
1764                                                          const char*    name,
1765                                                          const char*    desc,
1766                                                          deUint32               internalFormat,
1767                                                          int                    width,
1768                                                          int                    height,
1769                                                          int                    depth,
1770                                                          int                    subX,
1771                                                          int                    subY,
1772                                                          int                    subZ,
1773                                                          int                    subW,
1774                                                          int                    subH,
1775                                                          int                    subD,
1776                                                          int                    imageHeight,
1777                                                          int                    rowLength,
1778                                                          int                    skipImages,
1779                                                          int                    skipRows,
1780                                                          int                    skipPixels,
1781                                                          int                    alignment)
1782                 : Texture3DSpecCase     (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, depth, 1)
1783                 , m_internalFormat      (internalFormat)
1784                 , m_subX                        (subX)
1785                 , m_subY                        (subY)
1786                 , m_subZ                        (subZ)
1787                 , m_subW                        (subW)
1788                 , m_subH                        (subH)
1789                 , m_subD                        (subD)
1790                 , m_imageHeight         (imageHeight)
1791                 , m_rowLength           (rowLength)
1792                 , m_skipImages          (skipImages)
1793                 , m_skipRows            (skipRows)
1794                 , m_skipPixels          (skipPixels)
1795                 , m_alignment           (alignment)
1796         {
1797         }
1798
1799 protected:
1800         void createTexture (void)
1801         {
1802                 glu::TransferFormat             transferFmt             = glu::getTransferFormat(m_texFormat);
1803                 int                                             pixelSize               = m_texFormat.getPixelSize();
1804                 deUint32                                tex                             = 0;
1805                 vector<deUint8>                 data;
1806
1807                 DE_ASSERT(m_numLevels == 1);
1808
1809                 glGenTextures(1, &tex);
1810                 glBindTexture(GL_TEXTURE_3D, tex);
1811
1812                 // Fill with gradient.
1813                 {
1814                         int             rowPitch                = deAlign32(pixelSize*m_width,  4);
1815                         int             slicePitch              = rowPitch*m_height;
1816
1817                         data.resize(slicePitch*m_depth);
1818                         tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, m_depth, rowPitch, slicePitch, &data[0]), m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
1819                 }
1820
1821                 glTexImage3D(GL_TEXTURE_3D, 0, m_internalFormat, m_width, m_height, m_depth, 0, transferFmt.format, transferFmt.dataType, &data[0]);
1822
1823                 // Fill data with grid.
1824                 {
1825                         int             rowLength               = m_rowLength > 0 ? m_rowLength : m_subW;
1826                         int             rowPitch                = deAlign32(rowLength*pixelSize, m_alignment);
1827                         int             imageHeight             = m_imageHeight > 0 ? m_imageHeight : m_subH;
1828                         int             slicePitch              = imageHeight*rowPitch;
1829                         Vec4    cScale                  = m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
1830                         Vec4    cBias                   = m_texFormatInfo.valueMin;
1831                         Vec4    colorA                  = Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
1832                         Vec4    colorB                  = Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
1833
1834                         data.resize(slicePitch*(m_depth+m_skipImages));
1835                         tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, m_subW, m_subH, m_subD, rowPitch, slicePitch, &data[0] + m_skipImages*slicePitch + m_skipRows*rowPitch + m_skipPixels*pixelSize), 4, colorA, colorB);
1836                 }
1837
1838                 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT,   m_imageHeight);
1839                 glPixelStorei(GL_UNPACK_ROW_LENGTH,             m_rowLength);
1840                 glPixelStorei(GL_UNPACK_SKIP_IMAGES,    m_skipImages);
1841                 glPixelStorei(GL_UNPACK_SKIP_ROWS,              m_skipRows);
1842                 glPixelStorei(GL_UNPACK_SKIP_PIXELS,    m_skipPixels);
1843                 glPixelStorei(GL_UNPACK_ALIGNMENT,              m_alignment);
1844                 glTexSubImage3D(GL_TEXTURE_3D, 0, m_subX, m_subY, m_subZ, m_subW, m_subH, m_subD, transferFmt.format, transferFmt.dataType, &data[0]);
1845         }
1846
1847         deUint32        m_internalFormat;
1848         int                     m_subX;
1849         int                     m_subY;
1850         int                     m_subZ;
1851         int                     m_subW;
1852         int                     m_subH;
1853         int                     m_subD;
1854         int                     m_imageHeight;
1855         int                     m_rowLength;
1856         int                     m_skipImages;
1857         int                     m_skipRows;
1858         int                     m_skipPixels;
1859         int                     m_alignment;
1860 };
1861
1862 // Basic CopyTexImage2D() with 2D texture usage
1863 class BasicCopyTexImage2DCase : public Texture2DSpecCase
1864 {
1865 public:
1866         BasicCopyTexImage2DCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height)
1867                 : Texture2DSpecCase     (context, name, desc, glu::mapGLTransferFormat(internalFormat, GL_UNSIGNED_BYTE), width, height, maxLevelCount(width, height))
1868                 , m_internalFormat      (internalFormat)
1869         {
1870         }
1871
1872 protected:
1873         void createTexture (void)
1874         {
1875                 const tcu::RenderTarget&        renderTarget    = TestCase::m_context.getRenderContext().getRenderTarget();
1876                 bool                                            targetHasRGB    = renderTarget.getPixelFormat().redBits > 0 && renderTarget.getPixelFormat().greenBits > 0 && renderTarget.getPixelFormat().blueBits > 0;
1877                 bool                                            targetHasAlpha  = renderTarget.getPixelFormat().alphaBits > 0;
1878                 tcu::TextureFormat                      fmt                             = mapGLUnsizedInternalFormat(m_internalFormat);
1879                 bool                                            texHasRGB               = fmt.order != tcu::TextureFormat::A;
1880                 bool                                            texHasAlpha             = fmt.order == tcu::TextureFormat::RGBA || fmt.order == tcu::TextureFormat::LA || fmt.order == tcu::TextureFormat::A;
1881                 deUint32                                        tex                             = 0;
1882                 de::Random                                      rnd                             (deStringHash(getName()));
1883                 GradientShader                          shader                  (glu::TYPE_FLOAT_VEC4);
1884                 deUint32                                        shaderID                = getCurrentContext()->createProgram(&shader);
1885
1886                 if ((texHasRGB && !targetHasRGB) || (texHasAlpha && !targetHasAlpha))
1887                         throw tcu::NotSupportedError("Copying from current framebuffer is not supported", "", __FILE__, __LINE__);
1888
1889                 // Fill render target with gradient.
1890                 shader.setGradient(*getCurrentContext(), shaderID, Vec4(0.0f), Vec4(1.0f));
1891                 sglr::drawQuad(*getCurrentContext(), shaderID, tcu::Vec3(-1.0f, -1.0f, 0.0f), tcu::Vec3(1.0f, 1.0f, 0.0f));
1892
1893                 glGenTextures(1, &tex);
1894                 glBindTexture(GL_TEXTURE_2D, tex);
1895
1896                 for (int ndx = 0; ndx < m_numLevels; ndx++)
1897                 {
1898                         int             levelW          = de::max(1, m_width >> ndx);
1899                         int             levelH          = de::max(1, m_height >> ndx);
1900                         int             x                       = rnd.getInt(0, getWidth()      - levelW);
1901                         int             y                       = rnd.getInt(0, getHeight()     - levelH);
1902
1903                         glCopyTexImage2D(GL_TEXTURE_2D, ndx, m_internalFormat, x, y, levelW, levelH, 0);
1904                 }
1905         }
1906
1907         deUint32 m_internalFormat;
1908 };
1909
1910 // Basic CopyTexImage2D() with cubemap usage
1911 class BasicCopyTexImageCubeCase : public TextureCubeSpecCase
1912 {
1913 public:
1914         BasicCopyTexImageCubeCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int size)
1915                 : TextureCubeSpecCase   (context, name, desc, glu::mapGLTransferFormat(internalFormat, GL_UNSIGNED_BYTE), size, deLog2Floor32(size)+1)
1916                 , m_internalFormat              (internalFormat)
1917         {
1918         }
1919
1920 protected:
1921         void createTexture (void)
1922         {
1923                 const tcu::RenderTarget&        renderTarget    = TestCase::m_context.getRenderContext().getRenderTarget();
1924                 bool                                            targetHasRGB    = renderTarget.getPixelFormat().redBits > 0 && renderTarget.getPixelFormat().greenBits > 0 && renderTarget.getPixelFormat().blueBits > 0;
1925                 bool                                            targetHasAlpha  = renderTarget.getPixelFormat().alphaBits > 0;
1926                 tcu::TextureFormat                      fmt                             = mapGLUnsizedInternalFormat(m_internalFormat);
1927                 bool                                            texHasRGB               = fmt.order != tcu::TextureFormat::A;
1928                 bool                                            texHasAlpha             = fmt.order == tcu::TextureFormat::RGBA || fmt.order == tcu::TextureFormat::LA || fmt.order == tcu::TextureFormat::A;
1929                 deUint32                                        tex                             = 0;
1930                 de::Random                                      rnd                             (deStringHash(getName()));
1931                 GradientShader                          shader                  (glu::TYPE_FLOAT_VEC4);
1932                 deUint32                                        shaderID                = getCurrentContext()->createProgram(&shader);
1933
1934                 if ((texHasRGB && !targetHasRGB) || (texHasAlpha && !targetHasAlpha))
1935                         throw tcu::NotSupportedError("Copying from current framebuffer is not supported", "", __FILE__, __LINE__);
1936
1937                 // Fill render target with gradient.
1938                 shader.setGradient(*getCurrentContext(), shaderID, Vec4(0.0f), Vec4(1.0f));
1939                 sglr::drawQuad(*getCurrentContext(), shaderID, tcu::Vec3(-1.0f, -1.0f, 0.0f), tcu::Vec3(1.0f, 1.0f, 0.0f));
1940
1941                 glGenTextures(1, &tex);
1942                 glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
1943
1944                 for (int ndx = 0; ndx < m_numLevels; ndx++)
1945                 {
1946                         int levelSize = de::max(1, m_size >> ndx);
1947
1948                         for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
1949                         {
1950                                 int x = rnd.getInt(0, getWidth()        - levelSize);
1951                                 int y = rnd.getInt(0, getHeight()       - levelSize);
1952
1953                                 glCopyTexImage2D(s_cubeMapFaces[face], ndx, m_internalFormat, x, y, levelSize, levelSize, 0);
1954                         }
1955                 }
1956         }
1957
1958         deUint32 m_internalFormat;
1959 };
1960
1961 // Basic CopyTexSubImage2D() with 2D texture usage
1962 class BasicCopyTexSubImage2DCase : public Texture2DSpecCase
1963 {
1964 public:
1965         BasicCopyTexSubImage2DCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int width, int height)
1966                 : Texture2DSpecCase     (context, name, desc, glu::mapGLTransferFormat(format, dataType), width, height, maxLevelCount(width, height))
1967                 , m_format                      (format)
1968                 , m_dataType            (dataType)
1969         {
1970         }
1971
1972 protected:
1973         void createTexture (void)
1974         {
1975                 const tcu::RenderTarget&        renderTarget    = TestCase::m_context.getRenderContext().getRenderTarget();
1976                 bool                                            targetHasRGB    = renderTarget.getPixelFormat().redBits > 0 && renderTarget.getPixelFormat().greenBits > 0 && renderTarget.getPixelFormat().blueBits > 0;
1977                 bool                                            targetHasAlpha  = renderTarget.getPixelFormat().alphaBits > 0;
1978                 tcu::TextureFormat                      fmt                             = glu::mapGLTransferFormat(m_format, m_dataType);
1979                 bool                                            texHasRGB               = fmt.order != tcu::TextureFormat::A;
1980                 bool                                            texHasAlpha             = fmt.order == tcu::TextureFormat::RGBA || fmt.order == tcu::TextureFormat::LA || fmt.order == tcu::TextureFormat::A;
1981                 deUint32                                        tex                             = 0;
1982                 tcu::TextureLevel                       data                    (fmt);
1983                 de::Random                                      rnd                             (deStringHash(getName()));
1984                 GradientShader                          shader                  (glu::TYPE_FLOAT_VEC4);
1985                 deUint32                                        shaderID                = getCurrentContext()->createProgram(&shader);
1986
1987                 if ((texHasRGB && !targetHasRGB) || (texHasAlpha && !targetHasAlpha))
1988                         throw tcu::NotSupportedError("Copying from current framebuffer is not supported", "", __FILE__, __LINE__);
1989
1990                 glGenTextures(1, &tex);
1991                 glBindTexture(GL_TEXTURE_2D, tex);
1992                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1993
1994                 // First specify full texture.
1995                 for (int ndx = 0; ndx < m_numLevels; ndx++)
1996                 {
1997                         int             levelW          = de::max(1, m_width >> ndx);
1998                         int             levelH          = de::max(1, m_height >> ndx);
1999
2000                         Vec4    colorA          = randomVector<4>(rnd);
2001                         Vec4    colorB          = randomVector<4>(rnd);
2002                         int             cellSize        = rnd.getInt(2, 16);
2003
2004                         data.setSize(levelW, levelH);
2005                         tcu::fillWithGrid(data.getAccess(), cellSize, colorA, colorB);
2006
2007                         glTexImage2D(GL_TEXTURE_2D, ndx, m_format, levelW, levelH, 0, m_format, m_dataType, data.getAccess().getDataPtr());
2008                 }
2009
2010                 // Fill render target with gradient.
2011                 shader.setGradient(*getCurrentContext(), shaderID, Vec4(0.0f), Vec4(1.0f));
2012                 sglr::drawQuad(*getCurrentContext(), shaderID, tcu::Vec3(-1.0f, -1.0f, 0.0f), tcu::Vec3(1.0f, 1.0f, 0.0f));
2013
2014                 // Re-specify parts of each level.
2015                 for (int ndx = 0; ndx < m_numLevels; ndx++)
2016                 {
2017                         int             levelW          = de::max(1, m_width >> ndx);
2018                         int             levelH          = de::max(1, m_height >> ndx);
2019
2020                         int             w                       = rnd.getInt(1, levelW);
2021                         int             h                       = rnd.getInt(1, levelH);
2022                         int             xo                      = rnd.getInt(0, levelW-w);
2023                         int             yo                      = rnd.getInt(0, levelH-h);
2024
2025                         int             x                       = rnd.getInt(0, getWidth() - w);
2026                         int             y                       = rnd.getInt(0, getHeight() - h);
2027
2028                         glCopyTexSubImage2D(GL_TEXTURE_2D, ndx, xo, yo, x, y, w, h);
2029                 }
2030         }
2031
2032         deUint32        m_format;
2033         deUint32        m_dataType;
2034 };
2035
2036 // Basic CopyTexSubImage2D() with cubemap usage
2037 class BasicCopyTexSubImageCubeCase : public TextureCubeSpecCase
2038 {
2039 public:
2040         BasicCopyTexSubImageCubeCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int size)
2041                 : TextureCubeSpecCase   (context, name, desc, glu::mapGLTransferFormat(format, dataType), size, deLog2Floor32(size)+1)
2042                 , m_format                              (format)
2043                 , m_dataType                    (dataType)
2044         {
2045         }
2046
2047 protected:
2048         void createTexture (void)
2049         {
2050                 const tcu::RenderTarget&        renderTarget    = TestCase::m_context.getRenderContext().getRenderTarget();
2051                 bool                                            targetHasRGB    = renderTarget.getPixelFormat().redBits > 0 && renderTarget.getPixelFormat().greenBits > 0 && renderTarget.getPixelFormat().blueBits > 0;
2052                 bool                                            targetHasAlpha  = renderTarget.getPixelFormat().alphaBits > 0;
2053                 tcu::TextureFormat                      fmt                             = glu::mapGLTransferFormat(m_format, m_dataType);
2054                 bool                                            texHasRGB               = fmt.order != tcu::TextureFormat::A;
2055                 bool                                            texHasAlpha             = fmt.order == tcu::TextureFormat::RGBA || fmt.order == tcu::TextureFormat::LA || fmt.order == tcu::TextureFormat::A;
2056                 deUint32                                        tex                             = 0;
2057                 tcu::TextureLevel                       data                    (fmt);
2058                 de::Random                                      rnd                             (deStringHash(getName()));
2059                 GradientShader                          shader                  (glu::TYPE_FLOAT_VEC4);
2060                 deUint32                                        shaderID                = getCurrentContext()->createProgram(&shader);
2061
2062                 if ((texHasRGB && !targetHasRGB) || (texHasAlpha && !targetHasAlpha))
2063                         throw tcu::NotSupportedError("Copying from current framebuffer is not supported", "", __FILE__, __LINE__);
2064
2065                 glGenTextures(1, &tex);
2066                 glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
2067                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2068
2069                 for (int ndx = 0; ndx < m_numLevels; ndx++)
2070                 {
2071                         int levelSize = de::max(1, m_size >> ndx);
2072
2073                         data.setSize(levelSize, levelSize);
2074
2075                         for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
2076                         {
2077                                 Vec4    colorA          = randomVector<4>(rnd);
2078                                 Vec4    colorB          = randomVector<4>(rnd);
2079                                 int             cellSize        = rnd.getInt(2, 16);
2080
2081                                 tcu::fillWithGrid(data.getAccess(), cellSize, colorA, colorB);
2082                                 glTexImage2D(s_cubeMapFaces[face], ndx, m_format, levelSize, levelSize, 0, m_format, m_dataType, data.getAccess().getDataPtr());
2083                         }
2084                 }
2085
2086                 // Fill render target with gradient.
2087                 shader.setGradient(*getCurrentContext(), shaderID, Vec4(0.0f), Vec4(1.0f));
2088                 sglr::drawQuad(*getCurrentContext(), shaderID, tcu::Vec3(-1.0f, -1.0f, 0.0f), tcu::Vec3(1.0f, 1.0f, 0.0f));
2089
2090                 // Re-specify parts of each face and level.
2091                 for (int ndx = 0; ndx < m_numLevels; ndx++)
2092                 {
2093                         int levelSize = de::max(1, m_size >> ndx);
2094
2095                         for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
2096                         {
2097                                 int             w                       = rnd.getInt(1, levelSize);
2098                                 int             h                       = rnd.getInt(1, levelSize);
2099                                 int             xo                      = rnd.getInt(0, levelSize-w);
2100                                 int             yo                      = rnd.getInt(0, levelSize-h);
2101
2102                                 int             x                       = rnd.getInt(0, getWidth() - w);
2103                                 int             y                       = rnd.getInt(0, getHeight() - h);
2104
2105                                 glCopyTexSubImage2D(s_cubeMapFaces[face], ndx, xo, yo, x, y, w, h);
2106                         }
2107                 }
2108         }
2109
2110         deUint32        m_format;
2111         deUint32        m_dataType;
2112 };
2113
2114 // Basic glTexStorage2D() with 2D texture usage
2115 class BasicTexStorage2DCase : public Texture2DSpecCase
2116 {
2117 public:
2118         BasicTexStorage2DCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height, int numLevels)
2119                 : Texture2DSpecCase     (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, numLevels)
2120                 , m_internalFormat      (internalFormat)
2121         {
2122         }
2123
2124 protected:
2125         void createTexture (void)
2126         {
2127                 tcu::TextureFormat              fmt                             = glu::mapGLInternalFormat(m_internalFormat);
2128                 glu::TransferFormat             transferFmt             = glu::getTransferFormat(fmt);
2129                 deUint32                                tex                             = 0;
2130                 tcu::TextureLevel               levelData               (glu::mapGLTransferFormat(transferFmt.format, transferFmt.dataType));
2131                 de::Random                              rnd                             (deStringHash(getName()));
2132
2133                 glGenTextures(1, &tex);
2134                 glBindTexture(GL_TEXTURE_2D, tex);
2135                 glTexStorage2D(GL_TEXTURE_2D, m_numLevels, m_internalFormat, m_width, m_height);
2136
2137                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2138
2139                 for (int ndx = 0; ndx < m_numLevels; ndx++)
2140                 {
2141                         int             levelW          = de::max(1, m_width >> ndx);
2142                         int             levelH          = de::max(1, m_height >> ndx);
2143                         Vec4    gMin            = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
2144                         Vec4    gMax            = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
2145
2146                         levelData.setSize(levelW, levelH);
2147                         tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
2148
2149                         glTexSubImage2D(GL_TEXTURE_2D, ndx, 0, 0, levelW, levelH, transferFmt.format, transferFmt.dataType, levelData.getAccess().getDataPtr());
2150                 }
2151         }
2152
2153         deUint32 m_internalFormat;
2154 };
2155
2156 // Basic glTexStorage2D() with cubemap usage
2157 class BasicTexStorageCubeCase : public TextureCubeSpecCase
2158 {
2159 public:
2160         BasicTexStorageCubeCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int size, int numLevels)
2161                 : TextureCubeSpecCase   (context, name, desc, glu::mapGLInternalFormat(internalFormat), size, numLevels)
2162                 , m_internalFormat              (internalFormat)
2163         {
2164         }
2165
2166 protected:
2167         void createTexture (void)
2168         {
2169                 tcu::TextureFormat              fmt                             = glu::mapGLInternalFormat(m_internalFormat);
2170                 glu::TransferFormat             transferFmt             = glu::getTransferFormat(fmt);
2171                 deUint32                                tex                             = 0;
2172                 tcu::TextureLevel               levelData               (glu::mapGLTransferFormat(transferFmt.format, transferFmt.dataType));
2173                 de::Random                              rnd                             (deStringHash(getName()));
2174
2175                 glGenTextures(1, &tex);
2176                 glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
2177                 glTexStorage2D(GL_TEXTURE_CUBE_MAP, m_numLevels, m_internalFormat, m_size, m_size);
2178
2179                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2180
2181                 for (int ndx = 0; ndx < m_numLevels; ndx++)
2182                 {
2183                         int levelSize = de::max(1, m_size >> ndx);
2184
2185                         levelData.setSize(levelSize, levelSize);
2186
2187                         for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
2188                         {
2189                                 Vec4 gMin = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
2190                                 Vec4 gMax = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
2191
2192                                 tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
2193
2194                                 glTexSubImage2D(s_cubeMapFaces[face], ndx, 0, 0, levelSize, levelSize, transferFmt.format, transferFmt.dataType, levelData.getAccess().getDataPtr());
2195                         }
2196                 }
2197         }
2198
2199         deUint32 m_internalFormat;
2200 };
2201
2202 // Basic glTexStorage3D() with 2D array texture usage
2203 class BasicTexStorage2DArrayCase : public Texture2DArraySpecCase
2204 {
2205 public:
2206         BasicTexStorage2DArrayCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height, int numLayers, int numLevels)
2207                 : Texture2DArraySpecCase        (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, numLayers, numLevels)
2208                 , m_internalFormat                      (internalFormat)
2209         {
2210         }
2211
2212 protected:
2213         void createTexture (void)
2214         {
2215                 deUint32                                tex                     = 0;
2216                 de::Random                              rnd                     (deStringHash(getName()));
2217                 glu::TransferFormat             transferFmt     = glu::getTransferFormat(m_texFormat);
2218                 tcu::TextureLevel               levelData       (glu::mapGLTransferFormat(transferFmt.format, transferFmt.dataType));
2219
2220                 glGenTextures   (1, &tex);
2221                 glBindTexture   (GL_TEXTURE_2D_ARRAY, tex);
2222                 glTexStorage3D  (GL_TEXTURE_2D_ARRAY, m_numLevels, m_internalFormat, m_width, m_height, m_numLayers);
2223
2224                 glPixelStorei   (GL_UNPACK_ALIGNMENT, 1);
2225
2226                 for (int ndx = 0; ndx < m_numLevels; ndx++)
2227                 {
2228                         int             levelW          = de::max(1, m_width    >> ndx);
2229                         int             levelH          = de::max(1, m_height   >> ndx);
2230                         Vec4    gMin            = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
2231                         Vec4    gMax            = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
2232
2233                         levelData.setSize(levelW, levelH, m_numLayers);
2234                         tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
2235
2236                         glTexSubImage3D(GL_TEXTURE_2D_ARRAY, ndx, 0, 0, 0, levelW, levelH, m_numLayers, transferFmt.format, transferFmt.dataType, levelData.getAccess().getDataPtr());
2237                 }
2238         }
2239
2240         deUint32 m_internalFormat;
2241 };
2242
2243 // Basic TexStorage3D() with 3D texture usage
2244 class BasicTexStorage3DCase : public Texture3DSpecCase
2245 {
2246 public:
2247         BasicTexStorage3DCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height, int depth, int numLevels)
2248                 : Texture3DSpecCase     (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, depth, numLevels)
2249                 , m_internalFormat      (internalFormat)
2250         {
2251         }
2252
2253 protected:
2254         void createTexture (void)
2255         {
2256                 deUint32                                tex                     = 0;
2257                 de::Random                              rnd                     (deStringHash(getName()));
2258                 glu::TransferFormat             transferFmt     = glu::getTransferFormat(m_texFormat);
2259                 tcu::TextureLevel               levelData       (glu::mapGLTransferFormat(transferFmt.format, transferFmt.dataType));
2260
2261                 glGenTextures   (1, &tex);
2262                 glBindTexture   (GL_TEXTURE_3D, tex);
2263                 glTexStorage3D  (GL_TEXTURE_3D, m_numLevels, m_internalFormat, m_width, m_height, m_depth);
2264
2265                 glPixelStorei   (GL_UNPACK_ALIGNMENT, 1);
2266
2267                 for (int ndx = 0; ndx < m_numLevels; ndx++)
2268                 {
2269                         int             levelW          = de::max(1, m_width    >> ndx);
2270                         int             levelH          = de::max(1, m_height   >> ndx);
2271                         int             levelD          = de::max(1, m_depth    >> ndx);
2272                         Vec4    gMin            = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
2273                         Vec4    gMax            = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
2274
2275                         levelData.setSize(levelW, levelH, levelD);
2276                         tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
2277
2278                         glTexSubImage3D(GL_TEXTURE_3D, ndx, 0, 0, 0, levelW, levelH, levelD, transferFmt.format, transferFmt.dataType, levelData.getAccess().getDataPtr());
2279                 }
2280         }
2281
2282         deUint32 m_internalFormat;
2283 };
2284
2285 // Pixel buffer object cases.
2286
2287 // TexImage2D() from pixel buffer object.
2288 class TexImage2DBufferCase : public Texture2DSpecCase
2289 {
2290 public:
2291         TexImage2DBufferCase (Context&          context,
2292                                                   const char*   name,
2293                                                   const char*   desc,
2294                                                   deUint32              internalFormat,
2295                                                   int                   width,
2296                                                   int                   height,
2297                                                   int                   rowLength,
2298                                                   int                   skipRows,
2299                                                   int                   skipPixels,
2300                                                   int                   alignment,
2301                                                   int                   offset)
2302                 : Texture2DSpecCase     (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, 1)
2303                 , m_internalFormat      (internalFormat)
2304                 , m_rowLength           (rowLength)
2305                 , m_skipRows            (skipRows)
2306                 , m_skipPixels          (skipPixels)
2307                 , m_alignment           (alignment)
2308                 , m_offset                      (offset)
2309         {
2310         }
2311
2312 protected:
2313         void createTexture (void)
2314         {
2315                 glu::TransferFormat             transferFmt             = glu::getTransferFormat(m_texFormat);
2316                 int                                             pixelSize               = m_texFormat.getPixelSize();
2317                 int                                             rowLength               = m_rowLength > 0 ? m_rowLength : m_width + m_skipPixels;
2318                 int                                             rowPitch                = deAlign32(rowLength*pixelSize, m_alignment);
2319                 int                                             height                  = m_height + m_skipRows;
2320                 deUint32                                buf                             = 0;
2321                 deUint32                                tex                             = 0;
2322                 vector<deUint8>                 data;
2323
2324                 DE_ASSERT(m_numLevels == 1);
2325
2326                 // Fill data with grid.
2327                 data.resize(rowPitch*height + m_offset);
2328                 {
2329                         Vec4    cScale          = m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
2330                         Vec4    cBias           = m_texFormatInfo.valueMin;
2331                         Vec4    colorA          = Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
2332                         Vec4    colorB          = Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
2333
2334                         tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, 1, rowPitch, 0, &data[0] + m_skipRows*rowPitch + m_skipPixels*pixelSize + m_offset), 4, colorA, colorB);
2335                 }
2336
2337                 // Create buffer and upload.
2338                 glGenBuffers(1, &buf);
2339                 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf);
2340                 glBufferData(GL_PIXEL_UNPACK_BUFFER, (int)data.size(), &data[0], GL_STATIC_DRAW);
2341
2342                 glPixelStorei(GL_UNPACK_ROW_LENGTH,             m_rowLength);
2343                 glPixelStorei(GL_UNPACK_SKIP_ROWS,              m_skipRows);
2344                 glPixelStorei(GL_UNPACK_SKIP_PIXELS,    m_skipPixels);
2345                 glPixelStorei(GL_UNPACK_ALIGNMENT,              m_alignment);
2346
2347                 glGenTextures(1, &tex);
2348                 glBindTexture(GL_TEXTURE_2D, tex);
2349                 glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_width, m_height, 0, transferFmt.format, transferFmt.dataType, (const void*)(deUintptr)m_offset);
2350         }
2351
2352         deUint32        m_internalFormat;
2353         int                     m_rowLength;
2354         int                     m_skipRows;
2355         int                     m_skipPixels;
2356         int                     m_alignment;
2357         int                     m_offset;
2358 };
2359
2360 // TexImage2D() cubemap from pixel buffer object case
2361 class TexImageCubeBufferCase : public TextureCubeSpecCase
2362 {
2363 public:
2364         TexImageCubeBufferCase (Context&        context,
2365                                                         const char*     name,
2366                                                         const char*     desc,
2367                                                         deUint32        internalFormat,
2368                                                         int                     size,
2369                                                         int                     rowLength,
2370                                                         int                     skipRows,
2371                                                         int                     skipPixels,
2372                                                         int                     alignment,
2373                                                         int                     offset)
2374                 : TextureCubeSpecCase   (context, name, desc, glu::mapGLInternalFormat(internalFormat), size, 1)
2375                 , m_internalFormat              (internalFormat)
2376                 , m_rowLength                   (rowLength)
2377                 , m_skipRows                    (skipRows)
2378                 , m_skipPixels                  (skipPixels)
2379                 , m_alignment                   (alignment)
2380                 , m_offset                              (offset)
2381         {
2382         }
2383
2384 protected:
2385         void createTexture (void)
2386         {
2387                 de::Random                                      rnd                     (deStringHash(getName()));
2388                 deUint32                                        tex                     = 0;
2389                 glu::TransferFormat                     fmt                     = glu::getTransferFormat(m_texFormat);
2390                 const int                                       pixelSize       = m_texFormat.getPixelSize();
2391                 const int                                       rowLength       = m_rowLength > 0 ? m_rowLength : m_size + m_skipPixels;
2392                 const int                                       rowPitch        = deAlign32(rowLength*pixelSize, m_alignment);
2393                 const int                                       height          = m_size + m_skipRows;
2394                 vector<vector<deUint8> >        data            (DE_LENGTH_OF_ARRAY(s_cubeMapFaces));
2395
2396                 DE_ASSERT(m_numLevels == 1);
2397
2398                 glGenTextures(1, &tex);
2399                 glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
2400                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2401
2402                 for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
2403                 {
2404                         deUint32 buf = 0;
2405
2406                         {
2407                                 const Vec4 gMin = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
2408                                 const Vec4 gMax = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
2409
2410                                 data[face].resize(rowPitch*height + m_offset);
2411                                 tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_size, m_size, 1, rowPitch, 0, &data[face][0] + m_skipRows*rowPitch + m_skipPixels*pixelSize + m_offset), gMin, gMax);
2412                         }
2413
2414                         // Create buffer and upload.
2415                         glGenBuffers(1, &buf);
2416                         glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf);
2417                         glBufferData(GL_PIXEL_UNPACK_BUFFER, (int)data[face].size(), &data[face][0], GL_STATIC_DRAW);
2418
2419                         glPixelStorei(GL_UNPACK_ROW_LENGTH,             m_rowLength);
2420                         glPixelStorei(GL_UNPACK_SKIP_ROWS,              m_skipRows);
2421                         glPixelStorei(GL_UNPACK_SKIP_PIXELS,    m_skipPixels);
2422                         glPixelStorei(GL_UNPACK_ALIGNMENT,              m_alignment);
2423
2424                         glTexImage2D(s_cubeMapFaces[face], 0, m_internalFormat, m_size, m_size, 0, fmt.format, fmt.dataType, (const void*)(deUintptr)m_offset);
2425                 }
2426         }
2427
2428         deUint32        m_internalFormat;
2429         int                     m_rowLength;
2430         int                     m_skipRows;
2431         int                     m_skipPixels;
2432         int                     m_alignment;
2433         int                     m_offset;
2434 };
2435
2436 // TexImage3D() 2D array from pixel buffer object.
2437 class TexImage2DArrayBufferCase : public Texture2DArraySpecCase
2438 {
2439 public:
2440         TexImage2DArrayBufferCase (Context&             context,
2441                                                            const char*  name,
2442                                                            const char*  desc,
2443                                                            deUint32             internalFormat,
2444                                                            int                  width,
2445                                                            int                  height,
2446                                                            int                  depth,
2447                                                            int                  imageHeight,
2448                                                            int                  rowLength,
2449                                                            int                  skipImages,
2450                                                            int                  skipRows,
2451                                                            int                  skipPixels,
2452                                                            int                  alignment,
2453                                                            int                  offset)
2454                 : Texture2DArraySpecCase        (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, depth, 1)
2455                 , m_internalFormat                      (internalFormat)
2456                 , m_imageHeight                         (imageHeight)
2457                 , m_rowLength                           (rowLength)
2458                 , m_skipImages                          (skipImages)
2459                 , m_skipRows                            (skipRows)
2460                 , m_skipPixels                          (skipPixels)
2461                 , m_alignment                           (alignment)
2462                 , m_offset                                      (offset)
2463         {
2464         }
2465
2466 protected:
2467         void createTexture (void)
2468         {
2469                 glu::TransferFormat             transferFmt             = glu::getTransferFormat(m_texFormat);
2470                 int                                             pixelSize               = m_texFormat.getPixelSize();
2471                 int                                             rowLength               = m_rowLength > 0 ? m_rowLength : m_width;
2472                 int                                             rowPitch                = deAlign32(rowLength*pixelSize, m_alignment);
2473                 int                                             imageHeight             = m_imageHeight > 0 ? m_imageHeight : m_height;
2474                 int                                             slicePitch              = imageHeight*rowPitch;
2475                 deUint32                                tex                             = 0;
2476                 deUint32                                buf                             = 0;
2477                 vector<deUint8>                 data;
2478
2479                 DE_ASSERT(m_numLevels == 1);
2480
2481                 // Fill data with grid.
2482                 data.resize(slicePitch*(m_numLayers+m_skipImages) + m_offset);
2483                 {
2484                         Vec4    cScale          = m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
2485                         Vec4    cBias           = m_texFormatInfo.valueMin;
2486                         Vec4    colorA          = Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
2487                         Vec4    colorB          = Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
2488
2489                         tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, m_numLayers, rowPitch, slicePitch, &data[0] + m_skipImages*slicePitch + m_skipRows*rowPitch + m_skipPixels*pixelSize + m_offset), 4, colorA, colorB);
2490                 }
2491
2492                 glGenBuffers(1, &buf);
2493                 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf);
2494                 glBufferData(GL_PIXEL_UNPACK_BUFFER, (int)data.size(), &data[0], GL_STATIC_DRAW);
2495
2496                 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT,   m_imageHeight);
2497                 glPixelStorei(GL_UNPACK_ROW_LENGTH,             m_rowLength);
2498                 glPixelStorei(GL_UNPACK_SKIP_IMAGES,    m_skipImages);
2499                 glPixelStorei(GL_UNPACK_SKIP_ROWS,              m_skipRows);
2500                 glPixelStorei(GL_UNPACK_SKIP_PIXELS,    m_skipPixels);
2501                 glPixelStorei(GL_UNPACK_ALIGNMENT,              m_alignment);
2502
2503                 glGenTextures(1, &tex);
2504                 glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
2505                 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, m_internalFormat, m_width, m_height, m_numLayers, 0, transferFmt.format, transferFmt.dataType, (const void*)(deUintptr)m_offset);
2506         }
2507
2508         deUint32        m_internalFormat;
2509         int                     m_imageHeight;
2510         int                     m_rowLength;
2511         int                     m_skipImages;
2512         int                     m_skipRows;
2513         int                     m_skipPixels;
2514         int                     m_alignment;
2515         int                     m_offset;
2516 };
2517
2518 // TexImage3D() from pixel buffer object.
2519 class TexImage3DBufferCase : public Texture3DSpecCase
2520 {
2521 public:
2522         TexImage3DBufferCase (Context&          context,
2523                                                   const char*   name,
2524                                                   const char*   desc,
2525                                                   deUint32              internalFormat,
2526                                                   int                   width,
2527                                                   int                   height,
2528                                                   int                   depth,
2529                                                   int                   imageHeight,
2530                                                   int                   rowLength,
2531                                                   int                   skipImages,
2532                                                   int                   skipRows,
2533                                                   int                   skipPixels,
2534                                                   int                   alignment,
2535                                                   int                   offset)
2536                 : Texture3DSpecCase     (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, depth, 1)
2537                 , m_internalFormat      (internalFormat)
2538                 , m_imageHeight         (imageHeight)
2539                 , m_rowLength           (rowLength)
2540                 , m_skipImages          (skipImages)
2541                 , m_skipRows            (skipRows)
2542                 , m_skipPixels          (skipPixels)
2543                 , m_alignment           (alignment)
2544                 , m_offset                      (offset)
2545         {
2546         }
2547
2548 protected:
2549         void createTexture (void)
2550         {
2551                 glu::TransferFormat             transferFmt             = glu::getTransferFormat(m_texFormat);
2552                 int                                             pixelSize               = m_texFormat.getPixelSize();
2553                 int                                             rowLength               = m_rowLength > 0 ? m_rowLength : m_width;
2554                 int                                             rowPitch                = deAlign32(rowLength*pixelSize, m_alignment);
2555                 int                                             imageHeight             = m_imageHeight > 0 ? m_imageHeight : m_height;
2556                 int                                             slicePitch              = imageHeight*rowPitch;
2557                 deUint32                                tex                             = 0;
2558                 deUint32                                buf                             = 0;
2559                 vector<deUint8>                 data;
2560
2561                 DE_ASSERT(m_numLevels == 1);
2562
2563                 // Fill data with grid.
2564                 data.resize(slicePitch*(m_depth+m_skipImages) + m_offset);
2565                 {
2566                         Vec4    cScale          = m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
2567                         Vec4    cBias           = m_texFormatInfo.valueMin;
2568                         Vec4    colorA          = Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
2569                         Vec4    colorB          = Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
2570
2571                         tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, m_depth, rowPitch, slicePitch, &data[0] + m_skipImages*slicePitch + m_skipRows*rowPitch + m_skipPixels*pixelSize + m_offset), 4, colorA, colorB);
2572                 }
2573
2574                 glGenBuffers(1, &buf);
2575                 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf);
2576                 glBufferData(GL_PIXEL_UNPACK_BUFFER, (int)data.size(), &data[0], GL_STATIC_DRAW);
2577
2578                 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT,   m_imageHeight);
2579                 glPixelStorei(GL_UNPACK_ROW_LENGTH,             m_rowLength);
2580                 glPixelStorei(GL_UNPACK_SKIP_IMAGES,    m_skipImages);
2581                 glPixelStorei(GL_UNPACK_SKIP_ROWS,              m_skipRows);
2582                 glPixelStorei(GL_UNPACK_SKIP_PIXELS,    m_skipPixels);
2583                 glPixelStorei(GL_UNPACK_ALIGNMENT,              m_alignment);
2584
2585                 glGenTextures(1, &tex);
2586                 glBindTexture(GL_TEXTURE_3D, tex);
2587                 glTexImage3D(GL_TEXTURE_3D, 0, m_internalFormat, m_width, m_height, m_depth, 0, transferFmt.format, transferFmt.dataType, (const void*)(deUintptr)m_offset);
2588         }
2589
2590         deUint32        m_internalFormat;
2591         int                     m_imageHeight;
2592         int                     m_rowLength;
2593         int                     m_skipImages;
2594         int                     m_skipRows;
2595         int                     m_skipPixels;
2596         int                     m_alignment;
2597         int                     m_offset;
2598 };
2599
2600 // TexSubImage2D() PBO case.
2601 class TexSubImage2DBufferCase : public Texture2DSpecCase
2602 {
2603 public:
2604         TexSubImage2DBufferCase (Context&               context,
2605                                                          const char*    name,
2606                                                          const char*    desc,
2607                                                          deUint32               internalFormat,
2608                                                          int                    width,
2609                                                          int                    height,
2610                                                          int                    subX,
2611                                                          int                    subY,
2612                                                          int                    subW,
2613                                                          int                    subH,
2614                                                          int                    rowLength,
2615                                                          int                    skipRows,
2616                                                          int                    skipPixels,
2617                                                          int                    alignment,
2618                                                          int                    offset)
2619                 : Texture2DSpecCase     (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, 1)
2620                 , m_internalFormat      (internalFormat)
2621                 , m_subX                        (subX)
2622                 , m_subY                        (subY)
2623                 , m_subW                        (subW)
2624                 , m_subH                        (subH)
2625                 , m_rowLength           (rowLength)
2626                 , m_skipRows            (skipRows)
2627                 , m_skipPixels          (skipPixels)
2628                 , m_alignment           (alignment)
2629                 , m_offset                      (offset)
2630         {
2631         }
2632
2633 protected:
2634         void createTexture (void)
2635         {
2636                 glu::TransferFormat             transferFmt             = glu::getTransferFormat(m_texFormat);
2637                 int                                             pixelSize               = m_texFormat.getPixelSize();
2638                 deUint32                                tex                             = 0;
2639                 deUint32                                buf                             = 0;
2640                 vector<deUint8>                 data;
2641
2642                 DE_ASSERT(m_numLevels == 1);
2643
2644                 glGenTextures(1, &tex);
2645                 glBindTexture(GL_TEXTURE_2D, tex);
2646
2647                 // First fill texture with gradient.
2648                 data.resize(deAlign32(m_width*pixelSize, 4)*m_height);
2649                 tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, 1, deAlign32(m_width*pixelSize, 4), 0, &data[0]), m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
2650                 glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_width, m_height, 0, transferFmt.format, transferFmt.dataType, &data[0]);
2651
2652                 // Fill data with grid.
2653                 {
2654                         int             rowLength       = m_rowLength > 0 ? m_rowLength : m_subW;
2655                         int             rowPitch        = deAlign32(rowLength*pixelSize, m_alignment);
2656                         int             height          = m_subH + m_skipRows;
2657                         Vec4    cScale          = m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
2658                         Vec4    cBias           = m_texFormatInfo.valueMin;
2659                         Vec4    colorA          = Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
2660                         Vec4    colorB          = Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
2661
2662                         data.resize(rowPitch*height + m_offset);
2663                         tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, m_subW, m_subH, 1, rowPitch, 0, &data[0] + m_skipRows*rowPitch + m_skipPixels*pixelSize + m_offset), 4, colorA, colorB);
2664                 }
2665
2666                 glGenBuffers(1, &buf);
2667                 glBindBuffer(GL_PIXEL_UNPACK_BUFFER,    buf);
2668                 glBufferData(GL_PIXEL_UNPACK_BUFFER,    (int)data.size(), &data[0], GL_STATIC_DRAW);
2669
2670                 glPixelStorei(GL_UNPACK_ROW_LENGTH,             m_rowLength);
2671                 glPixelStorei(GL_UNPACK_SKIP_ROWS,              m_skipRows);
2672                 glPixelStorei(GL_UNPACK_SKIP_PIXELS,    m_skipPixels);
2673                 glPixelStorei(GL_UNPACK_ALIGNMENT,              m_alignment);
2674                 glTexSubImage2D(GL_TEXTURE_2D, 0, m_subX, m_subY, m_subW, m_subH, transferFmt.format, transferFmt.dataType, (const void*)(deUintptr)m_offset);
2675         }
2676
2677         deUint32        m_internalFormat;
2678         int                     m_subX;
2679         int                     m_subY;
2680         int                     m_subW;
2681         int                     m_subH;
2682         int                     m_rowLength;
2683         int                     m_skipRows;
2684         int                     m_skipPixels;
2685         int                     m_alignment;
2686         int                     m_offset;
2687 };
2688
2689 // TexSubImage2D() cubemap PBO case.
2690 class TexSubImageCubeBufferCase : public TextureCubeSpecCase
2691 {
2692 public:
2693         TexSubImageCubeBufferCase       (Context&               context,
2694                                                                  const char*    name,
2695                                                                  const char*    desc,
2696                                                                  deUint32               internalFormat,
2697                                                                  int                    size,
2698                                                                  int                    subX,
2699                                                                  int                    subY,
2700                                                                  int                    subW,
2701                                                                  int                    subH,
2702                                                                  int                    rowLength,
2703                                                                  int                    skipRows,
2704                                                                  int                    skipPixels,
2705                                                                  int                    alignment,
2706                                                                  int                    offset)
2707                 : TextureCubeSpecCase   (context, name, desc, glu::mapGLInternalFormat(internalFormat), size, 1)
2708                 , m_internalFormat              (internalFormat)
2709                 , m_subX                                (subX)
2710                 , m_subY                                (subY)
2711                 , m_subW                                (subW)
2712                 , m_subH                                (subH)
2713                 , m_rowLength                   (rowLength)
2714                 , m_skipRows                    (skipRows)
2715                 , m_skipPixels                  (skipPixels)
2716                 , m_alignment                   (alignment)
2717                 , m_offset                              (offset)
2718         {
2719         }
2720
2721 protected:
2722         void createTexture (void)
2723         {
2724                 de::Random                              rnd                             (deStringHash(getName()));
2725                 glu::TransferFormat             transferFmt             = glu::getTransferFormat(m_texFormat);
2726                 int                                             pixelSize               = m_texFormat.getPixelSize();
2727                 deUint32                                tex                             = 0;
2728                 deUint32                                buf                             = 0;
2729                 vector<deUint8>                 data;
2730
2731                 DE_ASSERT(m_numLevels == 1);
2732
2733                 glGenTextures(1, &tex);
2734                 glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
2735
2736                 // Fill faces with different gradients.
2737
2738                 data.resize(deAlign32(m_size*pixelSize, 4)*m_size);
2739                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2740
2741                 for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
2742                 {
2743                         const Vec4 gMin = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
2744                         const Vec4 gMax = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
2745
2746                         tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_size, m_size, 1, deAlign32(m_size*pixelSize, 4), 0, &data[0]), gMin, gMax);
2747
2748                         glTexImage2D(s_cubeMapFaces[face], 0, m_internalFormat, m_size, m_size, 0, transferFmt.format, transferFmt.dataType, &data[0]);
2749                 }
2750
2751                 // Fill data with grid.
2752                 {
2753                         int             rowLength       = m_rowLength > 0 ? m_rowLength : m_subW;
2754                         int             rowPitch        = deAlign32(rowLength*pixelSize, m_alignment);
2755                         int             height          = m_subH + m_skipRows;
2756                         Vec4    cScale          = m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
2757                         Vec4    cBias           = m_texFormatInfo.valueMin;
2758                         Vec4    colorA          = Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
2759                         Vec4    colorB          = Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
2760
2761                         data.resize(rowPitch*height + m_offset);
2762                         tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, m_subW, m_subH, 1, rowPitch, 0, &data[0] + m_skipRows*rowPitch + m_skipPixels*pixelSize + m_offset), 4, colorA, colorB);
2763                 }
2764
2765                 glGenBuffers(1, &buf);
2766                 glBindBuffer(GL_PIXEL_UNPACK_BUFFER,    buf);
2767                 glBufferData(GL_PIXEL_UNPACK_BUFFER,    (int)data.size(), &data[0], GL_STATIC_DRAW);
2768
2769                 glPixelStorei(GL_UNPACK_ROW_LENGTH,             m_rowLength);
2770                 glPixelStorei(GL_UNPACK_SKIP_ROWS,              m_skipRows);
2771                 glPixelStorei(GL_UNPACK_SKIP_PIXELS,    m_skipPixels);
2772                 glPixelStorei(GL_UNPACK_ALIGNMENT,              m_alignment);
2773
2774                 for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
2775                         glTexSubImage2D(s_cubeMapFaces[face], 0, m_subX, m_subY, m_subW, m_subH, transferFmt.format, transferFmt.dataType, (const void*)(deUintptr)m_offset);
2776         }
2777
2778         deUint32        m_internalFormat;
2779         int                     m_subX;
2780         int                     m_subY;
2781         int                     m_subW;
2782         int                     m_subH;
2783         int                     m_rowLength;
2784         int                     m_skipRows;
2785         int                     m_skipPixels;
2786         int                     m_alignment;
2787         int                     m_offset;
2788 };
2789
2790 // TexSubImage3D() 2D array PBO case.
2791 class TexSubImage2DArrayBufferCase : public Texture2DArraySpecCase
2792 {
2793 public:
2794         TexSubImage2DArrayBufferCase (Context&          context,
2795                                                                  const char*    name,
2796                                                                  const char*    desc,
2797                                                                  deUint32               internalFormat,
2798                                                                  int                    width,
2799                                                                  int                    height,
2800                                                                  int                    depth,
2801                                                                  int                    subX,
2802                                                                  int                    subY,
2803                                                                  int                    subZ,
2804                                                                  int                    subW,
2805                                                                  int                    subH,
2806                                                                  int                    subD,
2807                                                                  int                    imageHeight,
2808                                                                  int                    rowLength,
2809                                                                  int                    skipImages,
2810                                                                  int                    skipRows,
2811                                                                  int                    skipPixels,
2812                                                                  int                    alignment,
2813                                                                  int                    offset)
2814                 : Texture2DArraySpecCase        (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, depth, 1)
2815                 , m_internalFormat                      (internalFormat)
2816                 , m_subX                                        (subX)
2817                 , m_subY                                        (subY)
2818                 , m_subZ                                        (subZ)
2819                 , m_subW                                        (subW)
2820                 , m_subH                                        (subH)
2821                 , m_subD                                        (subD)
2822                 , m_imageHeight                         (imageHeight)
2823                 , m_rowLength                           (rowLength)
2824                 , m_skipImages                          (skipImages)
2825                 , m_skipRows                            (skipRows)
2826                 , m_skipPixels                          (skipPixels)
2827                 , m_alignment                           (alignment)
2828                 , m_offset                                      (offset)
2829         {
2830         }
2831
2832 protected:
2833         void createTexture (void)
2834         {
2835                 glu::TransferFormat             transferFmt             = glu::getTransferFormat(m_texFormat);
2836                 int                                             pixelSize               = m_texFormat.getPixelSize();
2837                 deUint32                                tex                             = 0;
2838                 deUint32                                buf                             = 0;
2839                 vector<deUint8>                 data;
2840
2841                 DE_ASSERT(m_numLevels == 1);
2842
2843                 glGenTextures(1, &tex);
2844                 glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
2845
2846                 // Fill with gradient.
2847                 {
2848                         int             rowPitch                = deAlign32(pixelSize*m_width,  4);
2849                         int             slicePitch              = rowPitch*m_height;
2850
2851                         data.resize(slicePitch*m_numLayers);
2852                         tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, m_numLayers, rowPitch, slicePitch, &data[0]), m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
2853                 }
2854
2855                 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, m_internalFormat, m_width, m_height, m_numLayers, 0, transferFmt.format, transferFmt.dataType, &data[0]);
2856
2857                 // Fill data with grid.
2858                 {
2859                         int             rowLength               = m_rowLength > 0 ? m_rowLength : m_subW;
2860                         int             rowPitch                = deAlign32(rowLength*pixelSize, m_alignment);
2861                         int             imageHeight             = m_imageHeight > 0 ? m_imageHeight : m_subH;
2862                         int             slicePitch              = imageHeight*rowPitch;
2863                         Vec4    cScale                  = m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
2864                         Vec4    cBias                   = m_texFormatInfo.valueMin;
2865                         Vec4    colorA                  = Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
2866                         Vec4    colorB                  = Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
2867
2868                         data.resize(slicePitch*(m_numLayers+m_skipImages) + m_offset);
2869                         tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, m_subW, m_subH, m_subD, rowPitch, slicePitch, &data[0] + m_skipImages*slicePitch + m_skipRows*rowPitch + m_skipPixels*pixelSize + m_offset), 4, colorA, colorB);
2870                 }
2871
2872                 glGenBuffers(1, &buf);
2873                 glBindBuffer(GL_PIXEL_UNPACK_BUFFER,    buf);
2874                 glBufferData(GL_PIXEL_UNPACK_BUFFER,    (int)data.size(), &data[0], GL_STATIC_DRAW);
2875
2876                 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT,   m_imageHeight);
2877                 glPixelStorei(GL_UNPACK_ROW_LENGTH,             m_rowLength);
2878                 glPixelStorei(GL_UNPACK_SKIP_IMAGES,    m_skipImages);
2879                 glPixelStorei(GL_UNPACK_SKIP_ROWS,              m_skipRows);
2880                 glPixelStorei(GL_UNPACK_SKIP_PIXELS,    m_skipPixels);
2881                 glPixelStorei(GL_UNPACK_ALIGNMENT,              m_alignment);
2882                 glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, m_subX, m_subY, m_subZ, m_subW, m_subH, m_subD, transferFmt.format, transferFmt.dataType, (const void*)(deIntptr)m_offset);
2883         }
2884
2885         deUint32        m_internalFormat;
2886         int                     m_subX;
2887         int                     m_subY;
2888         int                     m_subZ;
2889         int                     m_subW;
2890         int                     m_subH;
2891         int                     m_subD;
2892         int                     m_imageHeight;
2893         int                     m_rowLength;
2894         int                     m_skipImages;
2895         int                     m_skipRows;
2896         int                     m_skipPixels;
2897         int                     m_alignment;
2898         int                     m_offset;
2899 };
2900
2901 // TexSubImage3D() PBO case.
2902 class TexSubImage3DBufferCase : public Texture3DSpecCase
2903 {
2904 public:
2905         TexSubImage3DBufferCase (Context&               context,
2906                                                          const char*    name,
2907                                                          const char*    desc,
2908                                                          deUint32               internalFormat,
2909                                                          int                    width,
2910                                                          int                    height,
2911                                                          int                    depth,
2912                                                          int                    subX,
2913                                                          int                    subY,
2914                                                          int                    subZ,
2915                                                          int                    subW,
2916                                                          int                    subH,
2917                                                          int                    subD,
2918                                                          int                    imageHeight,
2919                                                          int                    rowLength,
2920                                                          int                    skipImages,
2921                                                          int                    skipRows,
2922                                                          int                    skipPixels,
2923                                                          int                    alignment,
2924                                                          int                    offset)
2925                 : Texture3DSpecCase     (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, depth, 1)
2926                 , m_internalFormat      (internalFormat)
2927                 , m_subX                        (subX)
2928                 , m_subY                        (subY)
2929                 , m_subZ                        (subZ)
2930                 , m_subW                        (subW)
2931                 , m_subH                        (subH)
2932                 , m_subD                        (subD)
2933                 , m_imageHeight         (imageHeight)
2934                 , m_rowLength           (rowLength)
2935                 , m_skipImages          (skipImages)
2936                 , m_skipRows            (skipRows)
2937                 , m_skipPixels          (skipPixels)
2938                 , m_alignment           (alignment)
2939                 , m_offset                      (offset)
2940         {
2941         }
2942
2943 protected:
2944         void createTexture (void)
2945         {
2946                 glu::TransferFormat             transferFmt             = glu::getTransferFormat(m_texFormat);
2947                 int                                             pixelSize               = m_texFormat.getPixelSize();
2948                 deUint32                                tex                             = 0;
2949                 deUint32                                buf                             = 0;
2950                 vector<deUint8>                 data;
2951
2952                 DE_ASSERT(m_numLevels == 1);
2953
2954                 glGenTextures(1, &tex);
2955                 glBindTexture(GL_TEXTURE_3D, tex);
2956
2957                 // Fill with gradient.
2958                 {
2959                         int             rowPitch                = deAlign32(pixelSize*m_width,  4);
2960                         int             slicePitch              = rowPitch*m_height;
2961
2962                         data.resize(slicePitch*m_depth);
2963                         tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, m_depth, rowPitch, slicePitch, &data[0]), m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
2964                 }
2965
2966                 glTexImage3D(GL_TEXTURE_3D, 0, m_internalFormat, m_width, m_height, m_depth, 0, transferFmt.format, transferFmt.dataType, &data[0]);
2967
2968                 // Fill data with grid.
2969                 {
2970                         int             rowLength               = m_rowLength > 0 ? m_rowLength : m_subW;
2971                         int             rowPitch                = deAlign32(rowLength*pixelSize, m_alignment);
2972                         int             imageHeight             = m_imageHeight > 0 ? m_imageHeight : m_subH;
2973                         int             slicePitch              = imageHeight*rowPitch;
2974                         Vec4    cScale                  = m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
2975                         Vec4    cBias                   = m_texFormatInfo.valueMin;
2976                         Vec4    colorA                  = Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
2977                         Vec4    colorB                  = Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
2978
2979                         data.resize(slicePitch*(m_depth+m_skipImages) + m_offset);
2980                         tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, m_subW, m_subH, m_subD, rowPitch, slicePitch, &data[0] + m_skipImages*slicePitch + m_skipRows*rowPitch + m_skipPixels*pixelSize + m_offset), 4, colorA, colorB);
2981                 }
2982
2983                 glGenBuffers(1, &buf);
2984                 glBindBuffer(GL_PIXEL_UNPACK_BUFFER,    buf);
2985                 glBufferData(GL_PIXEL_UNPACK_BUFFER,    (int)data.size(), &data[0], GL_STATIC_DRAW);
2986
2987                 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT,   m_imageHeight);
2988                 glPixelStorei(GL_UNPACK_ROW_LENGTH,             m_rowLength);
2989                 glPixelStorei(GL_UNPACK_SKIP_IMAGES,    m_skipImages);
2990                 glPixelStorei(GL_UNPACK_SKIP_ROWS,              m_skipRows);
2991                 glPixelStorei(GL_UNPACK_SKIP_PIXELS,    m_skipPixels);
2992                 glPixelStorei(GL_UNPACK_ALIGNMENT,              m_alignment);
2993                 glTexSubImage3D(GL_TEXTURE_3D, 0, m_subX, m_subY, m_subZ, m_subW, m_subH, m_subD, transferFmt.format, transferFmt.dataType, (const void*)(deIntptr)m_offset);
2994         }
2995
2996         deUint32        m_internalFormat;
2997         int                     m_subX;
2998         int                     m_subY;
2999         int                     m_subZ;
3000         int                     m_subW;
3001         int                     m_subH;
3002         int                     m_subD;
3003         int                     m_imageHeight;
3004         int                     m_rowLength;
3005         int                     m_skipImages;
3006         int                     m_skipRows;
3007         int                     m_skipPixels;
3008         int                     m_alignment;
3009         int                     m_offset;
3010 };
3011
3012 // TexImage2D() depth case.
3013 class TexImage2DDepthCase : public Texture2DSpecCase
3014 {
3015 public:
3016         TexImage2DDepthCase (Context&           context,
3017                                                  const char*    name,
3018                                                  const char*    desc,
3019                                                  deUint32               internalFormat,
3020                                                  int                    imageWidth,
3021                                                  int                    imageHeight)
3022                 : Texture2DSpecCase     (context, name, desc, glu::mapGLInternalFormat(internalFormat), imageWidth, imageHeight, maxLevelCount(imageWidth, imageHeight))
3023                 , m_internalFormat      (internalFormat)
3024         {
3025                 // we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
3026                 m_texFormatInfo.lookupBias = Vec4(0.25f, 0.0f, 0.0f, 1.0f);
3027                 m_texFormatInfo.lookupScale = Vec4(0.5f, 1.0f, 1.0f, 0.0f);
3028         }
3029
3030         void createTexture (void)
3031         {
3032                 glu::TransferFormat     fmt                     = glu::getTransferFormat(m_texFormat);
3033                 deUint32                        tex                     = 0;
3034                 tcu::TextureLevel       levelData       (glu::mapGLTransferFormat(fmt.format, fmt.dataType));
3035
3036                 glGenTextures(1, &tex);
3037                 glBindTexture(GL_TEXTURE_2D, tex);
3038                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
3039                 GLU_CHECK();
3040
3041                 for (int ndx = 0; ndx < m_numLevels; ndx++)
3042                 {
3043                         const int   levelW              = de::max(1, m_width >> ndx);
3044                         const int   levelH              = de::max(1, m_height >> ndx);
3045                         const Vec4  gMin                = Vec4(-1.5f, -2.0f, 1.7f, -1.5f);
3046                         const Vec4  gMax                = Vec4(2.0f, 1.5f, -1.0f, 2.0f);
3047
3048                         levelData.setSize(levelW, levelH);
3049                         tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
3050
3051                         glTexImage2D(GL_TEXTURE_2D, ndx, m_internalFormat, levelW, levelH, 0, fmt.format, fmt.dataType, levelData.getAccess().getDataPtr());
3052                 }
3053         }
3054
3055         const deUint32 m_internalFormat;
3056 };
3057
3058 // TexImage3D() depth case.
3059 class TexImage2DArrayDepthCase : public Texture2DArraySpecCase
3060 {
3061 public:
3062         TexImage2DArrayDepthCase (Context&              context,
3063                                                           const char*   name,
3064                                                           const char*   desc,
3065                                                           deUint32              internalFormat,
3066                                                           int                   imageWidth,
3067                                                           int                   imageHeight,
3068                                                           int                   numLayers)
3069                 : Texture2DArraySpecCase(context, name, desc, glu::mapGLInternalFormat(internalFormat), imageWidth, imageHeight, numLayers, maxLevelCount(imageWidth, imageHeight))
3070                 , m_internalFormat              (internalFormat)
3071         {
3072                 // we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
3073                 m_texFormatInfo.lookupBias = Vec4(0.25f, 0.0f, 0.0f, 1.0f);
3074                 m_texFormatInfo.lookupScale = Vec4(0.5f, 1.0f, 1.0f, 0.0f);
3075         }
3076
3077         void createTexture (void)
3078         {
3079                 glu::TransferFormat     fmt                     = glu::getTransferFormat(m_texFormat);
3080                 deUint32                        tex                     = 0;
3081                 tcu::TextureLevel       levelData       (glu::mapGLTransferFormat(fmt.format, fmt.dataType));
3082
3083                 glGenTextures(1, &tex);
3084                 glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
3085                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
3086                 GLU_CHECK();
3087
3088                 for (int ndx = 0; ndx < m_numLevels; ndx++)
3089                 {
3090                         const int   levelW              = de::max(1, m_width >> ndx);
3091                         const int   levelH              = de::max(1, m_height >> ndx);
3092                         const Vec4  gMin                = Vec4(-1.5f, -2.0f, 1.7f, -1.5f);
3093                         const Vec4  gMax                = Vec4(2.0f, 1.5f, -1.0f, 2.0f);
3094
3095                         levelData.setSize(levelW, levelH, m_numLayers);
3096                         tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
3097
3098                         glTexImage3D(GL_TEXTURE_2D_ARRAY, ndx, m_internalFormat, levelW, levelH, m_numLayers, 0, fmt.format, fmt.dataType, levelData.getAccess().getDataPtr());
3099                 }
3100         }
3101
3102         const deUint32 m_internalFormat;
3103 };
3104
3105 // TexSubImage2D() depth case.
3106 class TexSubImage2DDepthCase : public Texture2DSpecCase
3107 {
3108 public:
3109         TexSubImage2DDepthCase (Context&        context,
3110                                                         const char*     name,
3111                                                         const char*     desc,
3112                                                         deUint32        internalFormat,
3113                                                         int                     imageWidth,
3114                                                         int                     imageHeight)
3115                 : Texture2DSpecCase     (context, name, desc, glu::mapGLInternalFormat(internalFormat), imageWidth, imageHeight, maxLevelCount(imageWidth, imageHeight))
3116                 , m_internalFormat      (internalFormat)
3117         {
3118                 // we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
3119                 m_texFormatInfo.lookupBias = Vec4(0.25f, 0.0f, 0.0f, 1.0f);
3120                 m_texFormatInfo.lookupScale = Vec4(0.5f, 1.0f, 1.0f, 0.0f);
3121         }
3122
3123         void createTexture (void)
3124         {
3125                 glu::TransferFormat     fmt                     = glu::getTransferFormat(m_texFormat);
3126                 de::Random                      rnd                     (deStringHash(getName()));
3127                 deUint32                        tex                     = 0;
3128                 tcu::TextureLevel       levelData       (glu::mapGLTransferFormat(fmt.format, fmt.dataType));
3129
3130                 glGenTextures(1, &tex);
3131                 glBindTexture(GL_TEXTURE_2D, tex);
3132                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
3133                 GLU_CHECK();
3134
3135                 // First specify full texture.
3136                 for (int ndx = 0; ndx < m_numLevels; ndx++)
3137                 {
3138                         const int   levelW              = de::max(1, m_width >> ndx);
3139                         const int   levelH              = de::max(1, m_height >> ndx);
3140                         const Vec4  gMin                = Vec4(-1.5f, -2.0f, 1.7f, -1.5f);
3141                         const Vec4  gMax                = Vec4(2.0f, 1.5f, -1.0f, 2.0f);
3142
3143                         levelData.setSize(levelW, levelH);
3144                         tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
3145
3146                         glTexImage2D(GL_TEXTURE_2D, ndx, m_internalFormat, levelW, levelH, 0, fmt.format, fmt.dataType, levelData.getAccess().getDataPtr());
3147                 }
3148
3149                 // Re-specify parts of each level.
3150                 for (int ndx = 0; ndx < m_numLevels; ndx++)
3151                 {
3152                         const int       levelW          = de::max(1, m_width >> ndx);
3153                         const int       levelH          = de::max(1, m_height >> ndx);
3154
3155                         const int       w                       = rnd.getInt(1, levelW);
3156                         const int       h                       = rnd.getInt(1, levelH);
3157                         const int       x                       = rnd.getInt(0, levelW-w);
3158                         const int       y                       = rnd.getInt(0, levelH-h);
3159
3160                         const Vec4      colorA          = Vec4(2.0f, 1.5f, -1.0f, 2.0f);
3161                         const Vec4      colorB          = Vec4(-1.5f, -2.0f, 1.7f, -1.5f);
3162                         const int       cellSize        = rnd.getInt(2, 16);
3163
3164                         levelData.setSize(w, h);
3165                         tcu::fillWithGrid(levelData.getAccess(), cellSize, colorA, colorB);
3166
3167                         glTexSubImage2D(GL_TEXTURE_2D, ndx, x, y, w, h, fmt.format, fmt.dataType, levelData.getAccess().getDataPtr());
3168                 }
3169         }
3170
3171         const deUint32 m_internalFormat;
3172 };
3173
3174 // TexSubImage3D() depth case.
3175 class TexSubImage2DArrayDepthCase : public Texture2DArraySpecCase
3176 {
3177 public:
3178         TexSubImage2DArrayDepthCase (Context&           context,
3179                                                                  const char*    name,
3180                                                                  const char*    desc,
3181                                                                  deUint32               internalFormat,
3182                                                                  int                    imageWidth,
3183                                                                  int                    imageHeight,
3184                                                                  int                    numLayers)
3185                 : Texture2DArraySpecCase(context, name, desc, glu::mapGLInternalFormat(internalFormat), imageWidth, imageHeight, numLayers, maxLevelCount(imageWidth, imageHeight))
3186                 , m_internalFormat              (internalFormat)
3187         {
3188                 // we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
3189                 m_texFormatInfo.lookupBias = Vec4(0.25f, 0.0f, 0.0f, 1.0f);
3190                 m_texFormatInfo.lookupScale = Vec4(0.5f, 1.0f, 1.0f, 0.0f);
3191         }
3192
3193         void createTexture (void)
3194         {
3195                 glu::TransferFormat     fmt                     = glu::getTransferFormat(m_texFormat);
3196                 de::Random                      rnd                     (deStringHash(getName()));
3197                 deUint32                        tex                     = 0;
3198                 tcu::TextureLevel       levelData       (glu::mapGLTransferFormat(fmt.format, fmt.dataType));
3199
3200                 glGenTextures(1, &tex);
3201                 glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
3202                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
3203                 GLU_CHECK();
3204
3205                 // First specify full texture.
3206                 for (int ndx = 0; ndx < m_numLevels; ndx++)
3207                 {
3208                         const int   levelW              = de::max(1, m_width >> ndx);
3209                         const int   levelH              = de::max(1, m_height >> ndx);
3210                         const Vec4  gMin                = Vec4(-1.5f, -2.0f, 1.7f, -1.5f);
3211                         const Vec4  gMax                = Vec4(2.0f, 1.5f, -1.0f, 2.0f);
3212
3213                         levelData.setSize(levelW, levelH, m_numLayers);
3214                         tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
3215
3216                         glTexImage3D(GL_TEXTURE_2D_ARRAY, ndx, m_internalFormat, levelW, levelH, m_numLayers, 0, fmt.format, fmt.dataType, levelData.getAccess().getDataPtr());
3217                 }
3218
3219                 // Re-specify parts of each level.
3220                 for (int ndx = 0; ndx < m_numLevels; ndx++)
3221                 {
3222                         const int       levelW          = de::max(1, m_width >> ndx);
3223                         const int       levelH          = de::max(1, m_height >> ndx);
3224
3225                         const int       w                       = rnd.getInt(1, levelW);
3226                         const int       h                       = rnd.getInt(1, levelH);
3227                         const int       d                       = rnd.getInt(1, m_numLayers);
3228                         const int       x                       = rnd.getInt(0, levelW-w);
3229                         const int       y                       = rnd.getInt(0, levelH-h);
3230                         const int       z                       = rnd.getInt(0, m_numLayers-d);
3231
3232                         const Vec4      colorA          = Vec4(2.0f, 1.5f, -1.0f, 2.0f);
3233                         const Vec4      colorB          = Vec4(-1.5f, -2.0f, 1.7f, -1.5f);
3234                         const int       cellSize        = rnd.getInt(2, 16);
3235
3236                         levelData.setSize(w, h, d);
3237                         tcu::fillWithGrid(levelData.getAccess(), cellSize, colorA, colorB);
3238
3239                         glTexSubImage3D(GL_TEXTURE_2D_ARRAY, ndx, x, y, z, w, h, d, fmt.format, fmt.dataType, levelData.getAccess().getDataPtr());
3240                 }
3241         }
3242
3243         const deUint32 m_internalFormat;
3244 };
3245
3246 // TexImage2D() depth case with pbo.
3247 class TexImage2DDepthBufferCase : public Texture2DSpecCase
3248 {
3249 public:
3250         TexImage2DDepthBufferCase (Context&             context,
3251                                                            const char*  name,
3252                                                            const char*  desc,
3253                                                            deUint32             internalFormat,
3254                                                            int                  imageWidth,
3255                                                            int                  imageHeight)
3256                 : Texture2DSpecCase     (context, name, desc, glu::mapGLInternalFormat(internalFormat), imageWidth, imageHeight, 1)
3257                 , m_internalFormat      (internalFormat)
3258         {
3259                 // we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
3260                 m_texFormatInfo.lookupBias = Vec4(0.25f, 0.0f, 0.0f, 1.0f);
3261                 m_texFormatInfo.lookupScale = Vec4(0.5f, 1.0f, 1.0f, 0.0f);
3262         }
3263
3264         void createTexture (void)
3265         {
3266                 glu::TransferFormat             transferFmt             = glu::getTransferFormat(m_texFormat);
3267                 int                                             pixelSize               = m_texFormat.getPixelSize();
3268                 int                                             rowLength               = m_width;
3269                 int                                             alignment               = 4;
3270                 int                                             rowPitch                = deAlign32(rowLength*pixelSize, alignment);
3271                 int                                             height                  = m_height;
3272                 deUint32                                buf                             = 0;
3273                 deUint32                                tex                             = 0;
3274                 vector<deUint8>                 data;
3275
3276                 DE_ASSERT(m_numLevels == 1);
3277
3278                 // Fill data with gradient
3279                 data.resize(rowPitch*height);
3280                 {
3281                         const Vec4 gMin = Vec4(-1.5f, -2.0f, 1.7f, -1.5f);
3282                         const Vec4 gMax = Vec4(2.0f, 1.5f, -1.0f, 2.0f);
3283
3284                         tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, 1, rowPitch, 0, &data[0]), gMin, gMax);
3285                 }
3286
3287                 // Create buffer and upload.
3288                 glGenBuffers(1, &buf);
3289                 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf);
3290                 glBufferData(GL_PIXEL_UNPACK_BUFFER, (int)data.size(), &data[0], GL_STATIC_DRAW);
3291
3292                 glPixelStorei(GL_UNPACK_ROW_LENGTH,             rowLength);
3293                 glPixelStorei(GL_UNPACK_SKIP_ROWS,              0);
3294                 glPixelStorei(GL_UNPACK_SKIP_PIXELS,    0);
3295                 glPixelStorei(GL_UNPACK_ALIGNMENT,              alignment);
3296
3297                 glGenTextures(1, &tex);
3298                 glBindTexture(GL_TEXTURE_2D, tex);
3299                 glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_width, m_height, 0, transferFmt.format, transferFmt.dataType, DE_NULL);
3300                 glDeleteBuffers(1, &buf);
3301         }
3302
3303         const deUint32 m_internalFormat;
3304 };
3305
3306 // TexImage3D() depth case with pbo.
3307 class TexImage2DArrayDepthBufferCase : public Texture2DArraySpecCase
3308 {
3309 public:
3310         TexImage2DArrayDepthBufferCase (Context&        context,
3311                                                                         const char*     name,
3312                                                                         const char*     desc,
3313                                                                         deUint32        internalFormat,
3314                                                                         int                     imageWidth,
3315                                                                         int                     imageHeight,
3316                                                                         int                     numLayers)
3317                 : Texture2DArraySpecCase(context, name, desc, glu::mapGLInternalFormat(internalFormat), imageWidth, imageHeight, numLayers, 1)
3318                 , m_internalFormat              (internalFormat)
3319         {
3320                 // we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
3321                 m_texFormatInfo.lookupBias = Vec4(0.25f, 0.0f, 0.0f, 1.0f);
3322                 m_texFormatInfo.lookupScale = Vec4(0.5f, 1.0f, 1.0f, 0.0f);
3323         }
3324
3325         void createTexture (void)
3326         {
3327                 glu::TransferFormat             transferFmt             = glu::getTransferFormat(m_texFormat);
3328                 int                                             pixelSize               = m_texFormat.getPixelSize();
3329                 int                                             rowLength               = m_width;
3330                 int                                             alignment               = 4;
3331                 int                                             rowPitch                = deAlign32(rowLength*pixelSize, alignment);
3332                 int                                             imageHeight             = m_height;
3333                 int                                             slicePitch              = imageHeight*rowPitch;
3334                 deUint32                                tex                             = 0;
3335                 deUint32                                buf                             = 0;
3336                 vector<deUint8>                 data;
3337
3338                 DE_ASSERT(m_numLevels == 1);
3339
3340                 // Fill data with grid.
3341                 data.resize(slicePitch*m_numLayers);
3342                 {
3343                         const Vec4 gMin = Vec4(-1.5f, -2.0f, 1.7f, -1.5f);
3344                         const Vec4 gMax = Vec4(2.0f, 1.5f, -1.0f, 2.0f);
3345
3346                         tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, m_numLayers, rowPitch, slicePitch, &data[0]), gMin, gMax);
3347                 }
3348
3349                 glGenBuffers(1, &buf);
3350                 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf);
3351                 glBufferData(GL_PIXEL_UNPACK_BUFFER, (int)data.size(), &data[0], GL_STATIC_DRAW);
3352
3353                 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT,   imageHeight);
3354                 glPixelStorei(GL_UNPACK_ROW_LENGTH,             rowLength);
3355                 glPixelStorei(GL_UNPACK_SKIP_IMAGES,    0);
3356                 glPixelStorei(GL_UNPACK_SKIP_ROWS,              0);
3357                 glPixelStorei(GL_UNPACK_SKIP_PIXELS,    0);
3358                 glPixelStorei(GL_UNPACK_ALIGNMENT,              alignment);
3359
3360                 glGenTextures(1, &tex);
3361                 glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
3362                 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, m_internalFormat, m_width, m_height, m_numLayers, 0, transferFmt.format, transferFmt.dataType, DE_NULL);
3363                 glDeleteBuffers(1, &buf);
3364         }
3365
3366         const deUint32 m_internalFormat;
3367 };
3368
3369 TextureSpecificationTests::TextureSpecificationTests (Context& context)
3370         : TestCaseGroup(context, "specification", "Texture Specification Tests")
3371 {
3372 }
3373
3374 TextureSpecificationTests::~TextureSpecificationTests (void)
3375 {
3376 }
3377
3378 void TextureSpecificationTests::init (void)
3379 {
3380         struct
3381         {
3382                 const char*     name;
3383                 deUint32        format;
3384                 deUint32        dataType;
3385         } unsizedFormats[] =
3386         {
3387                 { "alpha_unsigned_byte",                        GL_ALPHA,                       GL_UNSIGNED_BYTE },
3388                 { "luminance_unsigned_byte",            GL_LUMINANCE,           GL_UNSIGNED_BYTE },
3389                 { "luminance_alpha_unsigned_byte",      GL_LUMINANCE_ALPHA,     GL_UNSIGNED_BYTE },
3390                 { "rgb_unsigned_short_5_6_5",           GL_RGB,                         GL_UNSIGNED_SHORT_5_6_5 },
3391                 { "rgb_unsigned_byte",                          GL_RGB,                         GL_UNSIGNED_BYTE },
3392                 { "rgba_unsigned_short_4_4_4_4",        GL_RGBA,                        GL_UNSIGNED_SHORT_4_4_4_4 },
3393                 { "rgba_unsigned_short_5_5_5_1",        GL_RGBA,                        GL_UNSIGNED_SHORT_5_5_5_1 },
3394                 { "rgba_unsigned_byte",                         GL_RGBA,                        GL_UNSIGNED_BYTE }
3395         };
3396
3397         struct
3398         {
3399                 const char*     name;
3400                 deUint32        internalFormat;
3401         } colorFormats[] =
3402         {
3403                 { "rgba32f",                    GL_RGBA32F,                     },
3404                 { "rgba32i",                    GL_RGBA32I,                     },
3405                 { "rgba32ui",                   GL_RGBA32UI,            },
3406                 { "rgba16f",                    GL_RGBA16F,                     },
3407                 { "rgba16i",                    GL_RGBA16I,                     },
3408                 { "rgba16ui",                   GL_RGBA16UI,            },
3409                 { "rgba8",                              GL_RGBA8,                       },
3410                 { "rgba8i",                             GL_RGBA8I,                      },
3411                 { "rgba8ui",                    GL_RGBA8UI,                     },
3412                 { "srgb8_alpha8",               GL_SRGB8_ALPHA8,        },
3413                 { "rgb10_a2",                   GL_RGB10_A2,            },
3414                 { "rgb10_a2ui",                 GL_RGB10_A2UI,          },
3415                 { "rgba4",                              GL_RGBA4,                       },
3416                 { "rgb5_a1",                    GL_RGB5_A1,                     },
3417                 { "rgba8_snorm",                GL_RGBA8_SNORM,         },
3418                 { "rgb8",                               GL_RGB8,                        },
3419                 { "rgb565",                             GL_RGB565,                      },
3420                 { "r11f_g11f_b10f",             GL_R11F_G11F_B10F,      },
3421                 { "rgb32f",                             GL_RGB32F,                      },
3422                 { "rgb32i",                             GL_RGB32I,                      },
3423                 { "rgb32ui",                    GL_RGB32UI,                     },
3424                 { "rgb16f",                             GL_RGB16F,                      },
3425                 { "rgb16i",                             GL_RGB16I,                      },
3426                 { "rgb16ui",                    GL_RGB16UI,                     },
3427                 { "rgb8_snorm",                 GL_RGB8_SNORM,          },
3428                 { "rgb8i",                              GL_RGB8I,                       },
3429                 { "rgb8ui",                             GL_RGB8UI,                      },
3430                 { "srgb8",                              GL_SRGB8,                       },
3431                 { "rgb9_e5",                    GL_RGB9_E5,                     },
3432                 { "rg32f",                              GL_RG32F,                       },
3433                 { "rg32i",                              GL_RG32I,                       },
3434                 { "rg32ui",                             GL_RG32UI,                      },
3435                 { "rg16f",                              GL_RG16F,                       },
3436                 { "rg16i",                              GL_RG16I,                       },
3437                 { "rg16ui",                             GL_RG16UI,                      },
3438                 { "rg8",                                GL_RG8,                         },
3439                 { "rg8i",                               GL_RG8I,                        },
3440                 { "rg8ui",                              GL_RG8UI,                       },
3441                 { "rg8_snorm",                  GL_RG8_SNORM,           },
3442                 { "r32f",                               GL_R32F,                        },
3443                 { "r32i",                               GL_R32I,                        },
3444                 { "r32ui",                              GL_R32UI,                       },
3445                 { "r16f",                               GL_R16F,                        },
3446                 { "r16i",                               GL_R16I,                        },
3447                 { "r16ui",                              GL_R16UI,                       },
3448                 { "r8",                                 GL_R8,                          },
3449                 { "r8i",                                GL_R8I,                         },
3450                 { "r8ui",                               GL_R8UI,                        },
3451                 { "r8_snorm",                   GL_R8_SNORM,            }
3452         };
3453
3454         static const struct
3455         {
3456                 const char*     name;
3457                 deUint32        internalFormat;
3458         } depthStencilFormats[] =
3459         {
3460                 // Depth and stencil formats
3461                 { "depth_component32f", GL_DEPTH_COMPONENT32F   },
3462                 { "depth_component24",  GL_DEPTH_COMPONENT24    },
3463                 { "depth_component16",  GL_DEPTH_COMPONENT16    },
3464                 { "depth32f_stencil8",  GL_DEPTH32F_STENCIL8    },
3465                 { "depth24_stencil8",   GL_DEPTH24_STENCIL8             }
3466         };
3467
3468         // Basic TexImage2D usage.
3469         {
3470                 tcu::TestCaseGroup* basicTexImageGroup = new tcu::TestCaseGroup(m_testCtx, "basic_teximage2d", "Basic glTexImage2D() usage");
3471                 addChild(basicTexImageGroup);
3472                 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++)
3473                 {
3474                         const char*     fmtName         = colorFormats[formatNdx].name;
3475                         deUint32        format          = colorFormats[formatNdx].internalFormat;
3476                         const int       tex2DWidth      = 64;
3477                         const int       tex2DHeight     = 128;
3478                         const int       texCubeSize     = 64;
3479
3480                         basicTexImageGroup->addChild(new BasicTexImage2DCase    (m_context,     (string(fmtName) + "_2d").c_str(),              "",     format, tex2DWidth, tex2DHeight));
3481                         basicTexImageGroup->addChild(new BasicTexImageCubeCase  (m_context,     (string(fmtName) + "_cube").c_str(),    "",     format, texCubeSize));
3482                 }
3483         }
3484
3485         // Randomized TexImage2D order.
3486         {
3487                 tcu::TestCaseGroup* randomTexImageGroup = new tcu::TestCaseGroup(m_testCtx, "random_teximage2d", "Randomized glTexImage2D() usage");
3488                 addChild(randomTexImageGroup);
3489
3490                 de::Random rnd(9);
3491
3492                 // 2D cases.
3493                 for (int ndx = 0; ndx < 10; ndx++)
3494                 {
3495                         int             formatNdx       = rnd.getInt(0, DE_LENGTH_OF_ARRAY(colorFormats)-1);
3496                         int             width           = 1 << rnd.getInt(2, 8);
3497                         int             height          = 1 << rnd.getInt(2, 8);
3498
3499                         randomTexImageGroup->addChild(new RandomOrderTexImage2DCase(m_context, (string("2d_") + de::toString(ndx)).c_str(), "", colorFormats[formatNdx].internalFormat, width, height));
3500                 }
3501
3502                 // Cubemap cases.
3503                 for (int ndx = 0; ndx < 10; ndx++)
3504                 {
3505                         int             formatNdx       = rnd.getInt(0, DE_LENGTH_OF_ARRAY(colorFormats)-1);
3506                         int             size            = 1 << rnd.getInt(2, 8);
3507
3508                         randomTexImageGroup->addChild(new RandomOrderTexImageCubeCase(m_context, (string("cube_") + de::toString(ndx)).c_str(), "", colorFormats[formatNdx].internalFormat, size));
3509                 }
3510         }
3511
3512         // TexImage2D unpack alignment.
3513         {
3514                 tcu::TestCaseGroup* alignGroup = new tcu::TestCaseGroup(m_testCtx, "teximage2d_align", "glTexImage2D() unpack alignment tests");
3515                 addChild(alignGroup);
3516
3517                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_r8_4_8",                        "",     GL_R8,                   4,  8, 4, 8));
3518                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_r8_63_1",                       "",     GL_R8,                  63, 30, 1, 1));
3519                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_r8_63_2",                       "",     GL_R8,                  63, 30, 1, 2));
3520                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_r8_63_4",                       "",     GL_R8,                  63, 30, 1, 4));
3521                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_r8_63_8",                       "",     GL_R8,                  63, 30, 1, 8));
3522                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_rgba4_51_1",            "",     GL_RGBA4,               51, 30, 1, 1));
3523                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_rgba4_51_2",            "",     GL_RGBA4,               51, 30, 1, 2));
3524                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_rgba4_51_4",            "",     GL_RGBA4,               51, 30, 1, 4));
3525                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_rgba4_51_8",            "",     GL_RGBA4,               51, 30, 1, 8));
3526                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_rgb8_39_1",                     "",     GL_RGB8,                39, 43, 1, 1));
3527                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_rgb8_39_2",                     "",     GL_RGB8,                39, 43, 1, 2));
3528                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_rgb8_39_4",                     "",     GL_RGB8,                39, 43, 1, 4));
3529                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_rgb8_39_8",                     "",     GL_RGB8,                39, 43, 1, 8));
3530                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_rgba8_47_1",            "",     GL_RGBA8,               47, 27, 1, 1));
3531                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_rgba8_47_2",            "",     GL_RGBA8,               47, 27, 1, 2));
3532                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_rgba8_47_4",            "",     GL_RGBA8,               47, 27, 1, 4));
3533                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_rgba8_47_8",            "",     GL_RGBA8,               47, 27, 1, 8));
3534
3535                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_r8_4_8",                      "",     GL_R8,                   4, 3, 8));
3536                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_r8_63_1",                     "",     GL_R8,                  63, 1, 1));
3537                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_r8_63_2",                     "",     GL_R8,                  63, 1, 2));
3538                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_r8_63_4",                     "",     GL_R8,                  63, 1, 4));
3539                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_r8_63_8",                     "",     GL_R8,                  63, 1, 8));
3540                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_rgba4_51_1",          "",     GL_RGBA4,               51, 1, 1));
3541                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_rgba4_51_2",          "",     GL_RGBA4,               51, 1, 2));
3542                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_rgba4_51_4",          "",     GL_RGBA4,               51, 1, 4));
3543                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_rgba4_51_8",          "",     GL_RGBA4,               51, 1, 8));
3544                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_rgb8_39_1",           "",     GL_RGB8,                39, 1, 1));
3545                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_rgb8_39_2",           "",     GL_RGB8,                39, 1, 2));
3546                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_rgb8_39_4",           "",     GL_RGB8,                39, 1, 4));
3547                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_rgb8_39_8",           "",     GL_RGB8,                39, 1, 8));
3548                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_rgba8_47_1",          "",     GL_RGBA8,               47, 1, 1));
3549                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_rgba8_47_2",          "",     GL_RGBA8,               47, 1, 2));
3550                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_rgba8_47_4",          "",     GL_RGBA8,               47, 1, 4));
3551                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_rgba8_47_8",          "",     GL_RGBA8,               47, 1, 8));
3552         }
3553
3554         // glTexImage2D() unpack parameter cases.
3555         {
3556                 tcu::TestCaseGroup* paramGroup = new tcu::TestCaseGroup(m_testCtx, "teximage2d_unpack_params", "glTexImage2D() pixel transfer mode cases");
3557                 addChild(paramGroup);
3558
3559                 static const struct
3560                 {
3561                         const char*     name;
3562                         deUint32        format;
3563                         int                     width;
3564                         int                     height;
3565                         int                     rowLength;
3566                         int                     skipRows;
3567                         int                     skipPixels;
3568                         int                     alignment;
3569                 } cases[] =
3570                 {
3571                         { "rgb8_alignment",             GL_RGB8,        31,     30,     0,      0,      0,      2 },
3572                         { "rgb8_row_length",    GL_RGB8,        31,     30,     50,     0,      0,      4 },
3573                         { "rgb8_skip_rows",             GL_RGB8,        31,     30,     0,      3,      0,      4 },
3574                         { "rgb8_skip_pixels",   GL_RGB8,        31,     30,     36,     0,      5,      4 },
3575                         { "r8_complex1",                GL_R8,          31, 30, 64, 1,  3,      1 },
3576                         { "r8_complex2",                GL_R8,          31, 30, 64, 1,  3,      2 },
3577                         { "r8_complex3",                GL_R8,          31, 30, 64, 1,  3,      4 },
3578                         { "r8_complex4",                GL_R8,          31, 30, 64, 1,  3,      8 },
3579                         { "rgba8_complex1",             GL_RGBA8,       56,     61,     69,     0,      0,      8 },
3580                         { "rgba8_complex2",             GL_RGBA8,       56,     61,     69,     0,      7,      8 },
3581                         { "rgba8_complex3",             GL_RGBA8,       56,     61,     69,     3,      0,      8 },
3582                         { "rgba8_complex4",             GL_RGBA8,       56,     61,     69,     3,      7,      8 },
3583                         { "rgba32f_complex",    GL_RGBA32F,     19,     10,     27,     1,      7,      8 }
3584                 };
3585
3586                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cases); ndx++)
3587                         paramGroup->addChild(new TexImage2DParamsCase(m_context, cases[ndx].name, "",
3588                                                                                                                   cases[ndx].format,
3589                                                                                                                   cases[ndx].width,
3590                                                                                                                   cases[ndx].height,
3591                                                                                                                   cases[ndx].rowLength,
3592                                                                                                                   cases[ndx].skipRows,
3593                                                                                                                   cases[ndx].skipPixels,
3594                                                                                                                   cases[ndx].alignment));
3595         }
3596
3597         // glTexImage2D() pbo cases.
3598         {
3599                 tcu::TestCaseGroup* pboGroup = new tcu::TestCaseGroup(m_testCtx, "teximage2d_pbo", "glTexImage2D() from PBO");
3600                 addChild(pboGroup);
3601
3602                 // Parameter cases
3603                 static const struct
3604                 {
3605                         const char*     name;
3606                         deUint32        format;
3607                         int                     width;
3608                         int                     height;
3609                         int                     rowLength;
3610                         int                     skipRows;
3611                         int                     skipPixels;
3612                         int                     alignment;
3613                         int                     offset;
3614                 } parameterCases[] =
3615                 {
3616                         { "rgb8_offset",                GL_RGB8,        31,     30,     0,      0,      0,      4,      67 },
3617                         { "rgb8_alignment",             GL_RGB8,        31,     30,     0,      0,      0,      2,      0 },
3618                         { "rgb8_row_length",    GL_RGB8,        31,     30,     50,     0,      0,      4,      0 },
3619                         { "rgb8_skip_rows",             GL_RGB8,        31,     30,     0,      3,      0,      4,      0 },
3620                         { "rgb8_skip_pixels",   GL_RGB8,        31,     30,     36,     0,      5,      4,      0 }
3621                 };
3622
3623                 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++)
3624                 {
3625                         const string    fmtName         = colorFormats[formatNdx].name;
3626                         const deUint32  format          = colorFormats[formatNdx].internalFormat;
3627                         const int               tex2DWidth      = 65;
3628                         const int               tex2DHeight     = 37;
3629                         const int               texCubeSize     = 64;
3630
3631                         pboGroup->addChild(new TexImage2DBufferCase             (m_context,     (fmtName + "_2d").c_str(),              "", format, tex2DWidth, tex2DHeight, 0, 0, 0, 4, 0));
3632                         pboGroup->addChild(new TexImageCubeBufferCase   (m_context,     (fmtName + "_cube").c_str(),    "", format, texCubeSize, 0, 0, 0, 4, 0));
3633                 }
3634
3635                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(parameterCases); ndx++)
3636                 {
3637                         pboGroup->addChild(new TexImage2DBufferCase(m_context, (string(parameterCases[ndx].name) + "_2d").c_str(), "",
3638                                                                                                                 parameterCases[ndx].format,
3639                                                                                                                 parameterCases[ndx].width,
3640                                                                                                                 parameterCases[ndx].height,
3641                                                                                                                 parameterCases[ndx].rowLength,
3642                                                                                                                 parameterCases[ndx].skipRows,
3643                                                                                                                 parameterCases[ndx].skipPixels,
3644                                                                                                                 parameterCases[ndx].alignment,
3645                                                                                                                 parameterCases[ndx].offset));
3646                         pboGroup->addChild(new TexImageCubeBufferCase(m_context, (string(parameterCases[ndx].name) + "_cube").c_str(), "",
3647                                                                                                                 parameterCases[ndx].format,
3648                                                                                                                 parameterCases[ndx].width,
3649                                                                                                                 parameterCases[ndx].rowLength,
3650                                                                                                                 parameterCases[ndx].skipRows,
3651                                                                                                                 parameterCases[ndx].skipPixels,
3652                                                                                                                 parameterCases[ndx].alignment,
3653                                                                                                                 parameterCases[ndx].offset));
3654                 }
3655         }
3656
3657         // glTexImage2D() depth cases.
3658         {
3659                 tcu::TestCaseGroup* shadow2dGroup = new tcu::TestCaseGroup(m_testCtx, "teximage2d_depth", "glTexImage2D() with depth or depth/stencil format");
3660                 addChild(shadow2dGroup);
3661
3662                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++)
3663                 {
3664                         const int tex2DWidth    = 64;
3665                         const int tex2DHeight   = 128;
3666
3667                         shadow2dGroup->addChild(new TexImage2DDepthCase(m_context, depthStencilFormats[ndx].name, "", depthStencilFormats[ndx].internalFormat, tex2DWidth, tex2DHeight));
3668                 }
3669         }
3670
3671         // glTexImage2D() depth cases with pbo.
3672         {
3673                 tcu::TestCaseGroup* shadow2dGroup = new tcu::TestCaseGroup(m_testCtx, "teximage2d_depth_pbo", "glTexImage2D() with depth or depth/stencil format with pbo");
3674                 addChild(shadow2dGroup);
3675
3676                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++)
3677                 {
3678                         const int tex2DWidth    = 64;
3679                         const int tex2DHeight   = 128;
3680
3681                         shadow2dGroup->addChild(new TexImage2DDepthBufferCase(m_context, depthStencilFormats[ndx].name, "", depthStencilFormats[ndx].internalFormat, tex2DWidth, tex2DHeight));
3682                 }
3683         }
3684
3685         // Basic TexSubImage2D usage.
3686         {
3687                 tcu::TestCaseGroup* basicTexSubImageGroup = new tcu::TestCaseGroup(m_testCtx, "basic_texsubimage2d", "Basic glTexSubImage2D() usage");
3688                 addChild(basicTexSubImageGroup);
3689                 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++)
3690                 {
3691                         const char*     fmtName         = colorFormats[formatNdx].name;
3692                         deUint32        format          = colorFormats[formatNdx].internalFormat;
3693                         const int       tex2DWidth      = 64;
3694                         const int       tex2DHeight     = 128;
3695                         const int       texCubeSize     = 64;
3696
3697                         basicTexSubImageGroup->addChild(new BasicTexSubImage2DCase              (m_context,     (string(fmtName) + "_2d").c_str(),              "",     format, tex2DWidth, tex2DHeight));
3698                         basicTexSubImageGroup->addChild(new BasicTexSubImageCubeCase    (m_context,     (string(fmtName) + "_cube").c_str(),    "",     format, texCubeSize));
3699                 }
3700         }
3701
3702         // TexSubImage2D to empty texture.
3703         {
3704                 tcu::TestCaseGroup* texSubImageEmptyTexGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage2d_empty_tex", "glTexSubImage2D() to texture that has storage but no data");
3705                 addChild(texSubImageEmptyTexGroup);
3706                 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(unsizedFormats); formatNdx++)
3707                 {
3708                         const char*     fmtName         = unsizedFormats[formatNdx].name;
3709                         deUint32        format          = unsizedFormats[formatNdx].format;
3710                         deUint32        dataType        = unsizedFormats[formatNdx].dataType;
3711                         const int       tex2DWidth      = 64;
3712                         const int       tex2DHeight     = 32;
3713                         const int       texCubeSize     = 32;
3714
3715                         texSubImageEmptyTexGroup->addChild(new TexSubImage2DEmptyTexCase        (m_context,     (string(fmtName) + "_2d").c_str(),              "",     format, dataType, tex2DWidth, tex2DHeight));
3716                         texSubImageEmptyTexGroup->addChild(new TexSubImageCubeEmptyTexCase      (m_context,     (string(fmtName) + "_cube").c_str(),    "",     format, dataType, texCubeSize));
3717                 }
3718         }
3719
3720         // TexSubImage2D alignment cases.
3721         {
3722                 tcu::TestCaseGroup* alignGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage2d_align", "glTexSubImage2D() unpack alignment tests");
3723                 addChild(alignGroup);
3724
3725                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_r8_1_1",                        "",     GL_R8,                  64, 64, 13, 17,  1,  6, 1));
3726                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_r8_1_2",                        "",     GL_R8,                  64, 64, 13, 17,  1,  6, 2));
3727                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_r8_1_4",                        "",     GL_R8,                  64, 64, 13, 17,  1,  6, 4));
3728                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_r8_1_8",                        "",     GL_R8,                  64, 64, 13, 17,  1,  6, 8));
3729                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_r8_63_1",                       "",     GL_R8,                  64, 64,  1,  9, 63, 30, 1));
3730                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_r8_63_2",                       "",     GL_R8,                  64, 64,  1,  9, 63, 30, 2));
3731                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_r8_63_4",                       "",     GL_R8,                  64, 64,  1,  9, 63, 30, 4));
3732                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_r8_63_8",                       "",     GL_R8,                  64, 64,  1,  9, 63, 30, 8));
3733                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_rgba4_51_1",            "",     GL_RGBA4,               64, 64,  7, 29, 51, 30, 1));
3734                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_rgba4_51_2",            "",     GL_RGBA4,               64, 64,  7, 29, 51, 30, 2));
3735                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_rgba4_51_4",            "",     GL_RGBA4,               64, 64,  7, 29, 51, 30, 4));
3736                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_rgba4_51_8",            "",     GL_RGBA4,               64, 64,  7, 29, 51, 30, 8));
3737                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_rgb8_39_1",                     "",     GL_RGB8,                64, 64, 11,  8, 39, 43, 1));
3738                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_rgb8_39_2",                     "",     GL_RGB8,                64, 64, 11,  8, 39, 43, 2));
3739                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_rgb8_39_4",                     "",     GL_RGB8,                64, 64, 11,  8, 39, 43, 4));
3740                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_rgb8_39_8",                     "",     GL_RGB8,                64, 64, 11,  8, 39, 43, 8));
3741                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_rgba8_47_1",            "",     GL_RGBA8,               64, 64, 10,  1, 47, 27, 1));
3742                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_rgba8_47_2",            "",     GL_RGBA8,               64, 64, 10,  1, 47, 27, 2));
3743                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_rgba8_47_4",            "",     GL_RGBA8,               64, 64, 10,  1, 47, 27, 4));
3744                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_rgba8_47_8",            "",     GL_RGBA8,               64, 64, 10,  1, 47, 27, 8));
3745
3746                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_r8_1_1",                      "",     GL_R8,                  64, 13, 17,  1,  6, 1));
3747                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_r8_1_2",                      "",     GL_R8,                  64, 13, 17,  1,  6, 2));
3748                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_r8_1_4",                      "",     GL_R8,                  64, 13, 17,  1,  6, 4));
3749                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_r8_1_8",                      "",     GL_R8,                  64, 13, 17,  1,  6, 8));
3750                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_r8_63_1",                     "",     GL_R8,                  64,  1,  9, 63, 30, 1));
3751                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_r8_63_2",                     "",     GL_R8,                  64,  1,  9, 63, 30, 2));
3752                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_r8_63_4",                     "",     GL_R8,                  64,  1,  9, 63, 30, 4));
3753                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_r8_63_8",                     "",     GL_R8,                  64,  1,  9, 63, 30, 8));
3754                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_rgba4_51_1",          "",     GL_RGBA4,               64,  7, 29, 51, 30, 1));
3755                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_rgba4_51_2",          "",     GL_RGBA4,               64,  7, 29, 51, 30, 2));
3756                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_rgba4_51_4",          "",     GL_RGBA4,               64,  7, 29, 51, 30, 4));
3757                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_rgba4_51_8",          "",     GL_RGBA4,               64,  7, 29, 51, 30, 8));
3758                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_rgb8_39_1",           "",     GL_RGB8,                64, 11,  8, 39, 43, 1));
3759                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_rgb8_39_2",           "",     GL_RGB8,                64, 11,  8, 39, 43, 2));
3760                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_rgb8_39_4",           "",     GL_RGB8,                64, 11,  8, 39, 43, 4));
3761                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_rgb8_39_8",           "",     GL_RGB8,                64, 11,  8, 39, 43, 8));
3762                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_rgba8_47_1",          "",     GL_RGBA8,               64, 10,  1, 47, 27, 1));
3763                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_rgba8_47_2",          "",     GL_RGBA8,               64, 10,  1, 47, 27, 2));
3764                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_rgba8_47_4",          "",     GL_RGBA8,               64, 10,  1, 47, 27, 4));
3765                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_rgba8_47_8",          "",     GL_RGBA8,               64, 10,  1, 47, 27, 8));
3766         }
3767
3768         // glTexSubImage2D() pixel transfer mode cases.
3769         {
3770                 tcu::TestCaseGroup* paramGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage2d_unpack_params", "glTexSubImage2D() pixel transfer mode cases");
3771                 addChild(paramGroup);
3772
3773                 static const struct
3774                 {
3775                         const char*     name;
3776                         deUint32        format;
3777                         int                     width;
3778                         int                     height;
3779                         int                     subX;
3780                         int                     subY;
3781                         int                     subW;
3782                         int                     subH;
3783                         int                     rowLength;
3784                         int                     skipRows;
3785                         int                     skipPixels;
3786                         int                     alignment;
3787                 } cases[] =
3788                 {
3789                         { "rgb8_alignment",             GL_RGB8,        54,     60,     11,     7,      31,     30,     0,      0,      0,      2 },
3790                         { "rgb8_row_length",    GL_RGB8,        54,     60,     11,     7,      31,     30,     50,     0,      0,      4 },
3791                         { "rgb8_skip_rows",             GL_RGB8,        54,     60,     11,     7,      31,     30,     0,      3,      0,      4 },
3792                         { "rgb8_skip_pixels",   GL_RGB8,        54,     60,     11,     7,      31,     30,     36,     0,      5,      4 },
3793                         { "r8_complex1",                GL_R8,          54,     60,     11,     7,      31, 30, 64, 1,  3,      1 },
3794                         { "r8_complex2",                GL_R8,          54,     60,     11,     7,      31, 30, 64, 1,  3,      2 },
3795                         { "r8_complex3",                GL_R8,          54,     60,     11,     7,      31, 30, 64, 1,  3,      4 },
3796                         { "r8_complex4",                GL_R8,          54,     60,     11,     7,      31, 30, 64, 1,  3,      8 },
3797                         { "rgba8_complex1",             GL_RGBA8,       92,     84,     13,     19,     56,     61,     69,     0,      0,      8 },
3798                         { "rgba8_complex2",             GL_RGBA8,       92,     84,     13,     19,     56,     61,     69,     0,      7,      8 },
3799                         { "rgba8_complex3",             GL_RGBA8,       92,     84,     13,     19,     56,     61,     69,     3,      0,      8 },
3800                         { "rgba8_complex4",             GL_RGBA8,       92,     84,     13,     19,     56,     61,     69,     3,      7,      8 },
3801                         { "rgba32f_complex",    GL_RGBA32F,     92,     84,     13,     19,     56,     61,     69,     3,      7,      8 }
3802                 };
3803
3804                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cases); ndx++)
3805                         paramGroup->addChild(new TexSubImage2DParamsCase(m_context, cases[ndx].name, "",
3806                                                                                                                          cases[ndx].format,
3807                                                                                                                          cases[ndx].width,
3808                                                                                                                          cases[ndx].height,
3809                                                                                                                          cases[ndx].subX,
3810                                                                                                                          cases[ndx].subY,
3811                                                                                                                          cases[ndx].subW,
3812                                                                                                                          cases[ndx].subH,
3813                                                                                                                          cases[ndx].rowLength,
3814                                                                                                                          cases[ndx].skipRows,
3815                                                                                                                          cases[ndx].skipPixels,
3816                                                                                                                          cases[ndx].alignment));
3817         }
3818
3819         // glTexSubImage2D() PBO cases.
3820         {
3821                 tcu::TestCaseGroup* pboGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage2d_pbo", "glTexSubImage2D() pixel buffer object tests");
3822                 addChild(pboGroup);
3823
3824                 static const struct
3825                 {
3826                         const char*     name;
3827                         deUint32        format;
3828                         int                     width;
3829                         int                     height;
3830                         int                     subX;
3831                         int                     subY;
3832                         int                     subW;
3833                         int                     subH;
3834                         int                     rowLength;
3835                         int                     skipRows;
3836                         int                     skipPixels;
3837                         int                     alignment;
3838                         int                     offset;
3839                 } paramCases[] =
3840                 {
3841                         { "rgb8_offset",                GL_RGB8,        54,     60,     11,     7,      31,     30,     0,      0,      0,      4,      67 },
3842                         { "rgb8_alignment",             GL_RGB8,        54,     60,     11,     7,      31,     30,     0,      0,      0,      2,      0 },
3843                         { "rgb8_row_length",    GL_RGB8,        54,     60,     11,     7,      31,     30,     50,     0,      0,      4,      0 },
3844                         { "rgb8_skip_rows",             GL_RGB8,        54,     60,     11,     7,      31,     30,     0,      3,      0,      4,      0 },
3845                         { "rgb8_skip_pixels",   GL_RGB8,        54,     60,     11,     7,      31,     30,     36,     0,      5,      4,      0 }
3846                 };
3847
3848                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(colorFormats); ndx++)
3849                 {
3850                         pboGroup->addChild(new TexSubImage2DBufferCase(m_context, (std::string(colorFormats[ndx].name) + "_2d").c_str(), "",
3851                                                                                                                    colorFormats[ndx].internalFormat,
3852                                                                                                                    54,  // Width
3853                                                                                                                    60,  // Height
3854                                                                                                                    11,  // Sub X
3855                                                                                                                    7,   // Sub Y
3856                                                                                                                    31,  // Sub W
3857                                                                                                                    30,  // Sub H
3858                                                                                                                    0,   // Row len
3859                                                                                                                    0,   // Skip rows
3860                                                                                                                    0,   // Skip pixels
3861                                                                                                                    4,   // Alignment
3862                                                                                                                    0    /* offset */));
3863                         pboGroup->addChild(new TexSubImageCubeBufferCase(m_context, (std::string(colorFormats[ndx].name) + "_cube").c_str(), "",
3864                                                                                                                    colorFormats[ndx].internalFormat,
3865                                                                                                                    64,  // Size
3866                                                                                                                    11,  // Sub X
3867                                                                                                                    7,   // Sub Y
3868                                                                                                                    31,  // Sub W
3869                                                                                                                    30,  // Sub H
3870                                                                                                                    0,   // Row len
3871                                                                                                                    0,   // Skip rows
3872                                                                                                                    0,   // Skip pixels
3873                                                                                                                    4,   // Alignment
3874                                                                                                                    0    /* offset */));
3875                 }
3876
3877                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(paramCases); ndx++)
3878                 {
3879                         pboGroup->addChild(new TexSubImage2DBufferCase(m_context, (std::string(paramCases[ndx].name) + "_2d").c_str(), "",
3880                                                                                                                    paramCases[ndx].format,
3881                                                                                                                    paramCases[ndx].width,
3882                                                                                                                    paramCases[ndx].height,
3883                                                                                                                    paramCases[ndx].subX,
3884                                                                                                                    paramCases[ndx].subY,
3885                                                                                                                    paramCases[ndx].subW,
3886                                                                                                                    paramCases[ndx].subH,
3887                                                                                                                    paramCases[ndx].rowLength,
3888                                                                                                                    paramCases[ndx].skipRows,
3889                                                                                                                    paramCases[ndx].skipPixels,
3890                                                                                                                    paramCases[ndx].alignment,
3891                                                                                                                    paramCases[ndx].offset));
3892                         pboGroup->addChild(new TexSubImageCubeBufferCase(m_context, (std::string(paramCases[ndx].name) + "_cube").c_str(), "",
3893                                                                                                                    paramCases[ndx].format,
3894                                                                                                                    paramCases[ndx].width,
3895                                                                                                                    paramCases[ndx].subX,
3896                                                                                                                    paramCases[ndx].subY,
3897                                                                                                                    paramCases[ndx].subW,
3898                                                                                                                    paramCases[ndx].subH,
3899                                                                                                                    paramCases[ndx].rowLength,
3900                                                                                                                    paramCases[ndx].skipRows,
3901                                                                                                                    paramCases[ndx].skipPixels,
3902                                                                                                                    paramCases[ndx].alignment,
3903                                                                                                                    paramCases[ndx].offset));
3904                 }
3905         }
3906
3907         // glTexSubImage2D() depth cases.
3908         {
3909                 tcu::TestCaseGroup* shadow2dGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage2d_depth", "glTexSubImage2D() with depth or depth/stencil format");
3910                 addChild(shadow2dGroup);
3911
3912                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++)
3913                 {
3914                         const int       tex2DWidth      = 64;
3915                         const int       tex2DHeight     = 32;
3916
3917                         shadow2dGroup->addChild(new TexSubImage2DDepthCase(m_context, depthStencilFormats[ndx].name, "", depthStencilFormats[ndx].internalFormat, tex2DWidth, tex2DHeight));
3918                 }
3919         }
3920
3921         // Basic glCopyTexImage2D() cases
3922         {
3923                 tcu::TestCaseGroup* copyTexImageGroup = new tcu::TestCaseGroup(m_testCtx, "basic_copyteximage2d", "Basic glCopyTexImage2D() usage");
3924                 addChild(copyTexImageGroup);
3925
3926                 copyTexImageGroup->addChild(new BasicCopyTexImage2DCase         (m_context, "2d_alpha",                         "",     GL_ALPHA,                       128, 64));
3927                 copyTexImageGroup->addChild(new BasicCopyTexImage2DCase         (m_context, "2d_luminance",                     "",     GL_LUMINANCE,           128, 64));
3928                 copyTexImageGroup->addChild(new BasicCopyTexImage2DCase         (m_context, "2d_luminance_alpha",       "",     GL_LUMINANCE_ALPHA,     128, 64));
3929                 copyTexImageGroup->addChild(new BasicCopyTexImage2DCase         (m_context, "2d_rgb",                           "",     GL_RGB,                         128, 64));
3930                 copyTexImageGroup->addChild(new BasicCopyTexImage2DCase         (m_context, "2d_rgba",                          "",     GL_RGBA,                        128, 64));
3931
3932                 copyTexImageGroup->addChild(new BasicCopyTexImageCubeCase       (m_context, "cube_alpha",                       "",     GL_ALPHA,                       64));
3933                 copyTexImageGroup->addChild(new BasicCopyTexImageCubeCase       (m_context, "cube_luminance",           "",     GL_LUMINANCE,           64));
3934                 copyTexImageGroup->addChild(new BasicCopyTexImageCubeCase       (m_context, "cube_luminance_alpha",     "",     GL_LUMINANCE_ALPHA,     64));
3935                 copyTexImageGroup->addChild(new BasicCopyTexImageCubeCase       (m_context, "cube_rgb",                         "",     GL_RGB,                         64));
3936                 copyTexImageGroup->addChild(new BasicCopyTexImageCubeCase       (m_context, "cube_rgba",                        "",     GL_RGBA,                        64));
3937         }
3938
3939         // Basic glCopyTexSubImage2D() cases
3940         {
3941                 tcu::TestCaseGroup* copyTexSubImageGroup = new tcu::TestCaseGroup(m_testCtx, "basic_copytexsubimage2d", "Basic glCopyTexSubImage2D() usage");
3942                 addChild(copyTexSubImageGroup);
3943
3944                 copyTexSubImageGroup->addChild(new BasicCopyTexSubImage2DCase   (m_context, "2d_alpha",                         "",     GL_ALPHA,                       GL_UNSIGNED_BYTE, 128, 64));
3945                 copyTexSubImageGroup->addChild(new BasicCopyTexSubImage2DCase   (m_context, "2d_luminance",                     "",     GL_LUMINANCE,           GL_UNSIGNED_BYTE, 128, 64));
3946                 copyTexSubImageGroup->addChild(new BasicCopyTexSubImage2DCase   (m_context, "2d_luminance_alpha",       "",     GL_LUMINANCE_ALPHA,     GL_UNSIGNED_BYTE, 128, 64));
3947                 copyTexSubImageGroup->addChild(new BasicCopyTexSubImage2DCase   (m_context, "2d_rgb",                           "",     GL_RGB,                         GL_UNSIGNED_BYTE, 128, 64));
3948                 copyTexSubImageGroup->addChild(new BasicCopyTexSubImage2DCase   (m_context, "2d_rgba",                          "",     GL_RGBA,                        GL_UNSIGNED_BYTE, 128, 64));
3949
3950                 copyTexSubImageGroup->addChild(new BasicCopyTexSubImageCubeCase (m_context, "cube_alpha",                       "",     GL_ALPHA,                       GL_UNSIGNED_BYTE, 64));
3951                 copyTexSubImageGroup->addChild(new BasicCopyTexSubImageCubeCase (m_context, "cube_luminance",           "",     GL_LUMINANCE,           GL_UNSIGNED_BYTE, 64));
3952                 copyTexSubImageGroup->addChild(new BasicCopyTexSubImageCubeCase (m_context, "cube_luminance_alpha",     "",     GL_LUMINANCE_ALPHA,     GL_UNSIGNED_BYTE, 64));
3953                 copyTexSubImageGroup->addChild(new BasicCopyTexSubImageCubeCase (m_context, "cube_rgb",                         "",     GL_RGB,                         GL_UNSIGNED_BYTE, 64));
3954                 copyTexSubImageGroup->addChild(new BasicCopyTexSubImageCubeCase (m_context, "cube_rgba",                        "",     GL_RGBA,                        GL_UNSIGNED_BYTE, 64));
3955         }
3956
3957         // Basic TexImage3D usage.
3958         {
3959                 tcu::TestCaseGroup* basicTexImageGroup = new tcu::TestCaseGroup(m_testCtx, "basic_teximage3d", "Basic glTexImage3D() usage");
3960                 addChild(basicTexImageGroup);
3961                 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++)
3962                 {
3963                         const char*     fmtName                         = colorFormats[formatNdx].name;
3964                         deUint32        format                          = colorFormats[formatNdx].internalFormat;
3965                         const int       tex2DArrayWidth         = 57;
3966                         const int       tex2DArrayHeight        = 44;
3967                         const int       tex2DArrayLevels        = 5;
3968                         const int       tex3DWidth                      = 63;
3969                         const int       tex3DHeight                     = 29;
3970                         const int       tex3DDepth                      = 11;
3971
3972                         basicTexImageGroup->addChild(new BasicTexImage2DArrayCase       (m_context,     (string(fmtName) + "_2d_array").c_str(),        "",     format, tex2DArrayWidth, tex2DArrayHeight, tex2DArrayLevels));
3973                         basicTexImageGroup->addChild(new BasicTexImage3DCase            (m_context,     (string(fmtName) + "_3d").c_str(),                      "",     format, tex3DWidth, tex3DHeight, tex3DDepth));
3974                 }
3975         }
3976
3977         // glTexImage3D() unpack params cases.
3978         {
3979                 tcu::TestCaseGroup* paramGroup = new tcu::TestCaseGroup(m_testCtx, "teximage3d_unpack_params", "glTexImage3D() unpack parameters");
3980                 addChild(paramGroup);
3981
3982                 static const struct
3983                 {
3984                         const char*     name;
3985                         deUint32        format;
3986                         int                     width;
3987                         int                     height;
3988                         int                     depth;
3989                         int                     imageHeight;
3990                         int                     rowLength;
3991                         int                     skipImages;
3992                         int                     skipRows;
3993                         int                     skipPixels;
3994                         int                     alignment;
3995                 } cases[] =
3996                 {
3997                         { "rgb8_image_height",  GL_RGB8,        23,     19,     8,      26,     0,      0,      0,      0,      4 },
3998                         { "rgb8_row_length",    GL_RGB8,        23,     19,     8,      0,      27,     0,      0,      0,      4 },
3999                         { "rgb8_skip_images",   GL_RGB8,        23,     19,     8,      0,      0,      3,      0,      0,      4 },
4000                         { "rgb8_skip_rows",             GL_RGB8,        23,     19,     8,      22,     0,      0,      3,      0,      4 },
4001                         { "rgb8_skip_pixels",   GL_RGB8,        23,     19,     8,      0,      25,     0,      0,      2,      4 },
4002                         { "r8_complex1",                GL_R8,          13, 17, 11,     23,     15,     2,      3,      1,      1 },
4003                         { "r8_complex2",                GL_R8,          13, 17, 11,     23,     15,     2,      3,      1,      2 },
4004                         { "r8_complex3",                GL_R8,          13, 17, 11,     23,     15,     2,      3,      1,      4 },
4005                         { "r8_complex4",                GL_R8,          13, 17, 11,     23,     15,     2,      3,      1,      8 },
4006                         { "rgba8_complex1",             GL_RGBA8,       11,     20,     8,      25,     14,     0,      0,      0,      8 },
4007                         { "rgba8_complex2",             GL_RGBA8,       11,     20,     8,      25,     14,     0,      2,      0,      8 },
4008                         { "rgba8_complex3",             GL_RGBA8,       11,     20,     8,      25,     14,     0,      0,      3,      8 },
4009                         { "rgba8_complex4",             GL_RGBA8,       11,     20,     8,      25,     14,     0,      2,      3,      8 },
4010                         { "rgba32f_complex",    GL_RGBA32F,     11,     20,     8,      25,     14,     0,      2,      3,      8 }
4011                 };
4012
4013                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cases); ndx++)
4014                         paramGroup->addChild(new TexImage3DParamsCase(m_context, cases[ndx].name, "",
4015                                                                                                                   cases[ndx].format,
4016                                                                                                                   cases[ndx].width,
4017                                                                                                                   cases[ndx].height,
4018                                                                                                                   cases[ndx].depth,
4019                                                                                                                   cases[ndx].imageHeight,
4020                                                                                                                   cases[ndx].rowLength,
4021                                                                                                                   cases[ndx].skipImages,
4022                                                                                                                   cases[ndx].skipRows,
4023                                                                                                                   cases[ndx].skipPixels,
4024                                                                                                                   cases[ndx].alignment));
4025         }
4026
4027         // glTexImage3D() pbo cases.
4028         {
4029                 tcu::TestCaseGroup* pboGroup = new tcu::TestCaseGroup(m_testCtx, "teximage3d_pbo", "glTexImage3D() from PBO");
4030                 addChild(pboGroup);
4031
4032                 // Parameter cases
4033                 static const struct
4034                 {
4035                         const char*     name;
4036                         deUint32        format;
4037                         int                     width;
4038                         int                     height;
4039                         int                     depth;
4040                         int                     imageHeight;
4041                         int                     rowLength;
4042                         int                     skipImages;
4043                         int                     skipRows;
4044                         int                     skipPixels;
4045                         int                     alignment;
4046                         int                     offset;
4047                 } parameterCases[] =
4048                 {
4049                         { "rgb8_offset",                GL_RGB8,        23,     19,     8,      0,      0,      0,      0,      0,      1,      67 },
4050                         { "rgb8_alignment",             GL_RGB8,        23,     19,     8,      0,      0,      0,      0,      0,      2,      0 },
4051                         { "rgb8_image_height",  GL_RGB8,        23,     19,     8,      26,     0,      0,      0,      0,      4,      0 },
4052                         { "rgb8_row_length",    GL_RGB8,        23,     19,     8,      0,      27,     0,      0,      0,      4,      0 },
4053                         { "rgb8_skip_images",   GL_RGB8,        23,     19,     8,      0,      0,      3,      0,      0,      4,      0 },
4054                         { "rgb8_skip_rows",             GL_RGB8,        23,     19,     8,      22,     0,      0,      3,      0,      4,      0 },
4055                         { "rgb8_skip_pixels",   GL_RGB8,        23,     19,     8,      0,      25,     0,      0,      2,      4,      0 }
4056                 };
4057
4058                 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++)
4059                 {
4060                         const string    fmtName         = colorFormats[formatNdx].name;
4061                         const deUint32  format          = colorFormats[formatNdx].internalFormat;
4062                         const int               tex3DWidth      = 11;
4063                         const int               tex3DHeight     = 20;
4064                         const int               tex3DDepth      = 8;
4065
4066                         pboGroup->addChild(new TexImage2DArrayBufferCase        (m_context, (fmtName + "_2d_array").c_str(),    "", format, tex3DWidth, tex3DHeight, tex3DDepth, 0, 0, 0, 0, 0, 4, 0));
4067                         pboGroup->addChild(new TexImage3DBufferCase                     (m_context, (fmtName + "_3d").c_str(),                  "", format, tex3DWidth, tex3DHeight, tex3DDepth, 0, 0, 0, 0, 0, 4, 0));
4068                 }
4069
4070                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(parameterCases); ndx++)
4071                 {
4072                         pboGroup->addChild(new TexImage2DArrayBufferCase(m_context, (string(parameterCases[ndx].name) + "_2d_array").c_str(), "",
4073                                                                                                                 parameterCases[ndx].format,
4074                                                                                                                 parameterCases[ndx].width,
4075                                                                                                                 parameterCases[ndx].depth,
4076                                                                                                                 parameterCases[ndx].height,
4077                                                                                                                 parameterCases[ndx].imageHeight,
4078                                                                                                                 parameterCases[ndx].rowLength,
4079                                                                                                                 parameterCases[ndx].skipImages,
4080                                                                                                                 parameterCases[ndx].skipRows,
4081                                                                                                                 parameterCases[ndx].skipPixels,
4082                                                                                                                 parameterCases[ndx].alignment,
4083                                                                                                                 parameterCases[ndx].offset));
4084                         pboGroup->addChild(new TexImage3DBufferCase(m_context, (string(parameterCases[ndx].name) + "_3d").c_str(), "",
4085                                                                                                                 parameterCases[ndx].format,
4086                                                                                                                 parameterCases[ndx].width,
4087                                                                                                                 parameterCases[ndx].depth,
4088                                                                                                                 parameterCases[ndx].height,
4089                                                                                                                 parameterCases[ndx].imageHeight,
4090                                                                                                                 parameterCases[ndx].rowLength,
4091                                                                                                                 parameterCases[ndx].skipImages,
4092                                                                                                                 parameterCases[ndx].skipRows,
4093                                                                                                                 parameterCases[ndx].skipPixels,
4094                                                                                                                 parameterCases[ndx].alignment,
4095                                                                                                                 parameterCases[ndx].offset));
4096                 }
4097         }
4098
4099         // glTexImage3D() depth cases.
4100         {
4101                 tcu::TestCaseGroup* shadow3dGroup = new tcu::TestCaseGroup(m_testCtx, "teximage3d_depth", "glTexImage3D() with depth or depth/stencil format");
4102                 addChild(shadow3dGroup);
4103
4104                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++)
4105                 {
4106                         const int       tex3DWidth      = 32;
4107                         const int       tex3DHeight     = 64;
4108                         const int       tex3DDepth      = 8;
4109
4110                         shadow3dGroup->addChild(new TexImage2DArrayDepthCase(m_context, (std::string(depthStencilFormats[ndx].name) + "_2d_array").c_str(), "", depthStencilFormats[ndx].internalFormat, tex3DWidth, tex3DHeight, tex3DDepth));
4111                 }
4112         }
4113
4114         // glTexImage3D() depth cases with pbo.
4115         {
4116                 tcu::TestCaseGroup* shadow3dGroup = new tcu::TestCaseGroup(m_testCtx, "teximage3d_depth_pbo", "glTexImage3D() with depth or depth/stencil format with pbo");
4117                 addChild(shadow3dGroup);
4118
4119                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++)
4120                 {
4121                         const int       tex3DWidth      = 32;
4122                         const int       tex3DHeight     = 64;
4123                         const int       tex3DDepth      = 8;
4124
4125                         shadow3dGroup->addChild(new TexImage2DArrayDepthBufferCase(m_context, (std::string(depthStencilFormats[ndx].name) + "_2d_array").c_str(), "", depthStencilFormats[ndx].internalFormat, tex3DWidth, tex3DHeight, tex3DDepth));
4126                 }
4127         }
4128
4129         // Basic TexSubImage3D usage.
4130         {
4131                 tcu::TestCaseGroup* basicTexSubImageGroup = new tcu::TestCaseGroup(m_testCtx, "basic_texsubimage3d", "Basic glTexSubImage3D() usage");
4132                 addChild(basicTexSubImageGroup);
4133                 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++)
4134                 {
4135                         const char*     fmtName         = colorFormats[formatNdx].name;
4136                         deUint32        format          = colorFormats[formatNdx].internalFormat;
4137                         const int       tex3DWidth      = 32;
4138                         const int       tex3DHeight     = 64;
4139                         const int       tex3DDepth      = 8;
4140
4141                         basicTexSubImageGroup->addChild(new BasicTexSubImage3DCase(m_context, (string(fmtName) + "_3d").c_str(), "", format, tex3DWidth, tex3DHeight, tex3DDepth));
4142                 }
4143         }
4144
4145         // glTexSubImage3D() unpack params cases.
4146         {
4147                 tcu::TestCaseGroup* paramGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage3d_unpack_params", "glTexSubImage3D() unpack parameters");
4148                 addChild(paramGroup);
4149
4150                 static const struct
4151                 {
4152                         const char*     name;
4153                         deUint32        format;
4154                         int                     width;
4155                         int                     height;
4156                         int                     depth;
4157                         int                     subX;
4158                         int                     subY;
4159                         int                     subZ;
4160                         int                     subW;
4161                         int                     subH;
4162                         int                     subD;
4163                         int                     imageHeight;
4164                         int                     rowLength;
4165                         int                     skipImages;
4166                         int                     skipRows;
4167                         int                     skipPixels;
4168                         int                     alignment;
4169                 } cases[] =
4170                 {
4171                         { "rgb8_image_height",  GL_RGB8,        26, 25, 10,     1,      2,      1,      23,     19,     8,      26,     0,      0,      0,      0,      4 },
4172                         { "rgb8_row_length",    GL_RGB8,        26, 25, 10,     1,      2,      1,      23,     19,     8,      0,      27,     0,      0,      0,      4 },
4173                         { "rgb8_skip_images",   GL_RGB8,        26, 25, 10,     1,      2,      1,      23,     19,     8,      0,      0,      3,      0,      0,      4 },
4174                         { "rgb8_skip_rows",             GL_RGB8,        26, 25, 10,     1,      2,      1,      23,     19,     8,      22,     0,      0,      3,      0,      4 },
4175                         { "rgb8_skip_pixels",   GL_RGB8,        26, 25, 10,     1,      2,      1,      23,     19,     8,      0,      25,     0,      0,      2,      4 },
4176                         { "r8_complex1",                GL_R8,          15,     20,     11,     1,      1,      0,      13, 17, 11,     23,     15,     2,      3,      1,      1 },
4177                         { "r8_complex2",                GL_R8,          15,     20,     11,     1,      1,      0,      13, 17, 11,     23,     15,     2,      3,      1,      2 },
4178                         { "r8_complex3",                GL_R8,          15,     20,     11,     1,      1,      0,      13, 17, 11,     23,     15,     2,      3,      1,      4 },
4179                         { "r8_complex4",                GL_R8,          15,     20,     11,     1,      1,      0,      13, 17, 11,     23,     15,     2,      3,      1,      8 },
4180                         { "rgba8_complex1",             GL_RGBA8,       15,     25,     10,     0,      5,      1,      11,     20,     8,      25,     14,     0,      0,      0,      8 },
4181                         { "rgba8_complex2",             GL_RGBA8,       15,     25,     10,     0,      5,      1,      11,     20,     8,      25,     14,     0,      2,      0,      8 },
4182                         { "rgba8_complex3",             GL_RGBA8,       15,     25,     10,     0,      5,      1,      11,     20,     8,      25,     14,     0,      0,      3,      8 },
4183                         { "rgba8_complex4",             GL_RGBA8,       15,     25,     10,     0,      5,      1,      11,     20,     8,      25,     14,     0,      2,      3,      8 },
4184                         { "rgba32f_complex",    GL_RGBA32F,     15,     25,     10,     0,      5,      1,      11,     20,     8,      25,     14,     0,      2,      3,      8 }
4185                 };
4186
4187                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cases); ndx++)
4188                         paramGroup->addChild(new TexSubImage3DParamsCase(m_context, cases[ndx].name, "",
4189                                                                                                                          cases[ndx].format,
4190                                                                                                                          cases[ndx].width,
4191                                                                                                                          cases[ndx].height,
4192                                                                                                                          cases[ndx].depth,
4193                                                                                                                          cases[ndx].subX,
4194                                                                                                                          cases[ndx].subY,
4195                                                                                                                          cases[ndx].subZ,
4196                                                                                                                          cases[ndx].subW,
4197                                                                                                                          cases[ndx].subH,
4198                                                                                                                          cases[ndx].subD,
4199                                                                                                                          cases[ndx].imageHeight,
4200                                                                                                                          cases[ndx].rowLength,
4201                                                                                                                          cases[ndx].skipImages,
4202                                                                                                                          cases[ndx].skipRows,
4203                                                                                                                          cases[ndx].skipPixels,
4204                                                                                                                          cases[ndx].alignment));
4205         }
4206
4207         // glTexSubImage3D() PBO cases.
4208         {
4209                 tcu::TestCaseGroup* pboGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage3d_pbo", "glTexSubImage3D() pixel buffer object tests");
4210                 addChild(pboGroup);
4211
4212                 static const struct
4213                 {
4214                         const char*     name;
4215                         deUint32        format;
4216                         int                     width;
4217                         int                     height;
4218                         int                     depth;
4219                         int                     subX;
4220                         int                     subY;
4221                         int                     subZ;
4222                         int                     subW;
4223                         int                     subH;
4224                         int                     subD;
4225                         int                     imageHeight;
4226                         int                     rowLength;
4227                         int                     skipImages;
4228                         int                     skipRows;
4229                         int                     skipPixels;
4230                         int                     alignment;
4231                         int                     offset;
4232                 } paramCases[] =
4233                 {
4234                         { "rgb8_offset",                GL_RGB8,        26, 25, 10,     1,      2,      1,      23,     19,     8,      0,      0,      0,      0,      0,      4,      67 },
4235                         { "rgb8_image_height",  GL_RGB8,        26, 25, 10,     1,      2,      1,      23,     19,     8,      26,     0,      0,      0,      0,      4,      0 },
4236                         { "rgb8_row_length",    GL_RGB8,        26, 25, 10,     1,      2,      1,      23,     19,     8,      0,      27,     0,      0,      0,      4,      0 },
4237                         { "rgb8_skip_images",   GL_RGB8,        26, 25, 10,     1,      2,      1,      23,     19,     8,      0,      0,      3,      0,      0,      4,      0 },
4238                         { "rgb8_skip_rows",             GL_RGB8,        26, 25, 10,     1,      2,      1,      23,     19,     8,      22,     0,      0,      3,      0,      4,      0 },
4239                         { "rgb8_skip_pixels",   GL_RGB8,        26, 25, 10,     1,      2,      1,      23,     19,     8,      0,      25,     0,      0,      2,      4,      0 }
4240                 };
4241
4242                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(colorFormats); ndx++)
4243                 {
4244                         pboGroup->addChild(new TexSubImage2DArrayBufferCase(m_context, (std::string(colorFormats[ndx].name) + "_2d_array").c_str(), "",
4245                                                                                                                    colorFormats[ndx].internalFormat,
4246                                                                                                                    26,  // Width
4247                                                                                                                    25,  // Height
4248                                                                                                                    10,  // Depth
4249                                                                                                                    1,   // Sub X
4250                                                                                                                    2,   // Sub Y
4251                                                                                                                    0,   // Sub Z
4252                                                                                                                    23,  // Sub W
4253                                                                                                                    19,  // Sub H
4254                                                                                                                    8,   // Sub D
4255                                                                                                                    0,   // Image height
4256                                                                                                                    0,   // Row length
4257                                                                                                                    0,   // Skip images
4258                                                                                                                    0,   // Skip rows
4259                                                                                                                    0,   // Skip pixels
4260                                                                                                                    4,   // Alignment
4261                                                                                                                    0    /* offset */));
4262                         pboGroup->addChild(new TexSubImage3DBufferCase(m_context, (std::string(colorFormats[ndx].name) + "_3d").c_str(), "",
4263                                                                                                                    colorFormats[ndx].internalFormat,
4264                                                                                                                    26,  // Width
4265                                                                                                                    25,  // Height
4266                                                                                                                    10,  // Depth
4267                                                                                                                    1,   // Sub X
4268                                                                                                                    2,   // Sub Y
4269                                                                                                                    0,   // Sub Z
4270                                                                                                                    23,  // Sub W
4271                                                                                                                    19,  // Sub H
4272                                                                                                                    8,   // Sub D
4273                                                                                                                    0,   // Image height
4274                                                                                                                    0,   // Row length
4275                                                                                                                    0,   // Skip images
4276                                                                                                                    0,   // Skip rows
4277                                                                                                                    0,   // Skip pixels
4278                                                                                                                    4,   // Alignment
4279                                                                                                                    0    /* offset */));
4280                 }
4281
4282                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(paramCases); ndx++)
4283                 {
4284                         pboGroup->addChild(new TexSubImage2DArrayBufferCase(m_context, (std::string(paramCases[ndx].name) + "_2d_array").c_str(), "",
4285                                                                                                                    paramCases[ndx].format,
4286                                                                                                                    paramCases[ndx].width,
4287                                                                                                                    paramCases[ndx].height,
4288                                                                                                                    paramCases[ndx].depth,
4289                                                                                                                    paramCases[ndx].subX,
4290                                                                                                                    paramCases[ndx].subY,
4291                                                                                                                    paramCases[ndx].subZ,
4292                                                                                                                    paramCases[ndx].subW,
4293                                                                                                                    paramCases[ndx].subH,
4294                                                                                                                    paramCases[ndx].subD,
4295                                                                                                                    paramCases[ndx].imageHeight,
4296                                                                                                                    paramCases[ndx].rowLength,
4297                                                                                                                    paramCases[ndx].skipImages,
4298                                                                                                                    paramCases[ndx].skipRows,
4299                                                                                                                    paramCases[ndx].skipPixels,
4300                                                                                                                    paramCases[ndx].alignment,
4301                                                                                                                    paramCases[ndx].offset));
4302                         pboGroup->addChild(new TexSubImage3DBufferCase(m_context, (std::string(paramCases[ndx].name) + "_3d").c_str(), "",
4303                                                                                                                    paramCases[ndx].format,
4304                                                                                                                    paramCases[ndx].width,
4305                                                                                                                    paramCases[ndx].height,
4306                                                                                                                    paramCases[ndx].depth,
4307                                                                                                                    paramCases[ndx].subX,
4308                                                                                                                    paramCases[ndx].subY,
4309                                                                                                                    paramCases[ndx].subZ,
4310                                                                                                                    paramCases[ndx].subW,
4311                                                                                                                    paramCases[ndx].subH,
4312                                                                                                                    paramCases[ndx].subD,
4313                                                                                                                    paramCases[ndx].imageHeight,
4314                                                                                                                    paramCases[ndx].rowLength,
4315                                                                                                                    paramCases[ndx].skipImages,
4316                                                                                                                    paramCases[ndx].skipRows,
4317                                                                                                                    paramCases[ndx].skipPixels,
4318                                                                                                                    paramCases[ndx].alignment,
4319                                                                                                                    paramCases[ndx].offset));
4320                 }
4321         }
4322
4323         // glTexSubImage3D() depth cases.
4324         {
4325                 tcu::TestCaseGroup* shadow3dGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage3d_depth", "glTexSubImage3D() with depth or depth/stencil format");
4326                 addChild(shadow3dGroup);
4327
4328                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++)
4329                 {
4330                         const int       tex2DArrayWidth         = 57;
4331                         const int       tex2DArrayHeight        = 44;
4332                         const int       tex2DArrayLevels        = 5;
4333
4334                         shadow3dGroup->addChild(new TexSubImage2DArrayDepthCase(m_context, (std::string(depthStencilFormats[ndx].name) + "_2d_array").c_str(), "", depthStencilFormats[ndx].internalFormat, tex2DArrayWidth, tex2DArrayHeight, tex2DArrayLevels));
4335                 }
4336         }
4337
4338         // glTexStorage2D() cases.
4339         {
4340                 tcu::TestCaseGroup* texStorageGroup = new tcu::TestCaseGroup(m_testCtx, "texstorage2d", "Basic glTexStorage2D() usage");
4341                 addChild(texStorageGroup);
4342
4343                 // All formats.
4344                 tcu::TestCaseGroup* formatGroup = new tcu::TestCaseGroup(m_testCtx, "format", "glTexStorage2D() with all formats");
4345                 texStorageGroup->addChild(formatGroup);
4346
4347                 // Color formats.
4348                 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++)
4349                 {
4350                         const char*     fmtName                 = colorFormats[formatNdx].name;
4351                         deUint32        internalFormat  = colorFormats[formatNdx].internalFormat;
4352                         const int       tex2DWidth              = 117;
4353                         const int       tex2DHeight             = 97;
4354                         int                     tex2DLevels             = maxLevelCount(tex2DWidth, tex2DHeight);
4355                         const int       cubeSize                = 57;
4356                         int                     cubeLevels              = maxLevelCount(cubeSize, cubeSize);
4357
4358                         formatGroup->addChild(new BasicTexStorage2DCase         (m_context, (string(fmtName) + "_2d").c_str(),          "", internalFormat, tex2DWidth, tex2DHeight, tex2DLevels));
4359                         formatGroup->addChild(new BasicTexStorageCubeCase       (m_context, (string(fmtName) + "_cube").c_str(),        "", internalFormat, cubeSize, cubeLevels));
4360                 }
4361
4362                 // Depth / stencil formats.
4363                 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(depthStencilFormats); formatNdx++)
4364                 {
4365                         const char*     fmtName                 = depthStencilFormats[formatNdx].name;
4366                         deUint32        internalFormat  = depthStencilFormats[formatNdx].internalFormat;
4367                         const int       tex2DWidth              = 117;
4368                         const int       tex2DHeight             = 97;
4369                         int                     tex2DLevels             = maxLevelCount(tex2DWidth, tex2DHeight);
4370                         const int       cubeSize                = 57;
4371                         int                     cubeLevels              = maxLevelCount(cubeSize, cubeSize);
4372
4373                         formatGroup->addChild(new BasicTexStorage2DCase         (m_context, (string(fmtName) + "_2d").c_str(),          "", internalFormat, tex2DWidth, tex2DHeight, tex2DLevels));
4374                         formatGroup->addChild(new BasicTexStorageCubeCase       (m_context, (string(fmtName) + "_cube").c_str(),        "", internalFormat, cubeSize, cubeLevels));
4375                 }
4376
4377                 // Sizes.
4378                 static const struct
4379                 {
4380                         int                             width;
4381                         int                             height;
4382                         int                             levels;
4383                 } tex2DSizes[] =
4384                 {
4385                         //      W       H       L
4386                         {       1,      1,      1 },
4387                         {       2,      2,      2 },
4388                         {       64,     32,     7 },
4389                         {       32,     64,     4 },
4390                         {       57,     63,     1 },
4391                         {       57,     63,     2 },
4392                         {       57,     63,     6 }
4393                 };
4394                 static const struct
4395                 {
4396                         int             size;
4397                         int             levels;
4398                 } cubeSizes[] =
4399                 {
4400                         //      S       L
4401                         {       1,      1 },
4402                         {       2,      2 },
4403                         {       57,     1 },
4404                         {       57,     2 },
4405                         {       57,     6 },
4406                         {       64,     4 },
4407                         {       64,     7 },
4408                 };
4409
4410                 tcu::TestCaseGroup* sizeGroup = new tcu::TestCaseGroup(m_testCtx, "size", "glTexStorage2D() with various sizes");
4411                 texStorageGroup->addChild(sizeGroup);
4412
4413                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(tex2DSizes); ndx++)
4414                 {
4415                         const deUint32          format          = GL_RGBA8;
4416                         int                                     width           = tex2DSizes[ndx].width;
4417                         int                                     height          = tex2DSizes[ndx].height;
4418                         int                                     levels          = tex2DSizes[ndx].levels;
4419                         string                          name            = string("2d_") + de::toString(width) + "x" + de::toString(height) + "_" + de::toString(levels) + "_levels";
4420
4421                         sizeGroup->addChild(new BasicTexStorage2DCase(m_context, name.c_str(), "", format, width, height, levels));
4422                 }
4423
4424                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cubeSizes); ndx++)
4425                 {
4426                         const deUint32          format          = GL_RGBA8;
4427                         int                                     size            = cubeSizes[ndx].size;
4428                         int                                     levels          = cubeSizes[ndx].levels;
4429                         string                          name            = string("cube_") + de::toString(size) + "x" + de::toString(size) + "_" + de::toString(levels) + "_levels";
4430
4431                         sizeGroup->addChild(new BasicTexStorageCubeCase(m_context, name.c_str(), "", format, size, levels));
4432                 }
4433         }
4434
4435         // glTexStorage3D() cases.
4436         {
4437                 tcu::TestCaseGroup* texStorageGroup = new tcu::TestCaseGroup(m_testCtx, "texstorage3d", "Basic glTexStorage3D() usage");
4438                 addChild(texStorageGroup);
4439
4440                 // All formats.
4441                 tcu::TestCaseGroup* formatGroup = new tcu::TestCaseGroup(m_testCtx, "format", "glTexStorage3D() with all formats");
4442                 texStorageGroup->addChild(formatGroup);
4443
4444                 // Color formats.
4445                 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++)
4446                 {
4447                         const char*     fmtName                         = colorFormats[formatNdx].name;
4448                         deUint32        internalFormat          = colorFormats[formatNdx].internalFormat;
4449                         const int       tex2DArrayWidth         = 57;
4450                         const int       tex2DArrayHeight        = 13;
4451                         const int       tex2DArrayLayers        = 7;
4452                         int                     tex2DArrayLevels        = maxLevelCount(tex2DArrayWidth, tex2DArrayHeight);
4453                         const int       tex3DWidth                      = 59;
4454                         const int       tex3DHeight                     = 37;
4455                         const int       tex3DDepth                      = 11;
4456                         int                     tex3DLevels                     = maxLevelCount(tex3DWidth, tex3DHeight, tex3DDepth);
4457
4458                         formatGroup->addChild(new BasicTexStorage2DArrayCase    (m_context, (string(fmtName) + "_2d_array").c_str(),    "", internalFormat, tex2DArrayWidth, tex2DArrayHeight, tex2DArrayLayers, tex2DArrayLevels));
4459                         formatGroup->addChild(new BasicTexStorage3DCase                 (m_context, (string(fmtName) + "_3d").c_str(),                  "", internalFormat, tex3DWidth, tex3DHeight, tex3DDepth, tex3DLevels));
4460                 }
4461
4462                 // Depth/stencil formats (only 2D texture array is supported).
4463                 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(depthStencilFormats); formatNdx++)
4464                 {
4465                         const char*     fmtName                         = depthStencilFormats[formatNdx].name;
4466                         deUint32        internalFormat          = depthStencilFormats[formatNdx].internalFormat;
4467                         const int       tex2DArrayWidth         = 57;
4468                         const int       tex2DArrayHeight        = 13;
4469                         const int       tex2DArrayLayers        = 7;
4470                         int                     tex2DArrayLevels        = maxLevelCount(tex2DArrayWidth, tex2DArrayHeight);
4471
4472                         formatGroup->addChild(new BasicTexStorage2DArrayCase    (m_context, (string(fmtName) + "_2d_array").c_str(),    "", internalFormat, tex2DArrayWidth, tex2DArrayHeight, tex2DArrayLayers, tex2DArrayLevels));
4473                 }
4474
4475                 // Sizes.
4476                 static const struct
4477                 {
4478                         int                             width;
4479                         int                             height;
4480                         int                             layers;
4481                         int                             levels;
4482                 } tex2DArraySizes[] =
4483                 {
4484                         //      W       H       La      Le
4485                         {       1,      1,      1,      1 },
4486                         {       2,      2,      2,      2 },
4487                         {       64,     32,     3,      7 },
4488                         {       32,     64,     3,      4 },
4489                         {       57,     63,     5,      1 },
4490                         {       57,     63,     5,      2 },
4491                         {       57,     63,     5,      6 }
4492                 };
4493                 static const struct
4494                 {
4495                         int                             width;
4496                         int                             height;
4497                         int                             depth;
4498                         int                             levels;
4499                 } tex3DSizes[] =
4500                 {
4501                         //      W       H       D       L
4502                         {       1,      1,      1,      1 },
4503                         {       2,      2,      2,      2 },
4504                         {       64,     32,     16,     7 },
4505                         {       32,     64,     16,     4 },
4506                         {       32,     16,     64,     4 },
4507                         {       57,     63,     11,     1 },
4508                         {       57,     63,     11,     2 },
4509                         {       57,     63,     11,     6 }
4510                 };
4511
4512                 tcu::TestCaseGroup* sizeGroup = new tcu::TestCaseGroup(m_testCtx, "size", "glTexStorage2D() with various sizes");
4513                 texStorageGroup->addChild(sizeGroup);
4514
4515                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(tex2DArraySizes); ndx++)
4516                 {
4517                         const deUint32          format          = GL_RGBA8;
4518                         int                                     width           = tex2DArraySizes[ndx].width;
4519                         int                                     height          = tex2DArraySizes[ndx].height;
4520                         int                                     layers          = tex2DArraySizes[ndx].layers;
4521                         int                                     levels          = tex2DArraySizes[ndx].levels;
4522                         string                          name            = string("2d_array_") + de::toString(width) + "x" + de::toString(height) + "x" + de::toString(layers) + "_" + de::toString(levels) + "_levels";
4523
4524                         sizeGroup->addChild(new BasicTexStorage2DArrayCase(m_context, name.c_str(), "", format, width, height, layers, levels));
4525                 }
4526
4527                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(tex3DSizes); ndx++)
4528                 {
4529                         const deUint32          format          = GL_RGBA8;
4530                         int                                     width           = tex3DSizes[ndx].width;
4531                         int                                     height          = tex3DSizes[ndx].height;
4532                         int                                     depth           = tex3DSizes[ndx].depth;
4533                         int                                     levels          = tex3DSizes[ndx].levels;
4534                         string                          name            = string("3d_") + de::toString(width) + "x" + de::toString(height) + "x" + de::toString(depth) + "_" + de::toString(levels) + "_levels";
4535
4536                         sizeGroup->addChild(new BasicTexStorage3DCase(m_context, name.c_str(), "", format, width, height, depth, levels));
4537                 }
4538         }
4539 }
4540
4541 } // Functional
4542 } // gles3
4543 } // deqp