8e5b0ecb173983f3b15578e2b5a4c707eafe2294
[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                 int                                             height                  = m_height + m_skipRows;
1084                 deUint32                                tex                             = 0;
1085                 vector<deUint8>                 data;
1086
1087                 DE_ASSERT(m_numLevels == 1);
1088
1089                 // Fill data with grid.
1090                 data.resize(rowPitch*height);
1091                 {
1092                         Vec4    cScale          = m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
1093                         Vec4    cBias           = m_texFormatInfo.valueMin;
1094                         Vec4    colorA          = Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
1095                         Vec4    colorB          = Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
1096
1097                         tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, 1, rowPitch, 0, &data[0] + m_skipRows*rowPitch + m_skipPixels*pixelSize), 4, colorA, colorB);
1098                 }
1099
1100                 glPixelStorei(GL_UNPACK_ROW_LENGTH,             m_rowLength);
1101                 glPixelStorei(GL_UNPACK_SKIP_ROWS,              m_skipRows);
1102                 glPixelStorei(GL_UNPACK_SKIP_PIXELS,    m_skipPixels);
1103                 glPixelStorei(GL_UNPACK_ALIGNMENT,              m_alignment);
1104
1105                 glGenTextures(1, &tex);
1106                 glBindTexture(GL_TEXTURE_2D, tex);
1107                 glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_width, m_height, 0, transferFmt.format, transferFmt.dataType, &data[0]);
1108         }
1109
1110         deUint32        m_internalFormat;
1111         int                     m_rowLength;
1112         int                     m_skipRows;
1113         int                     m_skipPixels;
1114         int                     m_alignment;
1115 };
1116
1117 // TexImage3D() unpack parameters case.
1118 class TexImage3DParamsCase : public Texture3DSpecCase
1119 {
1120 public:
1121         TexImage3DParamsCase (Context&          context,
1122                                                    const char*  name,
1123                                                    const char*  desc,
1124                                                    deUint32             internalFormat,
1125                                                    int                  width,
1126                                                    int                  height,
1127                                                    int                  depth,
1128                                                    int                  imageHeight,
1129                                                    int                  rowLength,
1130                                                    int                  skipImages,
1131                                                    int                  skipRows,
1132                                                    int                  skipPixels,
1133                                                    int                  alignment)
1134                 : Texture3DSpecCase     (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, depth, 1)
1135                 , m_internalFormat      (internalFormat)
1136                 , m_imageHeight         (imageHeight)
1137                 , m_rowLength           (rowLength)
1138                 , m_skipImages          (skipImages)
1139                 , m_skipRows            (skipRows)
1140                 , m_skipPixels          (skipPixels)
1141                 , m_alignment           (alignment)
1142         {
1143         }
1144
1145 protected:
1146         void createTexture (void)
1147         {
1148                 glu::TransferFormat             transferFmt             = glu::getTransferFormat(m_texFormat);
1149                 int                                             pixelSize               = m_texFormat.getPixelSize();
1150                 int                                             rowLength               = m_rowLength > 0 ? m_rowLength : m_width;
1151                 int                                             rowPitch                = deAlign32(rowLength*pixelSize, m_alignment);
1152                 int                                             imageHeight             = m_imageHeight > 0 ? m_imageHeight : m_height;
1153                 int                                             slicePitch              = imageHeight*rowPitch;
1154                 deUint32                                tex                             = 0;
1155                 vector<deUint8>                 data;
1156
1157                 DE_ASSERT(m_numLevels == 1);
1158
1159                 // Fill data with grid.
1160                 data.resize(slicePitch*(m_depth+m_skipImages));
1161                 {
1162                         Vec4    cScale          = m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
1163                         Vec4    cBias           = m_texFormatInfo.valueMin;
1164                         Vec4    colorA          = Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
1165                         Vec4    colorB          = Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
1166
1167                         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);
1168                 }
1169
1170                 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT,   m_imageHeight);
1171                 glPixelStorei(GL_UNPACK_ROW_LENGTH,             m_rowLength);
1172                 glPixelStorei(GL_UNPACK_SKIP_IMAGES,    m_skipImages);
1173                 glPixelStorei(GL_UNPACK_SKIP_ROWS,              m_skipRows);
1174                 glPixelStorei(GL_UNPACK_SKIP_PIXELS,    m_skipPixels);
1175                 glPixelStorei(GL_UNPACK_ALIGNMENT,              m_alignment);
1176
1177                 glGenTextures(1, &tex);
1178                 glBindTexture(GL_TEXTURE_3D, tex);
1179                 glTexImage3D(GL_TEXTURE_3D, 0, m_internalFormat, m_width, m_height, m_depth, 0, transferFmt.format, transferFmt.dataType, &data[0]);
1180         }
1181
1182         deUint32        m_internalFormat;
1183         int                     m_imageHeight;
1184         int                     m_rowLength;
1185         int                     m_skipImages;
1186         int                     m_skipRows;
1187         int                     m_skipPixels;
1188         int                     m_alignment;
1189 };
1190
1191 // Basic TexSubImage2D() with 2D texture usage
1192 class BasicTexSubImage2DCase : public Texture2DSpecCase
1193 {
1194 public:
1195         BasicTexSubImage2DCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int width, int height)
1196                 : Texture2DSpecCase     (context, name, desc, glu::mapGLTransferFormat(format, dataType), width, height, maxLevelCount(width, height))
1197                 , m_internalFormat      (format)
1198                 , m_format                      (format)
1199                 , m_dataType            (dataType)
1200         {
1201         }
1202
1203         BasicTexSubImage2DCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height)
1204                 : Texture2DSpecCase     (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, maxLevelCount(width, height))
1205                 , m_internalFormat      (internalFormat)
1206                 , m_format                      (GL_NONE)
1207                 , m_dataType            (GL_NONE)
1208         {
1209                 glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat);
1210                 m_format        = fmt.format;
1211                 m_dataType      = fmt.dataType;
1212         }
1213
1214 protected:
1215         void createTexture (void)
1216         {
1217                 deUint32                        tex                     = 0;
1218                 tcu::TextureLevel       data            (m_texFormat);
1219                 de::Random                      rnd                     (deStringHash(getName()));
1220
1221                 glGenTextures(1, &tex);
1222                 glBindTexture(GL_TEXTURE_2D, tex);
1223                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1224
1225                 // First specify full texture.
1226                 for (int ndx = 0; ndx < m_numLevels; ndx++)
1227                 {
1228                         int             levelW          = de::max(1, m_width >> ndx);
1229                         int             levelH          = de::max(1, m_height >> ndx);
1230                         Vec4    gMin            = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
1231                         Vec4    gMax            = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
1232
1233                         data.setSize(levelW, levelH);
1234                         tcu::fillWithComponentGradients(data.getAccess(), gMin, gMax);
1235
1236                         glTexImage2D(GL_TEXTURE_2D, ndx, m_internalFormat, levelW, levelH, 0, m_format, m_dataType, data.getAccess().getDataPtr());
1237                 }
1238
1239                 // Re-specify parts of each level.
1240                 for (int ndx = 0; ndx < m_numLevels; ndx++)
1241                 {
1242                         int             levelW          = de::max(1, m_width >> ndx);
1243                         int             levelH          = de::max(1, m_height >> ndx);
1244
1245                         int             w                       = rnd.getInt(1, levelW);
1246                         int             h                       = rnd.getInt(1, levelH);
1247                         int             x                       = rnd.getInt(0, levelW-w);
1248                         int             y                       = rnd.getInt(0, levelH-h);
1249
1250                         Vec4    colorA          = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
1251                         Vec4    colorB          = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
1252                         int             cellSize        = rnd.getInt(2, 16);
1253
1254                         data.setSize(w, h);
1255                         tcu::fillWithGrid(data.getAccess(), cellSize, colorA, colorB);
1256
1257                         glTexSubImage2D(GL_TEXTURE_2D, ndx, x, y, w, h, m_format, m_dataType, data.getAccess().getDataPtr());
1258                 }
1259         }
1260
1261         deUint32        m_internalFormat;
1262         deUint32        m_format;
1263         deUint32        m_dataType;
1264 };
1265
1266 // Basic TexSubImage2D() with cubemap usage
1267 class BasicTexSubImageCubeCase : public TextureCubeSpecCase
1268 {
1269 public:
1270         BasicTexSubImageCubeCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int size)
1271                 : TextureCubeSpecCase   (context, name, desc, glu::mapGLTransferFormat(format, dataType), size, deLog2Floor32(size)+1)
1272                 , m_internalFormat              (format)
1273                 , m_format                              (format)
1274                 , m_dataType                    (dataType)
1275         {
1276         }
1277
1278         BasicTexSubImageCubeCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int size)
1279                 : TextureCubeSpecCase   (context, name, desc, glu::mapGLInternalFormat(internalFormat), size, deLog2Floor32(size)+1)
1280                 , m_internalFormat              (internalFormat)
1281                 , m_format                              (GL_NONE)
1282                 , m_dataType                    (GL_NONE)
1283         {
1284                 glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat);
1285                 m_format        = fmt.format;
1286                 m_dataType      = fmt.dataType;
1287         }
1288
1289 protected:
1290         void createTexture (void)
1291         {
1292                 deUint32                        tex                     = 0;
1293                 tcu::TextureLevel       data            (m_texFormat);
1294                 de::Random                      rnd                     (deStringHash(getName()));
1295
1296                 glGenTextures(1, &tex);
1297                 glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
1298                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1299
1300                 for (int ndx = 0; ndx < m_numLevels; ndx++)
1301                 {
1302                         int levelSize = de::max(1, m_size >> ndx);
1303
1304                         data.setSize(levelSize, levelSize);
1305
1306                         for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
1307                         {
1308                                 Vec4 gMin = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
1309                                 Vec4 gMax = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
1310
1311                                 tcu::fillWithComponentGradients(data.getAccess(), gMin, gMax);
1312
1313                                 glTexImage2D(s_cubeMapFaces[face], ndx, m_internalFormat, levelSize, levelSize, 0, m_format, m_dataType, data.getAccess().getDataPtr());
1314                         }
1315                 }
1316
1317                 // Re-specify parts of each face and level.
1318                 for (int ndx = 0; ndx < m_numLevels; ndx++)
1319                 {
1320                         int levelSize = de::max(1, m_size >> ndx);
1321
1322                         for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
1323                         {
1324                                 int             w                       = rnd.getInt(1, levelSize);
1325                                 int             h                       = rnd.getInt(1, levelSize);
1326                                 int             x                       = rnd.getInt(0, levelSize-w);
1327                                 int             y                       = rnd.getInt(0, levelSize-h);
1328
1329                                 Vec4    colorA          = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
1330                                 Vec4    colorB          = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
1331                                 int             cellSize        = rnd.getInt(2, 16);
1332
1333                                 data.setSize(w, h);
1334                                 tcu::fillWithGrid(data.getAccess(), cellSize, colorA, colorB);
1335
1336                                 glTexSubImage2D(s_cubeMapFaces[face], ndx, x, y, w, h, m_format, m_dataType, data.getAccess().getDataPtr());
1337                         }
1338                 }
1339         }
1340
1341         deUint32        m_internalFormat;
1342         deUint32        m_format;
1343         deUint32        m_dataType;
1344 };
1345
1346 // TexSubImage2D() unpack parameters case.
1347 class TexSubImage2DParamsCase : public Texture2DSpecCase
1348 {
1349 public:
1350         TexSubImage2DParamsCase (Context&               context,
1351                                                          const char*    name,
1352                                                          const char*    desc,
1353                                                          deUint32               internalFormat,
1354                                                          int                    width,
1355                                                          int                    height,
1356                                                          int                    subX,
1357                                                          int                    subY,
1358                                                          int                    subW,
1359                                                          int                    subH,
1360                                                          int                    rowLength,
1361                                                          int                    skipRows,
1362                                                          int                    skipPixels,
1363                                                          int                    alignment)
1364                 : Texture2DSpecCase     (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, 1)
1365                 , m_internalFormat      (internalFormat)
1366                 , m_subX                        (subX)
1367                 , m_subY                        (subY)
1368                 , m_subW                        (subW)
1369                 , m_subH                        (subH)
1370                 , m_rowLength           (rowLength)
1371                 , m_skipRows            (skipRows)
1372                 , m_skipPixels          (skipPixels)
1373                 , m_alignment           (alignment)
1374         {
1375         }
1376
1377 protected:
1378         void createTexture (void)
1379         {
1380                 glu::TransferFormat             transferFmt             = glu::getTransferFormat(m_texFormat);
1381                 int                                             pixelSize               = m_texFormat.getPixelSize();
1382                 deUint32                                tex                             = 0;
1383                 vector<deUint8>                 data;
1384
1385                 DE_ASSERT(m_numLevels == 1);
1386
1387                 glGenTextures(1, &tex);
1388                 glBindTexture(GL_TEXTURE_2D, tex);
1389
1390                 // First fill texture with gradient.
1391                 data.resize(deAlign32(m_width*pixelSize, 4)*m_height);
1392                 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);
1393                 glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_width, m_height, 0, transferFmt.format, transferFmt.dataType, &data[0]);
1394
1395                 // Fill data with grid.
1396                 {
1397                         int             rowLength       = m_rowLength > 0 ? m_rowLength : m_subW;
1398                         int             rowPitch        = deAlign32(rowLength*pixelSize, m_alignment);
1399                         int             height          = m_subH + m_skipRows;
1400                         Vec4    cScale          = m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
1401                         Vec4    cBias           = m_texFormatInfo.valueMin;
1402                         Vec4    colorA          = Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
1403                         Vec4    colorB          = Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
1404
1405                         data.resize(rowPitch*height);
1406                         tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, m_subW, m_subH, 1, rowPitch, 0, &data[0] + m_skipRows*rowPitch + m_skipPixels*pixelSize), 4, colorA, colorB);
1407                 }
1408
1409                 glPixelStorei(GL_UNPACK_ROW_LENGTH,             m_rowLength);
1410                 glPixelStorei(GL_UNPACK_SKIP_ROWS,              m_skipRows);
1411                 glPixelStorei(GL_UNPACK_SKIP_PIXELS,    m_skipPixels);
1412                 glPixelStorei(GL_UNPACK_ALIGNMENT,              m_alignment);
1413                 glTexSubImage2D(GL_TEXTURE_2D, 0, m_subX, m_subY, m_subW, m_subH, transferFmt.format, transferFmt.dataType, &data[0]);
1414         }
1415
1416         deUint32        m_internalFormat;
1417         int                     m_subX;
1418         int                     m_subY;
1419         int                     m_subW;
1420         int                     m_subH;
1421         int                     m_rowLength;
1422         int                     m_skipRows;
1423         int                     m_skipPixels;
1424         int                     m_alignment;
1425 };
1426
1427 // Basic TexSubImage3D() with 3D texture usage
1428 class BasicTexSubImage3DCase : public Texture3DSpecCase
1429 {
1430 public:
1431         BasicTexSubImage3DCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height, int depth)
1432                 : Texture3DSpecCase     (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, depth, maxLevelCount(width, height, depth))
1433                 , m_internalFormat      (internalFormat)
1434         {
1435         }
1436
1437 protected:
1438         void createTexture (void)
1439         {
1440                 deUint32                                tex                             = 0;
1441                 tcu::TextureLevel               data                    (m_texFormat);
1442                 de::Random                              rnd                             (deStringHash(getName()));
1443                 glu::TransferFormat             transferFmt             = glu::getTransferFormat(m_texFormat);
1444
1445                 glGenTextures(1, &tex);
1446                 glBindTexture(GL_TEXTURE_3D, tex);
1447                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1448
1449                 // First specify full texture.
1450                 for (int ndx = 0; ndx < m_numLevels; ndx++)
1451                 {
1452                         int             levelW          = de::max(1, m_width >> ndx);
1453                         int             levelH          = de::max(1, m_height >> ndx);
1454                         int             levelD          = de::max(1, m_depth >> ndx);
1455                         Vec4    gMin            = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
1456                         Vec4    gMax            = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
1457
1458                         data.setSize(levelW, levelH, levelD);
1459                         tcu::fillWithComponentGradients(data.getAccess(), gMin, gMax);
1460
1461                         glTexImage3D(GL_TEXTURE_3D, ndx, m_internalFormat, levelW, levelH, levelD, 0, transferFmt.format, transferFmt.dataType, data.getAccess().getDataPtr());
1462                 }
1463
1464                 // Re-specify parts of each level.
1465                 for (int ndx = 0; ndx < m_numLevels; ndx++)
1466                 {
1467                         int             levelW          = de::max(1, m_width >> ndx);
1468                         int             levelH          = de::max(1, m_height >> ndx);
1469                         int             levelD          = de::max(1, m_depth >> ndx);
1470
1471                         int             w                       = rnd.getInt(1, levelW);
1472                         int             h                       = rnd.getInt(1, levelH);
1473                         int             d                       = rnd.getInt(1, levelD);
1474                         int             x                       = rnd.getInt(0, levelW-w);
1475                         int             y                       = rnd.getInt(0, levelH-h);
1476                         int             z                       = rnd.getInt(0, levelD-d);
1477
1478                         Vec4    colorA          = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
1479                         Vec4    colorB          = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
1480                         int             cellSize        = rnd.getInt(2, 16);
1481
1482                         data.setSize(w, h, d);
1483                         tcu::fillWithGrid(data.getAccess(), cellSize, colorA, colorB);
1484
1485                         glTexSubImage3D(GL_TEXTURE_3D, ndx, x, y, z, w, h, d, transferFmt.format, transferFmt.dataType, data.getAccess().getDataPtr());
1486                 }
1487         }
1488
1489         deUint32 m_internalFormat;
1490 };
1491
1492 // TexSubImage2D() to texture initialized with empty data
1493 class TexSubImage2DEmptyTexCase : public Texture2DSpecCase
1494 {
1495 public:
1496         TexSubImage2DEmptyTexCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int width, int height)
1497                 : Texture2DSpecCase     (context, name, desc, glu::mapGLTransferFormat(format, dataType), width, height, maxLevelCount(width, height))
1498                 , m_internalFormat      (format)
1499                 , m_format                      (format)
1500                 , m_dataType            (dataType)
1501         {
1502         }
1503
1504         TexSubImage2DEmptyTexCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height)
1505                 : Texture2DSpecCase     (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, maxLevelCount(width, height))
1506                 , m_internalFormat      (internalFormat)
1507                 , m_format                      (GL_NONE)
1508                 , m_dataType            (GL_NONE)
1509         {
1510                 glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat);
1511                 m_format        = fmt.format;
1512                 m_dataType      = fmt.dataType;
1513         }
1514
1515 protected:
1516         void createTexture (void)
1517         {
1518                 deUint32                        tex                     = 0;
1519                 tcu::TextureLevel       data            (m_texFormat);
1520                 de::Random                      rnd                     (deStringHash(getName()));
1521
1522                 glGenTextures(1, &tex);
1523                 glBindTexture(GL_TEXTURE_2D, tex);
1524                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1525
1526                 // First allocate storage for each level.
1527                 for (int ndx = 0; ndx < m_numLevels; ndx++)
1528                 {
1529                         int             levelW          = de::max(1, m_width >> ndx);
1530                         int             levelH          = de::max(1, m_height >> ndx);
1531
1532                         glTexImage2D(GL_TEXTURE_2D, ndx, m_internalFormat, levelW, levelH, 0, m_format, m_dataType, DE_NULL);
1533                 }
1534
1535                 // Specify pixel data to all levels using glTexSubImage2D()
1536                 for (int ndx = 0; ndx < m_numLevels; ndx++)
1537                 {
1538                         int             levelW          = de::max(1, m_width >> ndx);
1539                         int             levelH          = de::max(1, m_height >> ndx);
1540                         Vec4    gMin            = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
1541                         Vec4    gMax            = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
1542
1543                         data.setSize(levelW, levelH);
1544                         tcu::fillWithComponentGradients(data.getAccess(), gMin, gMax);
1545
1546                         glTexSubImage2D(GL_TEXTURE_2D, ndx, 0, 0, levelW, levelH, m_format, m_dataType, data.getAccess().getDataPtr());
1547                 }
1548         }
1549
1550         deUint32        m_internalFormat;
1551         deUint32        m_format;
1552         deUint32        m_dataType;
1553 };
1554
1555 // TexSubImage2D() to empty cubemap texture
1556 class TexSubImageCubeEmptyTexCase : public TextureCubeSpecCase
1557 {
1558 public:
1559         TexSubImageCubeEmptyTexCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int size)
1560                 : TextureCubeSpecCase   (context, name, desc, glu::mapGLTransferFormat(format, dataType), size, deLog2Floor32(size)+1)
1561                 , m_internalFormat              (format)
1562                 , m_format                              (format)
1563                 , m_dataType                    (dataType)
1564         {
1565         }
1566
1567         TexSubImageCubeEmptyTexCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int size)
1568                 : TextureCubeSpecCase   (context, name, desc, glu::mapGLInternalFormat(internalFormat), size, deLog2Floor32(size)+1)
1569                 , m_internalFormat              (internalFormat)
1570                 , m_format                              (GL_NONE)
1571                 , m_dataType                    (GL_NONE)
1572         {
1573                 glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat);
1574                 m_format        = fmt.format;
1575                 m_dataType      = fmt.dataType;
1576         }
1577
1578 protected:
1579         void createTexture (void)
1580         {
1581                 deUint32                        tex                     = 0;
1582                 tcu::TextureLevel       data            (m_texFormat);
1583                 de::Random                      rnd                     (deStringHash(getName()));
1584
1585                 glGenTextures(1, &tex);
1586                 glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
1587                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1588
1589                 // Specify storage for each level.
1590                 for (int ndx = 0; ndx < m_numLevels; ndx++)
1591                 {
1592                         int levelSize = de::max(1, m_size >> ndx);
1593
1594                         for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
1595                                 glTexImage2D(s_cubeMapFaces[face], ndx, m_internalFormat, levelSize, levelSize, 0, m_format, m_dataType, DE_NULL);
1596                 }
1597
1598                 // Specify data using glTexSubImage2D()
1599                 for (int ndx = 0; ndx < m_numLevels; ndx++)
1600                 {
1601                         int levelSize = de::max(1, m_size >> ndx);
1602
1603                         data.setSize(levelSize, levelSize);
1604
1605                         for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
1606                         {
1607                                 Vec4 gMin = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
1608                                 Vec4 gMax = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
1609
1610                                 tcu::fillWithComponentGradients(data.getAccess(), gMin, gMax);
1611
1612                                 glTexSubImage2D(s_cubeMapFaces[face], ndx, 0, 0, levelSize, levelSize, m_format, m_dataType, data.getAccess().getDataPtr());
1613                         }
1614                 }
1615         }
1616
1617         deUint32        m_internalFormat;
1618         deUint32        m_format;
1619         deUint32        m_dataType;
1620 };
1621
1622 // TexSubImage2D() unpack alignment with 2D texture
1623 class TexSubImage2DAlignCase : public Texture2DSpecCase
1624 {
1625 public:
1626         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)
1627                 : Texture2DSpecCase     (context, name, desc, glu::mapGLTransferFormat(format, dataType), width, height, 1)
1628                 , m_internalFormat      (format)
1629                 , m_format                      (format)
1630                 , m_dataType            (dataType)
1631                 , m_subX                        (subX)
1632                 , m_subY                        (subY)
1633                 , m_subW                        (subW)
1634                 , m_subH                        (subH)
1635                 , m_alignment           (alignment)
1636         {
1637         }
1638
1639         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)
1640                 : Texture2DSpecCase     (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, 1)
1641                 , m_internalFormat      (internalFormat)
1642                 , m_format                      (GL_NONE)
1643                 , m_dataType            (GL_NONE)
1644                 , m_subX                        (subX)
1645                 , m_subY                        (subY)
1646                 , m_subW                        (subW)
1647                 , m_subH                        (subH)
1648                 , m_alignment           (alignment)
1649         {
1650                 glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat);
1651                 m_format        = fmt.format;
1652                 m_dataType      = fmt.dataType;
1653         }
1654
1655 protected:
1656         void createTexture (void)
1657         {
1658                 deUint32                        tex                     = 0;
1659                 vector<deUint8>         data;
1660
1661                 glGenTextures(1, &tex);
1662                 glBindTexture(GL_TEXTURE_2D, tex);
1663
1664                 // Specify base level.
1665                 data.resize(m_texFormat.getPixelSize()*m_width*m_height);
1666                 tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, 1, &data[0]), Vec4(0.0f), Vec4(1.0f));
1667
1668                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1669                 glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_width, m_height, 0, m_format, m_dataType, &data[0]);
1670
1671                 // Re-specify subrectangle.
1672                 int rowPitch = deAlign32(m_texFormat.getPixelSize()*m_subW, m_alignment);
1673                 data.resize(rowPitch*m_subH);
1674                 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));
1675
1676                 glPixelStorei(GL_UNPACK_ALIGNMENT, m_alignment);
1677                 glTexSubImage2D(GL_TEXTURE_2D, 0, m_subX, m_subY, m_subW, m_subH, m_format, m_dataType, &data[0]);
1678         }
1679
1680         deUint32        m_internalFormat;
1681         deUint32        m_format;
1682         deUint32        m_dataType;
1683         int                     m_subX;
1684         int                     m_subY;
1685         int                     m_subW;
1686         int                     m_subH;
1687         int                     m_alignment;
1688 };
1689
1690 // TexSubImage2D() unpack alignment with cubemap texture
1691 class TexSubImageCubeAlignCase : public TextureCubeSpecCase
1692 {
1693 public:
1694         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)
1695                 : TextureCubeSpecCase   (context, name, desc, glu::mapGLTransferFormat(format, dataType), size, 1)
1696                 , m_internalFormat              (format)
1697                 , m_format                              (format)
1698                 , m_dataType                    (dataType)
1699                 , m_subX                                (subX)
1700                 , m_subY                                (subY)
1701                 , m_subW                                (subW)
1702                 , m_subH                                (subH)
1703                 , m_alignment                   (alignment)
1704         {
1705         }
1706
1707         TexSubImageCubeAlignCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int size, int subX, int subY, int subW, int subH, int alignment)
1708                 : TextureCubeSpecCase   (context, name, desc, glu::mapGLInternalFormat(internalFormat), size, 1)
1709                 , m_internalFormat              (internalFormat)
1710                 , m_format                              (GL_NONE)
1711                 , m_dataType                    (GL_NONE)
1712                 , m_subX                                (subX)
1713                 , m_subY                                (subY)
1714                 , m_subW                                (subW)
1715                 , m_subH                                (subH)
1716                 , m_alignment                   (alignment)
1717         {
1718                 glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat);
1719                 m_format        = fmt.format;
1720                 m_dataType      = fmt.dataType;
1721         }
1722
1723 protected:
1724         void createTexture (void)
1725         {
1726                 deUint32                        tex                     = 0;
1727                 vector<deUint8>         data;
1728
1729                 glGenTextures(1, &tex);
1730                 glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
1731
1732                 // Specify base level.
1733                 data.resize(m_texFormat.getPixelSize()*m_size*m_size);
1734                 tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_size, m_size, 1, &data[0]), Vec4(0.0f), Vec4(1.0f));
1735
1736                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1737                 for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
1738                         glTexImage2D(s_cubeMapFaces[face], 0, m_internalFormat, m_size, m_size, 0, m_format, m_dataType, &data[0]);
1739
1740                 // Re-specify subrectangle.
1741                 int rowPitch = deAlign32(m_texFormat.getPixelSize()*m_subW, m_alignment);
1742                 data.resize(rowPitch*m_subH);
1743                 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));
1744
1745                 glPixelStorei(GL_UNPACK_ALIGNMENT, m_alignment);
1746                 for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
1747                         glTexSubImage2D(s_cubeMapFaces[face], 0, m_subX, m_subY, m_subW, m_subH, m_format, m_dataType, &data[0]);
1748         }
1749
1750         deUint32        m_internalFormat;
1751         deUint32        m_format;
1752         deUint32        m_dataType;
1753         int                     m_subX;
1754         int                     m_subY;
1755         int                     m_subW;
1756         int                     m_subH;
1757         int                     m_alignment;
1758 };
1759
1760 // TexSubImage3D() unpack parameters case.
1761 class TexSubImage3DParamsCase : public Texture3DSpecCase
1762 {
1763 public:
1764         TexSubImage3DParamsCase (Context&               context,
1765                                                          const char*    name,
1766                                                          const char*    desc,
1767                                                          deUint32               internalFormat,
1768                                                          int                    width,
1769                                                          int                    height,
1770                                                          int                    depth,
1771                                                          int                    subX,
1772                                                          int                    subY,
1773                                                          int                    subZ,
1774                                                          int                    subW,
1775                                                          int                    subH,
1776                                                          int                    subD,
1777                                                          int                    imageHeight,
1778                                                          int                    rowLength,
1779                                                          int                    skipImages,
1780                                                          int                    skipRows,
1781                                                          int                    skipPixels,
1782                                                          int                    alignment)
1783                 : Texture3DSpecCase     (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, depth, 1)
1784                 , m_internalFormat      (internalFormat)
1785                 , m_subX                        (subX)
1786                 , m_subY                        (subY)
1787                 , m_subZ                        (subZ)
1788                 , m_subW                        (subW)
1789                 , m_subH                        (subH)
1790                 , m_subD                        (subD)
1791                 , m_imageHeight         (imageHeight)
1792                 , m_rowLength           (rowLength)
1793                 , m_skipImages          (skipImages)
1794                 , m_skipRows            (skipRows)
1795                 , m_skipPixels          (skipPixels)
1796                 , m_alignment           (alignment)
1797         {
1798         }
1799
1800 protected:
1801         void createTexture (void)
1802         {
1803                 glu::TransferFormat             transferFmt             = glu::getTransferFormat(m_texFormat);
1804                 int                                             pixelSize               = m_texFormat.getPixelSize();
1805                 deUint32                                tex                             = 0;
1806                 vector<deUint8>                 data;
1807
1808                 DE_ASSERT(m_numLevels == 1);
1809
1810                 glGenTextures(1, &tex);
1811                 glBindTexture(GL_TEXTURE_3D, tex);
1812
1813                 // Fill with gradient.
1814                 {
1815                         int             rowPitch                = deAlign32(pixelSize*m_width,  4);
1816                         int             slicePitch              = rowPitch*m_height;
1817
1818                         data.resize(slicePitch*m_depth);
1819                         tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, m_depth, rowPitch, slicePitch, &data[0]), m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
1820                 }
1821
1822                 glTexImage3D(GL_TEXTURE_3D, 0, m_internalFormat, m_width, m_height, m_depth, 0, transferFmt.format, transferFmt.dataType, &data[0]);
1823
1824                 // Fill data with grid.
1825                 {
1826                         int             rowLength               = m_rowLength > 0 ? m_rowLength : m_subW;
1827                         int             rowPitch                = deAlign32(rowLength*pixelSize, m_alignment);
1828                         int             imageHeight             = m_imageHeight > 0 ? m_imageHeight : m_subH;
1829                         int             slicePitch              = imageHeight*rowPitch;
1830                         Vec4    cScale                  = m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
1831                         Vec4    cBias                   = m_texFormatInfo.valueMin;
1832                         Vec4    colorA                  = Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
1833                         Vec4    colorB                  = Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
1834
1835                         data.resize(slicePitch*(m_depth+m_skipImages));
1836                         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);
1837                 }
1838
1839                 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT,   m_imageHeight);
1840                 glPixelStorei(GL_UNPACK_ROW_LENGTH,             m_rowLength);
1841                 glPixelStorei(GL_UNPACK_SKIP_IMAGES,    m_skipImages);
1842                 glPixelStorei(GL_UNPACK_SKIP_ROWS,              m_skipRows);
1843                 glPixelStorei(GL_UNPACK_SKIP_PIXELS,    m_skipPixels);
1844                 glPixelStorei(GL_UNPACK_ALIGNMENT,              m_alignment);
1845                 glTexSubImage3D(GL_TEXTURE_3D, 0, m_subX, m_subY, m_subZ, m_subW, m_subH, m_subD, transferFmt.format, transferFmt.dataType, &data[0]);
1846         }
1847
1848         deUint32        m_internalFormat;
1849         int                     m_subX;
1850         int                     m_subY;
1851         int                     m_subZ;
1852         int                     m_subW;
1853         int                     m_subH;
1854         int                     m_subD;
1855         int                     m_imageHeight;
1856         int                     m_rowLength;
1857         int                     m_skipImages;
1858         int                     m_skipRows;
1859         int                     m_skipPixels;
1860         int                     m_alignment;
1861 };
1862
1863 // Basic CopyTexImage2D() with 2D texture usage
1864 class BasicCopyTexImage2DCase : public Texture2DSpecCase
1865 {
1866 public:
1867         BasicCopyTexImage2DCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height)
1868                 : Texture2DSpecCase     (context, name, desc, glu::mapGLTransferFormat(internalFormat, GL_UNSIGNED_BYTE), width, height, maxLevelCount(width, height))
1869                 , m_internalFormat      (internalFormat)
1870         {
1871         }
1872
1873 protected:
1874         void createTexture (void)
1875         {
1876                 const tcu::RenderTarget&        renderTarget    = TestCase::m_context.getRenderContext().getRenderTarget();
1877                 bool                                            targetHasRGB    = renderTarget.getPixelFormat().redBits > 0 && renderTarget.getPixelFormat().greenBits > 0 && renderTarget.getPixelFormat().blueBits > 0;
1878                 bool                                            targetHasAlpha  = renderTarget.getPixelFormat().alphaBits > 0;
1879                 tcu::TextureFormat                      fmt                             = mapGLUnsizedInternalFormat(m_internalFormat);
1880                 bool                                            texHasRGB               = fmt.order != tcu::TextureFormat::A;
1881                 bool                                            texHasAlpha             = fmt.order == tcu::TextureFormat::RGBA || fmt.order == tcu::TextureFormat::LA || fmt.order == tcu::TextureFormat::A;
1882                 deUint32                                        tex                             = 0;
1883                 de::Random                                      rnd                             (deStringHash(getName()));
1884                 GradientShader                          shader                  (glu::TYPE_FLOAT_VEC4);
1885                 deUint32                                        shaderID                = getCurrentContext()->createProgram(&shader);
1886
1887                 if ((texHasRGB && !targetHasRGB) || (texHasAlpha && !targetHasAlpha))
1888                         throw tcu::NotSupportedError("Copying from current framebuffer is not supported", "", __FILE__, __LINE__);
1889
1890                 // Fill render target with gradient.
1891                 shader.setGradient(*getCurrentContext(), shaderID, Vec4(0.0f), Vec4(1.0f));
1892                 sglr::drawQuad(*getCurrentContext(), shaderID, tcu::Vec3(-1.0f, -1.0f, 0.0f), tcu::Vec3(1.0f, 1.0f, 0.0f));
1893
1894                 glGenTextures(1, &tex);
1895                 glBindTexture(GL_TEXTURE_2D, tex);
1896
1897                 for (int ndx = 0; ndx < m_numLevels; ndx++)
1898                 {
1899                         int             levelW          = de::max(1, m_width >> ndx);
1900                         int             levelH          = de::max(1, m_height >> ndx);
1901                         int             x                       = rnd.getInt(0, getWidth()      - levelW);
1902                         int             y                       = rnd.getInt(0, getHeight()     - levelH);
1903
1904                         glCopyTexImage2D(GL_TEXTURE_2D, ndx, m_internalFormat, x, y, levelW, levelH, 0);
1905                 }
1906         }
1907
1908         deUint32 m_internalFormat;
1909 };
1910
1911 // Basic CopyTexImage2D() with cubemap usage
1912 class BasicCopyTexImageCubeCase : public TextureCubeSpecCase
1913 {
1914 public:
1915         BasicCopyTexImageCubeCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int size)
1916                 : TextureCubeSpecCase   (context, name, desc, glu::mapGLTransferFormat(internalFormat, GL_UNSIGNED_BYTE), size, deLog2Floor32(size)+1)
1917                 , m_internalFormat              (internalFormat)
1918         {
1919         }
1920
1921 protected:
1922         void createTexture (void)
1923         {
1924                 const tcu::RenderTarget&        renderTarget    = TestCase::m_context.getRenderContext().getRenderTarget();
1925                 bool                                            targetHasRGB    = renderTarget.getPixelFormat().redBits > 0 && renderTarget.getPixelFormat().greenBits > 0 && renderTarget.getPixelFormat().blueBits > 0;
1926                 bool                                            targetHasAlpha  = renderTarget.getPixelFormat().alphaBits > 0;
1927                 tcu::TextureFormat                      fmt                             = mapGLUnsizedInternalFormat(m_internalFormat);
1928                 bool                                            texHasRGB               = fmt.order != tcu::TextureFormat::A;
1929                 bool                                            texHasAlpha             = fmt.order == tcu::TextureFormat::RGBA || fmt.order == tcu::TextureFormat::LA || fmt.order == tcu::TextureFormat::A;
1930                 deUint32                                        tex                             = 0;
1931                 de::Random                                      rnd                             (deStringHash(getName()));
1932                 GradientShader                          shader                  (glu::TYPE_FLOAT_VEC4);
1933                 deUint32                                        shaderID                = getCurrentContext()->createProgram(&shader);
1934
1935                 if ((texHasRGB && !targetHasRGB) || (texHasAlpha && !targetHasAlpha))
1936                         throw tcu::NotSupportedError("Copying from current framebuffer is not supported", "", __FILE__, __LINE__);
1937
1938                 // Fill render target with gradient.
1939                 shader.setGradient(*getCurrentContext(), shaderID, Vec4(0.0f), Vec4(1.0f));
1940                 sglr::drawQuad(*getCurrentContext(), shaderID, tcu::Vec3(-1.0f, -1.0f, 0.0f), tcu::Vec3(1.0f, 1.0f, 0.0f));
1941
1942                 glGenTextures(1, &tex);
1943                 glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
1944
1945                 for (int ndx = 0; ndx < m_numLevels; ndx++)
1946                 {
1947                         int levelSize = de::max(1, m_size >> ndx);
1948
1949                         for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
1950                         {
1951                                 int x = rnd.getInt(0, getWidth()        - levelSize);
1952                                 int y = rnd.getInt(0, getHeight()       - levelSize);
1953
1954                                 glCopyTexImage2D(s_cubeMapFaces[face], ndx, m_internalFormat, x, y, levelSize, levelSize, 0);
1955                         }
1956                 }
1957         }
1958
1959         deUint32 m_internalFormat;
1960 };
1961
1962 // Basic CopyTexSubImage2D() with 2D texture usage
1963 class BasicCopyTexSubImage2DCase : public Texture2DSpecCase
1964 {
1965 public:
1966         BasicCopyTexSubImage2DCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int width, int height)
1967                 : Texture2DSpecCase     (context, name, desc, glu::mapGLTransferFormat(format, dataType), width, height, maxLevelCount(width, height))
1968                 , m_format                      (format)
1969                 , m_dataType            (dataType)
1970         {
1971         }
1972
1973 protected:
1974         void createTexture (void)
1975         {
1976                 const tcu::RenderTarget&        renderTarget    = TestCase::m_context.getRenderContext().getRenderTarget();
1977                 bool                                            targetHasRGB    = renderTarget.getPixelFormat().redBits > 0 && renderTarget.getPixelFormat().greenBits > 0 && renderTarget.getPixelFormat().blueBits > 0;
1978                 bool                                            targetHasAlpha  = renderTarget.getPixelFormat().alphaBits > 0;
1979                 tcu::TextureFormat                      fmt                             = glu::mapGLTransferFormat(m_format, m_dataType);
1980                 bool                                            texHasRGB               = fmt.order != tcu::TextureFormat::A;
1981                 bool                                            texHasAlpha             = fmt.order == tcu::TextureFormat::RGBA || fmt.order == tcu::TextureFormat::LA || fmt.order == tcu::TextureFormat::A;
1982                 deUint32                                        tex                             = 0;
1983                 tcu::TextureLevel                       data                    (fmt);
1984                 de::Random                                      rnd                             (deStringHash(getName()));
1985                 GradientShader                          shader                  (glu::TYPE_FLOAT_VEC4);
1986                 deUint32                                        shaderID                = getCurrentContext()->createProgram(&shader);
1987
1988                 if ((texHasRGB && !targetHasRGB) || (texHasAlpha && !targetHasAlpha))
1989                         throw tcu::NotSupportedError("Copying from current framebuffer is not supported", "", __FILE__, __LINE__);
1990
1991                 glGenTextures(1, &tex);
1992                 glBindTexture(GL_TEXTURE_2D, tex);
1993                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1994
1995                 // First specify full texture.
1996                 for (int ndx = 0; ndx < m_numLevels; ndx++)
1997                 {
1998                         int             levelW          = de::max(1, m_width >> ndx);
1999                         int             levelH          = de::max(1, m_height >> ndx);
2000
2001                         Vec4    colorA          = randomVector<4>(rnd);
2002                         Vec4    colorB          = randomVector<4>(rnd);
2003                         int             cellSize        = rnd.getInt(2, 16);
2004
2005                         data.setSize(levelW, levelH);
2006                         tcu::fillWithGrid(data.getAccess(), cellSize, colorA, colorB);
2007
2008                         glTexImage2D(GL_TEXTURE_2D, ndx, m_format, levelW, levelH, 0, m_format, m_dataType, data.getAccess().getDataPtr());
2009                 }
2010
2011                 // Fill render target with gradient.
2012                 shader.setGradient(*getCurrentContext(), shaderID, Vec4(0.0f), Vec4(1.0f));
2013                 sglr::drawQuad(*getCurrentContext(), shaderID, tcu::Vec3(-1.0f, -1.0f, 0.0f), tcu::Vec3(1.0f, 1.0f, 0.0f));
2014
2015                 // Re-specify parts of each level.
2016                 for (int ndx = 0; ndx < m_numLevels; ndx++)
2017                 {
2018                         int             levelW          = de::max(1, m_width >> ndx);
2019                         int             levelH          = de::max(1, m_height >> ndx);
2020
2021                         int             w                       = rnd.getInt(1, levelW);
2022                         int             h                       = rnd.getInt(1, levelH);
2023                         int             xo                      = rnd.getInt(0, levelW-w);
2024                         int             yo                      = rnd.getInt(0, levelH-h);
2025
2026                         int             x                       = rnd.getInt(0, getWidth() - w);
2027                         int             y                       = rnd.getInt(0, getHeight() - h);
2028
2029                         glCopyTexSubImage2D(GL_TEXTURE_2D, ndx, xo, yo, x, y, w, h);
2030                 }
2031         }
2032
2033         deUint32        m_format;
2034         deUint32        m_dataType;
2035 };
2036
2037 // Basic CopyTexSubImage2D() with cubemap usage
2038 class BasicCopyTexSubImageCubeCase : public TextureCubeSpecCase
2039 {
2040 public:
2041         BasicCopyTexSubImageCubeCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int size)
2042                 : TextureCubeSpecCase   (context, name, desc, glu::mapGLTransferFormat(format, dataType), size, deLog2Floor32(size)+1)
2043                 , m_format                              (format)
2044                 , m_dataType                    (dataType)
2045         {
2046         }
2047
2048 protected:
2049         void createTexture (void)
2050         {
2051                 const tcu::RenderTarget&        renderTarget    = TestCase::m_context.getRenderContext().getRenderTarget();
2052                 bool                                            targetHasRGB    = renderTarget.getPixelFormat().redBits > 0 && renderTarget.getPixelFormat().greenBits > 0 && renderTarget.getPixelFormat().blueBits > 0;
2053                 bool                                            targetHasAlpha  = renderTarget.getPixelFormat().alphaBits > 0;
2054                 tcu::TextureFormat                      fmt                             = glu::mapGLTransferFormat(m_format, m_dataType);
2055                 bool                                            texHasRGB               = fmt.order != tcu::TextureFormat::A;
2056                 bool                                            texHasAlpha             = fmt.order == tcu::TextureFormat::RGBA || fmt.order == tcu::TextureFormat::LA || fmt.order == tcu::TextureFormat::A;
2057                 deUint32                                        tex                             = 0;
2058                 tcu::TextureLevel                       data                    (fmt);
2059                 de::Random                                      rnd                             (deStringHash(getName()));
2060                 GradientShader                          shader                  (glu::TYPE_FLOAT_VEC4);
2061                 deUint32                                        shaderID                = getCurrentContext()->createProgram(&shader);
2062
2063                 if ((texHasRGB && !targetHasRGB) || (texHasAlpha && !targetHasAlpha))
2064                         throw tcu::NotSupportedError("Copying from current framebuffer is not supported", "", __FILE__, __LINE__);
2065
2066                 glGenTextures(1, &tex);
2067                 glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
2068                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2069
2070                 for (int ndx = 0; ndx < m_numLevels; ndx++)
2071                 {
2072                         int levelSize = de::max(1, m_size >> ndx);
2073
2074                         data.setSize(levelSize, levelSize);
2075
2076                         for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
2077                         {
2078                                 Vec4    colorA          = randomVector<4>(rnd);
2079                                 Vec4    colorB          = randomVector<4>(rnd);
2080                                 int             cellSize        = rnd.getInt(2, 16);
2081
2082                                 tcu::fillWithGrid(data.getAccess(), cellSize, colorA, colorB);
2083                                 glTexImage2D(s_cubeMapFaces[face], ndx, m_format, levelSize, levelSize, 0, m_format, m_dataType, data.getAccess().getDataPtr());
2084                         }
2085                 }
2086
2087                 // Fill render target with gradient.
2088                 shader.setGradient(*getCurrentContext(), shaderID, Vec4(0.0f), Vec4(1.0f));
2089                 sglr::drawQuad(*getCurrentContext(), shaderID, tcu::Vec3(-1.0f, -1.0f, 0.0f), tcu::Vec3(1.0f, 1.0f, 0.0f));
2090
2091                 // Re-specify parts of each face and level.
2092                 for (int ndx = 0; ndx < m_numLevels; ndx++)
2093                 {
2094                         int levelSize = de::max(1, m_size >> ndx);
2095
2096                         for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
2097                         {
2098                                 int             w                       = rnd.getInt(1, levelSize);
2099                                 int             h                       = rnd.getInt(1, levelSize);
2100                                 int             xo                      = rnd.getInt(0, levelSize-w);
2101                                 int             yo                      = rnd.getInt(0, levelSize-h);
2102
2103                                 int             x                       = rnd.getInt(0, getWidth() - w);
2104                                 int             y                       = rnd.getInt(0, getHeight() - h);
2105
2106                                 glCopyTexSubImage2D(s_cubeMapFaces[face], ndx, xo, yo, x, y, w, h);
2107                         }
2108                 }
2109         }
2110
2111         deUint32        m_format;
2112         deUint32        m_dataType;
2113 };
2114
2115 // Basic glTexStorage2D() with 2D texture usage
2116 class BasicTexStorage2DCase : public Texture2DSpecCase
2117 {
2118 public:
2119         BasicTexStorage2DCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height, int numLevels)
2120                 : Texture2DSpecCase     (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, numLevels)
2121                 , m_internalFormat      (internalFormat)
2122         {
2123         }
2124
2125 protected:
2126         void createTexture (void)
2127         {
2128                 tcu::TextureFormat              fmt                             = glu::mapGLInternalFormat(m_internalFormat);
2129                 glu::TransferFormat             transferFmt             = glu::getTransferFormat(fmt);
2130                 deUint32                                tex                             = 0;
2131                 tcu::TextureLevel               levelData               (glu::mapGLTransferFormat(transferFmt.format, transferFmt.dataType));
2132                 de::Random                              rnd                             (deStringHash(getName()));
2133
2134                 glGenTextures(1, &tex);
2135                 glBindTexture(GL_TEXTURE_2D, tex);
2136                 glTexStorage2D(GL_TEXTURE_2D, m_numLevels, m_internalFormat, m_width, m_height);
2137
2138                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2139
2140                 for (int ndx = 0; ndx < m_numLevels; ndx++)
2141                 {
2142                         int             levelW          = de::max(1, m_width >> ndx);
2143                         int             levelH          = de::max(1, m_height >> ndx);
2144                         Vec4    gMin            = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
2145                         Vec4    gMax            = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
2146
2147                         levelData.setSize(levelW, levelH);
2148                         tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
2149
2150                         glTexSubImage2D(GL_TEXTURE_2D, ndx, 0, 0, levelW, levelH, transferFmt.format, transferFmt.dataType, levelData.getAccess().getDataPtr());
2151                 }
2152         }
2153
2154         deUint32 m_internalFormat;
2155 };
2156
2157 // Basic glTexStorage2D() with cubemap usage
2158 class BasicTexStorageCubeCase : public TextureCubeSpecCase
2159 {
2160 public:
2161         BasicTexStorageCubeCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int size, int numLevels)
2162                 : TextureCubeSpecCase   (context, name, desc, glu::mapGLInternalFormat(internalFormat), size, numLevels)
2163                 , m_internalFormat              (internalFormat)
2164         {
2165         }
2166
2167 protected:
2168         void createTexture (void)
2169         {
2170                 tcu::TextureFormat              fmt                             = glu::mapGLInternalFormat(m_internalFormat);
2171                 glu::TransferFormat             transferFmt             = glu::getTransferFormat(fmt);
2172                 deUint32                                tex                             = 0;
2173                 tcu::TextureLevel               levelData               (glu::mapGLTransferFormat(transferFmt.format, transferFmt.dataType));
2174                 de::Random                              rnd                             (deStringHash(getName()));
2175
2176                 glGenTextures(1, &tex);
2177                 glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
2178                 glTexStorage2D(GL_TEXTURE_CUBE_MAP, m_numLevels, m_internalFormat, m_size, m_size);
2179
2180                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2181
2182                 for (int ndx = 0; ndx < m_numLevels; ndx++)
2183                 {
2184                         int levelSize = de::max(1, m_size >> ndx);
2185
2186                         levelData.setSize(levelSize, levelSize);
2187
2188                         for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
2189                         {
2190                                 Vec4 gMin = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
2191                                 Vec4 gMax = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
2192
2193                                 tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
2194
2195                                 glTexSubImage2D(s_cubeMapFaces[face], ndx, 0, 0, levelSize, levelSize, transferFmt.format, transferFmt.dataType, levelData.getAccess().getDataPtr());
2196                         }
2197                 }
2198         }
2199
2200         deUint32 m_internalFormat;
2201 };
2202
2203 // Basic glTexStorage3D() with 2D array texture usage
2204 class BasicTexStorage2DArrayCase : public Texture2DArraySpecCase
2205 {
2206 public:
2207         BasicTexStorage2DArrayCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height, int numLayers, int numLevels)
2208                 : Texture2DArraySpecCase        (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, numLayers, numLevels)
2209                 , m_internalFormat                      (internalFormat)
2210         {
2211         }
2212
2213 protected:
2214         void createTexture (void)
2215         {
2216                 deUint32                                tex                     = 0;
2217                 de::Random                              rnd                     (deStringHash(getName()));
2218                 glu::TransferFormat             transferFmt     = glu::getTransferFormat(m_texFormat);
2219                 tcu::TextureLevel               levelData       (glu::mapGLTransferFormat(transferFmt.format, transferFmt.dataType));
2220
2221                 glGenTextures   (1, &tex);
2222                 glBindTexture   (GL_TEXTURE_2D_ARRAY, tex);
2223                 glTexStorage3D  (GL_TEXTURE_2D_ARRAY, m_numLevels, m_internalFormat, m_width, m_height, m_numLayers);
2224
2225                 glPixelStorei   (GL_UNPACK_ALIGNMENT, 1);
2226
2227                 for (int ndx = 0; ndx < m_numLevels; ndx++)
2228                 {
2229                         int             levelW          = de::max(1, m_width    >> ndx);
2230                         int             levelH          = de::max(1, m_height   >> ndx);
2231                         Vec4    gMin            = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
2232                         Vec4    gMax            = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
2233
2234                         levelData.setSize(levelW, levelH, m_numLayers);
2235                         tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
2236
2237                         glTexSubImage3D(GL_TEXTURE_2D_ARRAY, ndx, 0, 0, 0, levelW, levelH, m_numLayers, transferFmt.format, transferFmt.dataType, levelData.getAccess().getDataPtr());
2238                 }
2239         }
2240
2241         deUint32 m_internalFormat;
2242 };
2243
2244 // Basic TexStorage3D() with 3D texture usage
2245 class BasicTexStorage3DCase : public Texture3DSpecCase
2246 {
2247 public:
2248         BasicTexStorage3DCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height, int depth, int numLevels)
2249                 : Texture3DSpecCase     (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, depth, numLevels)
2250                 , m_internalFormat      (internalFormat)
2251         {
2252         }
2253
2254 protected:
2255         void createTexture (void)
2256         {
2257                 deUint32                                tex                     = 0;
2258                 de::Random                              rnd                     (deStringHash(getName()));
2259                 glu::TransferFormat             transferFmt     = glu::getTransferFormat(m_texFormat);
2260                 tcu::TextureLevel               levelData       (glu::mapGLTransferFormat(transferFmt.format, transferFmt.dataType));
2261
2262                 glGenTextures   (1, &tex);
2263                 glBindTexture   (GL_TEXTURE_3D, tex);
2264                 glTexStorage3D  (GL_TEXTURE_3D, m_numLevels, m_internalFormat, m_width, m_height, m_depth);
2265
2266                 glPixelStorei   (GL_UNPACK_ALIGNMENT, 1);
2267
2268                 for (int ndx = 0; ndx < m_numLevels; ndx++)
2269                 {
2270                         int             levelW          = de::max(1, m_width    >> ndx);
2271                         int             levelH          = de::max(1, m_height   >> ndx);
2272                         int             levelD          = de::max(1, m_depth    >> ndx);
2273                         Vec4    gMin            = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
2274                         Vec4    gMax            = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
2275
2276                         levelData.setSize(levelW, levelH, levelD);
2277                         tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
2278
2279                         glTexSubImage3D(GL_TEXTURE_3D, ndx, 0, 0, 0, levelW, levelH, levelD, transferFmt.format, transferFmt.dataType, levelData.getAccess().getDataPtr());
2280                 }
2281         }
2282
2283         deUint32 m_internalFormat;
2284 };
2285
2286 // Pixel buffer object cases.
2287
2288 // TexImage2D() from pixel buffer object.
2289 class TexImage2DBufferCase : public Texture2DSpecCase
2290 {
2291 public:
2292         TexImage2DBufferCase (Context&          context,
2293                                                   const char*   name,
2294                                                   const char*   desc,
2295                                                   deUint32              internalFormat,
2296                                                   int                   width,
2297                                                   int                   height,
2298                                                   int                   rowLength,
2299                                                   int                   skipRows,
2300                                                   int                   skipPixels,
2301                                                   int                   alignment,
2302                                                   int                   offset)
2303                 : Texture2DSpecCase     (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, 1)
2304                 , m_internalFormat      (internalFormat)
2305                 , m_rowLength           (rowLength)
2306                 , m_skipRows            (skipRows)
2307                 , m_skipPixels          (skipPixels)
2308                 , m_alignment           (alignment)
2309                 , m_offset                      (offset)
2310         {
2311         }
2312
2313 protected:
2314         void createTexture (void)
2315         {
2316                 glu::TransferFormat             transferFmt             = glu::getTransferFormat(m_texFormat);
2317                 int                                             pixelSize               = m_texFormat.getPixelSize();
2318                 int                                             rowLength               = m_rowLength > 0 ? m_rowLength : m_width + m_skipPixels;
2319                 int                                             rowPitch                = deAlign32(rowLength*pixelSize, m_alignment);
2320                 int                                             height                  = m_height + m_skipRows;
2321                 deUint32                                buf                             = 0;
2322                 deUint32                                tex                             = 0;
2323                 vector<deUint8>                 data;
2324
2325                 DE_ASSERT(m_numLevels == 1);
2326
2327                 // Fill data with grid.
2328                 data.resize(rowPitch*height + m_offset);
2329                 {
2330                         Vec4    cScale          = m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
2331                         Vec4    cBias           = m_texFormatInfo.valueMin;
2332                         Vec4    colorA          = Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
2333                         Vec4    colorB          = Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
2334
2335                         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);
2336                 }
2337
2338                 // Create buffer and upload.
2339                 glGenBuffers(1, &buf);
2340                 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf);
2341                 glBufferData(GL_PIXEL_UNPACK_BUFFER, (int)data.size(), &data[0], GL_STATIC_DRAW);
2342
2343                 glPixelStorei(GL_UNPACK_ROW_LENGTH,             m_rowLength);
2344                 glPixelStorei(GL_UNPACK_SKIP_ROWS,              m_skipRows);
2345                 glPixelStorei(GL_UNPACK_SKIP_PIXELS,    m_skipPixels);
2346                 glPixelStorei(GL_UNPACK_ALIGNMENT,              m_alignment);
2347
2348                 glGenTextures(1, &tex);
2349                 glBindTexture(GL_TEXTURE_2D, tex);
2350                 glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_width, m_height, 0, transferFmt.format, transferFmt.dataType, (const void*)(deUintptr)m_offset);
2351         }
2352
2353         deUint32        m_internalFormat;
2354         int                     m_rowLength;
2355         int                     m_skipRows;
2356         int                     m_skipPixels;
2357         int                     m_alignment;
2358         int                     m_offset;
2359 };
2360
2361 // TexImage2D() cubemap from pixel buffer object case
2362 class TexImageCubeBufferCase : public TextureCubeSpecCase
2363 {
2364 public:
2365         TexImageCubeBufferCase (Context&        context,
2366                                                         const char*     name,
2367                                                         const char*     desc,
2368                                                         deUint32        internalFormat,
2369                                                         int                     size,
2370                                                         int                     rowLength,
2371                                                         int                     skipRows,
2372                                                         int                     skipPixels,
2373                                                         int                     alignment,
2374                                                         int                     offset)
2375                 : TextureCubeSpecCase   (context, name, desc, glu::mapGLInternalFormat(internalFormat), size, 1)
2376                 , m_internalFormat              (internalFormat)
2377                 , m_rowLength                   (rowLength)
2378                 , m_skipRows                    (skipRows)
2379                 , m_skipPixels                  (skipPixels)
2380                 , m_alignment                   (alignment)
2381                 , m_offset                              (offset)
2382         {
2383         }
2384
2385 protected:
2386         void createTexture (void)
2387         {
2388                 de::Random                                      rnd                     (deStringHash(getName()));
2389                 deUint32                                        tex                     = 0;
2390                 glu::TransferFormat                     fmt                     = glu::getTransferFormat(m_texFormat);
2391                 const int                                       pixelSize       = m_texFormat.getPixelSize();
2392                 const int                                       rowLength       = m_rowLength > 0 ? m_rowLength : m_size + m_skipPixels;
2393                 const int                                       rowPitch        = deAlign32(rowLength*pixelSize, m_alignment);
2394                 const int                                       height          = m_size + m_skipRows;
2395                 vector<vector<deUint8> >        data            (DE_LENGTH_OF_ARRAY(s_cubeMapFaces));
2396
2397                 DE_ASSERT(m_numLevels == 1);
2398
2399                 glGenTextures(1, &tex);
2400                 glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
2401                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2402
2403                 for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
2404                 {
2405                         deUint32 buf = 0;
2406
2407                         {
2408                                 const Vec4 gMin = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
2409                                 const Vec4 gMax = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
2410
2411                                 data[face].resize(rowPitch*height + m_offset);
2412                                 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);
2413                         }
2414
2415                         // Create buffer and upload.
2416                         glGenBuffers(1, &buf);
2417                         glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf);
2418                         glBufferData(GL_PIXEL_UNPACK_BUFFER, (int)data[face].size(), &data[face][0], GL_STATIC_DRAW);
2419
2420                         glPixelStorei(GL_UNPACK_ROW_LENGTH,             m_rowLength);
2421                         glPixelStorei(GL_UNPACK_SKIP_ROWS,              m_skipRows);
2422                         glPixelStorei(GL_UNPACK_SKIP_PIXELS,    m_skipPixels);
2423                         glPixelStorei(GL_UNPACK_ALIGNMENT,              m_alignment);
2424
2425                         glTexImage2D(s_cubeMapFaces[face], 0, m_internalFormat, m_size, m_size, 0, fmt.format, fmt.dataType, (const void*)(deUintptr)m_offset);
2426                 }
2427         }
2428
2429         deUint32        m_internalFormat;
2430         int                     m_rowLength;
2431         int                     m_skipRows;
2432         int                     m_skipPixels;
2433         int                     m_alignment;
2434         int                     m_offset;
2435 };
2436
2437 // TexImage3D() 2D array from pixel buffer object.
2438 class TexImage2DArrayBufferCase : public Texture2DArraySpecCase
2439 {
2440 public:
2441         TexImage2DArrayBufferCase (Context&             context,
2442                                                            const char*  name,
2443                                                            const char*  desc,
2444                                                            deUint32             internalFormat,
2445                                                            int                  width,
2446                                                            int                  height,
2447                                                            int                  depth,
2448                                                            int                  imageHeight,
2449                                                            int                  rowLength,
2450                                                            int                  skipImages,
2451                                                            int                  skipRows,
2452                                                            int                  skipPixels,
2453                                                            int                  alignment,
2454                                                            int                  offset)
2455                 : Texture2DArraySpecCase        (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, depth, 1)
2456                 , m_internalFormat                      (internalFormat)
2457                 , m_imageHeight                         (imageHeight)
2458                 , m_rowLength                           (rowLength)
2459                 , m_skipImages                          (skipImages)
2460                 , m_skipRows                            (skipRows)
2461                 , m_skipPixels                          (skipPixels)
2462                 , m_alignment                           (alignment)
2463                 , m_offset                                      (offset)
2464         {
2465         }
2466
2467 protected:
2468         void createTexture (void)
2469         {
2470                 glu::TransferFormat             transferFmt             = glu::getTransferFormat(m_texFormat);
2471                 int                                             pixelSize               = m_texFormat.getPixelSize();
2472                 int                                             rowLength               = m_rowLength > 0 ? m_rowLength : m_width;
2473                 int                                             rowPitch                = deAlign32(rowLength*pixelSize, m_alignment);
2474                 int                                             imageHeight             = m_imageHeight > 0 ? m_imageHeight : m_height;
2475                 int                                             slicePitch              = imageHeight*rowPitch;
2476                 deUint32                                tex                             = 0;
2477                 deUint32                                buf                             = 0;
2478                 vector<deUint8>                 data;
2479
2480                 DE_ASSERT(m_numLevels == 1);
2481
2482                 // Fill data with grid.
2483                 data.resize(slicePitch*(m_numLayers+m_skipImages) + m_offset);
2484                 {
2485                         Vec4    cScale          = m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
2486                         Vec4    cBias           = m_texFormatInfo.valueMin;
2487                         Vec4    colorA          = Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
2488                         Vec4    colorB          = Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
2489
2490                         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);
2491                 }
2492
2493                 glGenBuffers(1, &buf);
2494                 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf);
2495                 glBufferData(GL_PIXEL_UNPACK_BUFFER, (int)data.size(), &data[0], GL_STATIC_DRAW);
2496
2497                 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT,   m_imageHeight);
2498                 glPixelStorei(GL_UNPACK_ROW_LENGTH,             m_rowLength);
2499                 glPixelStorei(GL_UNPACK_SKIP_IMAGES,    m_skipImages);
2500                 glPixelStorei(GL_UNPACK_SKIP_ROWS,              m_skipRows);
2501                 glPixelStorei(GL_UNPACK_SKIP_PIXELS,    m_skipPixels);
2502                 glPixelStorei(GL_UNPACK_ALIGNMENT,              m_alignment);
2503
2504                 glGenTextures(1, &tex);
2505                 glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
2506                 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, m_internalFormat, m_width, m_height, m_numLayers, 0, transferFmt.format, transferFmt.dataType, (const void*)(deUintptr)m_offset);
2507         }
2508
2509         deUint32        m_internalFormat;
2510         int                     m_imageHeight;
2511         int                     m_rowLength;
2512         int                     m_skipImages;
2513         int                     m_skipRows;
2514         int                     m_skipPixels;
2515         int                     m_alignment;
2516         int                     m_offset;
2517 };
2518
2519 // TexImage3D() from pixel buffer object.
2520 class TexImage3DBufferCase : public Texture3DSpecCase
2521 {
2522 public:
2523         TexImage3DBufferCase (Context&          context,
2524                                                   const char*   name,
2525                                                   const char*   desc,
2526                                                   deUint32              internalFormat,
2527                                                   int                   width,
2528                                                   int                   height,
2529                                                   int                   depth,
2530                                                   int                   imageHeight,
2531                                                   int                   rowLength,
2532                                                   int                   skipImages,
2533                                                   int                   skipRows,
2534                                                   int                   skipPixels,
2535                                                   int                   alignment,
2536                                                   int                   offset)
2537                 : Texture3DSpecCase     (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, depth, 1)
2538                 , m_internalFormat      (internalFormat)
2539                 , m_imageHeight         (imageHeight)
2540                 , m_rowLength           (rowLength)
2541                 , m_skipImages          (skipImages)
2542                 , m_skipRows            (skipRows)
2543                 , m_skipPixels          (skipPixels)
2544                 , m_alignment           (alignment)
2545                 , m_offset                      (offset)
2546         {
2547         }
2548
2549 protected:
2550         void createTexture (void)
2551         {
2552                 glu::TransferFormat             transferFmt             = glu::getTransferFormat(m_texFormat);
2553                 int                                             pixelSize               = m_texFormat.getPixelSize();
2554                 int                                             rowLength               = m_rowLength > 0 ? m_rowLength : m_width;
2555                 int                                             rowPitch                = deAlign32(rowLength*pixelSize, m_alignment);
2556                 int                                             imageHeight             = m_imageHeight > 0 ? m_imageHeight : m_height;
2557                 int                                             slicePitch              = imageHeight*rowPitch;
2558                 deUint32                                tex                             = 0;
2559                 deUint32                                buf                             = 0;
2560                 vector<deUint8>                 data;
2561
2562                 DE_ASSERT(m_numLevels == 1);
2563
2564                 // Fill data with grid.
2565                 data.resize(slicePitch*(m_depth+m_skipImages) + m_offset);
2566                 {
2567                         Vec4    cScale          = m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
2568                         Vec4    cBias           = m_texFormatInfo.valueMin;
2569                         Vec4    colorA          = Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
2570                         Vec4    colorB          = Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
2571
2572                         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);
2573                 }
2574
2575                 glGenBuffers(1, &buf);
2576                 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf);
2577                 glBufferData(GL_PIXEL_UNPACK_BUFFER, (int)data.size(), &data[0], GL_STATIC_DRAW);
2578
2579                 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT,   m_imageHeight);
2580                 glPixelStorei(GL_UNPACK_ROW_LENGTH,             m_rowLength);
2581                 glPixelStorei(GL_UNPACK_SKIP_IMAGES,    m_skipImages);
2582                 glPixelStorei(GL_UNPACK_SKIP_ROWS,              m_skipRows);
2583                 glPixelStorei(GL_UNPACK_SKIP_PIXELS,    m_skipPixels);
2584                 glPixelStorei(GL_UNPACK_ALIGNMENT,              m_alignment);
2585
2586                 glGenTextures(1, &tex);
2587                 glBindTexture(GL_TEXTURE_3D, tex);
2588                 glTexImage3D(GL_TEXTURE_3D, 0, m_internalFormat, m_width, m_height, m_depth, 0, transferFmt.format, transferFmt.dataType, (const void*)(deUintptr)m_offset);
2589         }
2590
2591         deUint32        m_internalFormat;
2592         int                     m_imageHeight;
2593         int                     m_rowLength;
2594         int                     m_skipImages;
2595         int                     m_skipRows;
2596         int                     m_skipPixels;
2597         int                     m_alignment;
2598         int                     m_offset;
2599 };
2600
2601 // TexSubImage2D() PBO case.
2602 class TexSubImage2DBufferCase : public Texture2DSpecCase
2603 {
2604 public:
2605         TexSubImage2DBufferCase (Context&               context,
2606                                                          const char*    name,
2607                                                          const char*    desc,
2608                                                          deUint32               internalFormat,
2609                                                          int                    width,
2610                                                          int                    height,
2611                                                          int                    subX,
2612                                                          int                    subY,
2613                                                          int                    subW,
2614                                                          int                    subH,
2615                                                          int                    rowLength,
2616                                                          int                    skipRows,
2617                                                          int                    skipPixels,
2618                                                          int                    alignment,
2619                                                          int                    offset)
2620                 : Texture2DSpecCase     (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, 1)
2621                 , m_internalFormat      (internalFormat)
2622                 , m_subX                        (subX)
2623                 , m_subY                        (subY)
2624                 , m_subW                        (subW)
2625                 , m_subH                        (subH)
2626                 , m_rowLength           (rowLength)
2627                 , m_skipRows            (skipRows)
2628                 , m_skipPixels          (skipPixels)
2629                 , m_alignment           (alignment)
2630                 , m_offset                      (offset)
2631         {
2632         }
2633
2634 protected:
2635         void createTexture (void)
2636         {
2637                 glu::TransferFormat             transferFmt             = glu::getTransferFormat(m_texFormat);
2638                 int                                             pixelSize               = m_texFormat.getPixelSize();
2639                 deUint32                                tex                             = 0;
2640                 deUint32                                buf                             = 0;
2641                 vector<deUint8>                 data;
2642
2643                 DE_ASSERT(m_numLevels == 1);
2644
2645                 glGenTextures(1, &tex);
2646                 glBindTexture(GL_TEXTURE_2D, tex);
2647
2648                 // First fill texture with gradient.
2649                 data.resize(deAlign32(m_width*pixelSize, 4)*m_height);
2650                 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);
2651                 glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_width, m_height, 0, transferFmt.format, transferFmt.dataType, &data[0]);
2652
2653                 // Fill data with grid.
2654                 {
2655                         int             rowLength       = m_rowLength > 0 ? m_rowLength : m_subW;
2656                         int             rowPitch        = deAlign32(rowLength*pixelSize, m_alignment);
2657                         int             height          = m_subH + m_skipRows;
2658                         Vec4    cScale          = m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
2659                         Vec4    cBias           = m_texFormatInfo.valueMin;
2660                         Vec4    colorA          = Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
2661                         Vec4    colorB          = Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
2662
2663                         data.resize(rowPitch*height + m_offset);
2664                         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);
2665                 }
2666
2667                 glGenBuffers(1, &buf);
2668                 glBindBuffer(GL_PIXEL_UNPACK_BUFFER,    buf);
2669                 glBufferData(GL_PIXEL_UNPACK_BUFFER,    (int)data.size(), &data[0], GL_STATIC_DRAW);
2670
2671                 glPixelStorei(GL_UNPACK_ROW_LENGTH,             m_rowLength);
2672                 glPixelStorei(GL_UNPACK_SKIP_ROWS,              m_skipRows);
2673                 glPixelStorei(GL_UNPACK_SKIP_PIXELS,    m_skipPixels);
2674                 glPixelStorei(GL_UNPACK_ALIGNMENT,              m_alignment);
2675                 glTexSubImage2D(GL_TEXTURE_2D, 0, m_subX, m_subY, m_subW, m_subH, transferFmt.format, transferFmt.dataType, (const void*)(deUintptr)m_offset);
2676         }
2677
2678         deUint32        m_internalFormat;
2679         int                     m_subX;
2680         int                     m_subY;
2681         int                     m_subW;
2682         int                     m_subH;
2683         int                     m_rowLength;
2684         int                     m_skipRows;
2685         int                     m_skipPixels;
2686         int                     m_alignment;
2687         int                     m_offset;
2688 };
2689
2690 // TexSubImage2D() cubemap PBO case.
2691 class TexSubImageCubeBufferCase : public TextureCubeSpecCase
2692 {
2693 public:
2694         TexSubImageCubeBufferCase       (Context&               context,
2695                                                                  const char*    name,
2696                                                                  const char*    desc,
2697                                                                  deUint32               internalFormat,
2698                                                                  int                    size,
2699                                                                  int                    subX,
2700                                                                  int                    subY,
2701                                                                  int                    subW,
2702                                                                  int                    subH,
2703                                                                  int                    rowLength,
2704                                                                  int                    skipRows,
2705                                                                  int                    skipPixels,
2706                                                                  int                    alignment,
2707                                                                  int                    offset)
2708                 : TextureCubeSpecCase   (context, name, desc, glu::mapGLInternalFormat(internalFormat), size, 1)
2709                 , m_internalFormat              (internalFormat)
2710                 , m_subX                                (subX)
2711                 , m_subY                                (subY)
2712                 , m_subW                                (subW)
2713                 , m_subH                                (subH)
2714                 , m_rowLength                   (rowLength)
2715                 , m_skipRows                    (skipRows)
2716                 , m_skipPixels                  (skipPixels)
2717                 , m_alignment                   (alignment)
2718                 , m_offset                              (offset)
2719         {
2720         }
2721
2722 protected:
2723         void createTexture (void)
2724         {
2725                 de::Random                              rnd                             (deStringHash(getName()));
2726                 glu::TransferFormat             transferFmt             = glu::getTransferFormat(m_texFormat);
2727                 int                                             pixelSize               = m_texFormat.getPixelSize();
2728                 deUint32                                tex                             = 0;
2729                 deUint32                                buf                             = 0;
2730                 vector<deUint8>                 data;
2731
2732                 DE_ASSERT(m_numLevels == 1);
2733
2734                 glGenTextures(1, &tex);
2735                 glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
2736
2737                 // Fill faces with different gradients.
2738
2739                 data.resize(deAlign32(m_size*pixelSize, 4)*m_size);
2740                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2741
2742                 for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
2743                 {
2744                         const Vec4 gMin = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
2745                         const Vec4 gMax = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
2746
2747                         tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_size, m_size, 1, deAlign32(m_size*pixelSize, 4), 0, &data[0]), gMin, gMax);
2748
2749                         glTexImage2D(s_cubeMapFaces[face], 0, m_internalFormat, m_size, m_size, 0, transferFmt.format, transferFmt.dataType, &data[0]);
2750                 }
2751
2752                 // Fill data with grid.
2753                 {
2754                         int             rowLength       = m_rowLength > 0 ? m_rowLength : m_subW;
2755                         int             rowPitch        = deAlign32(rowLength*pixelSize, m_alignment);
2756                         int             height          = m_subH + m_skipRows;
2757                         Vec4    cScale          = m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
2758                         Vec4    cBias           = m_texFormatInfo.valueMin;
2759                         Vec4    colorA          = Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
2760                         Vec4    colorB          = Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
2761
2762                         data.resize(rowPitch*height + m_offset);
2763                         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);
2764                 }
2765
2766                 glGenBuffers(1, &buf);
2767                 glBindBuffer(GL_PIXEL_UNPACK_BUFFER,    buf);
2768                 glBufferData(GL_PIXEL_UNPACK_BUFFER,    (int)data.size(), &data[0], GL_STATIC_DRAW);
2769
2770                 glPixelStorei(GL_UNPACK_ROW_LENGTH,             m_rowLength);
2771                 glPixelStorei(GL_UNPACK_SKIP_ROWS,              m_skipRows);
2772                 glPixelStorei(GL_UNPACK_SKIP_PIXELS,    m_skipPixels);
2773                 glPixelStorei(GL_UNPACK_ALIGNMENT,              m_alignment);
2774
2775                 for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
2776                         glTexSubImage2D(s_cubeMapFaces[face], 0, m_subX, m_subY, m_subW, m_subH, transferFmt.format, transferFmt.dataType, (const void*)(deUintptr)m_offset);
2777         }
2778
2779         deUint32        m_internalFormat;
2780         int                     m_subX;
2781         int                     m_subY;
2782         int                     m_subW;
2783         int                     m_subH;
2784         int                     m_rowLength;
2785         int                     m_skipRows;
2786         int                     m_skipPixels;
2787         int                     m_alignment;
2788         int                     m_offset;
2789 };
2790
2791 // TexSubImage3D() 2D array PBO case.
2792 class TexSubImage2DArrayBufferCase : public Texture2DArraySpecCase
2793 {
2794 public:
2795         TexSubImage2DArrayBufferCase (Context&          context,
2796                                                                  const char*    name,
2797                                                                  const char*    desc,
2798                                                                  deUint32               internalFormat,
2799                                                                  int                    width,
2800                                                                  int                    height,
2801                                                                  int                    depth,
2802                                                                  int                    subX,
2803                                                                  int                    subY,
2804                                                                  int                    subZ,
2805                                                                  int                    subW,
2806                                                                  int                    subH,
2807                                                                  int                    subD,
2808                                                                  int                    imageHeight,
2809                                                                  int                    rowLength,
2810                                                                  int                    skipImages,
2811                                                                  int                    skipRows,
2812                                                                  int                    skipPixels,
2813                                                                  int                    alignment,
2814                                                                  int                    offset)
2815                 : Texture2DArraySpecCase        (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, depth, 1)
2816                 , m_internalFormat                      (internalFormat)
2817                 , m_subX                                        (subX)
2818                 , m_subY                                        (subY)
2819                 , m_subZ                                        (subZ)
2820                 , m_subW                                        (subW)
2821                 , m_subH                                        (subH)
2822                 , m_subD                                        (subD)
2823                 , m_imageHeight                         (imageHeight)
2824                 , m_rowLength                           (rowLength)
2825                 , m_skipImages                          (skipImages)
2826                 , m_skipRows                            (skipRows)
2827                 , m_skipPixels                          (skipPixels)
2828                 , m_alignment                           (alignment)
2829                 , m_offset                                      (offset)
2830         {
2831         }
2832
2833 protected:
2834         void createTexture (void)
2835         {
2836                 glu::TransferFormat             transferFmt             = glu::getTransferFormat(m_texFormat);
2837                 int                                             pixelSize               = m_texFormat.getPixelSize();
2838                 deUint32                                tex                             = 0;
2839                 deUint32                                buf                             = 0;
2840                 vector<deUint8>                 data;
2841
2842                 DE_ASSERT(m_numLevels == 1);
2843
2844                 glGenTextures(1, &tex);
2845                 glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
2846
2847                 // Fill with gradient.
2848                 {
2849                         int             rowPitch                = deAlign32(pixelSize*m_width,  4);
2850                         int             slicePitch              = rowPitch*m_height;
2851
2852                         data.resize(slicePitch*m_numLayers);
2853                         tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, m_numLayers, rowPitch, slicePitch, &data[0]), m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
2854                 }
2855
2856                 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, m_internalFormat, m_width, m_height, m_numLayers, 0, transferFmt.format, transferFmt.dataType, &data[0]);
2857
2858                 // Fill data with grid.
2859                 {
2860                         int             rowLength               = m_rowLength > 0 ? m_rowLength : m_subW;
2861                         int             rowPitch                = deAlign32(rowLength*pixelSize, m_alignment);
2862                         int             imageHeight             = m_imageHeight > 0 ? m_imageHeight : m_subH;
2863                         int             slicePitch              = imageHeight*rowPitch;
2864                         Vec4    cScale                  = m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
2865                         Vec4    cBias                   = m_texFormatInfo.valueMin;
2866                         Vec4    colorA                  = Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
2867                         Vec4    colorB                  = Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
2868
2869                         data.resize(slicePitch*(m_numLayers+m_skipImages) + m_offset);
2870                         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);
2871                 }
2872
2873                 glGenBuffers(1, &buf);
2874                 glBindBuffer(GL_PIXEL_UNPACK_BUFFER,    buf);
2875                 glBufferData(GL_PIXEL_UNPACK_BUFFER,    (int)data.size(), &data[0], GL_STATIC_DRAW);
2876
2877                 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT,   m_imageHeight);
2878                 glPixelStorei(GL_UNPACK_ROW_LENGTH,             m_rowLength);
2879                 glPixelStorei(GL_UNPACK_SKIP_IMAGES,    m_skipImages);
2880                 glPixelStorei(GL_UNPACK_SKIP_ROWS,              m_skipRows);
2881                 glPixelStorei(GL_UNPACK_SKIP_PIXELS,    m_skipPixels);
2882                 glPixelStorei(GL_UNPACK_ALIGNMENT,              m_alignment);
2883                 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);
2884         }
2885
2886         deUint32        m_internalFormat;
2887         int                     m_subX;
2888         int                     m_subY;
2889         int                     m_subZ;
2890         int                     m_subW;
2891         int                     m_subH;
2892         int                     m_subD;
2893         int                     m_imageHeight;
2894         int                     m_rowLength;
2895         int                     m_skipImages;
2896         int                     m_skipRows;
2897         int                     m_skipPixels;
2898         int                     m_alignment;
2899         int                     m_offset;
2900 };
2901
2902 // TexSubImage3D() PBO case.
2903 class TexSubImage3DBufferCase : public Texture3DSpecCase
2904 {
2905 public:
2906         TexSubImage3DBufferCase (Context&               context,
2907                                                          const char*    name,
2908                                                          const char*    desc,
2909                                                          deUint32               internalFormat,
2910                                                          int                    width,
2911                                                          int                    height,
2912                                                          int                    depth,
2913                                                          int                    subX,
2914                                                          int                    subY,
2915                                                          int                    subZ,
2916                                                          int                    subW,
2917                                                          int                    subH,
2918                                                          int                    subD,
2919                                                          int                    imageHeight,
2920                                                          int                    rowLength,
2921                                                          int                    skipImages,
2922                                                          int                    skipRows,
2923                                                          int                    skipPixels,
2924                                                          int                    alignment,
2925                                                          int                    offset)
2926                 : Texture3DSpecCase     (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, depth, 1)
2927                 , m_internalFormat      (internalFormat)
2928                 , m_subX                        (subX)
2929                 , m_subY                        (subY)
2930                 , m_subZ                        (subZ)
2931                 , m_subW                        (subW)
2932                 , m_subH                        (subH)
2933                 , m_subD                        (subD)
2934                 , m_imageHeight         (imageHeight)
2935                 , m_rowLength           (rowLength)
2936                 , m_skipImages          (skipImages)
2937                 , m_skipRows            (skipRows)
2938                 , m_skipPixels          (skipPixels)
2939                 , m_alignment           (alignment)
2940                 , m_offset                      (offset)
2941         {
2942         }
2943
2944 protected:
2945         void createTexture (void)
2946         {
2947                 glu::TransferFormat             transferFmt             = glu::getTransferFormat(m_texFormat);
2948                 int                                             pixelSize               = m_texFormat.getPixelSize();
2949                 deUint32                                tex                             = 0;
2950                 deUint32                                buf                             = 0;
2951                 vector<deUint8>                 data;
2952
2953                 DE_ASSERT(m_numLevels == 1);
2954
2955                 glGenTextures(1, &tex);
2956                 glBindTexture(GL_TEXTURE_3D, tex);
2957
2958                 // Fill with gradient.
2959                 {
2960                         int             rowPitch                = deAlign32(pixelSize*m_width,  4);
2961                         int             slicePitch              = rowPitch*m_height;
2962
2963                         data.resize(slicePitch*m_depth);
2964                         tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, m_depth, rowPitch, slicePitch, &data[0]), m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
2965                 }
2966
2967                 glTexImage3D(GL_TEXTURE_3D, 0, m_internalFormat, m_width, m_height, m_depth, 0, transferFmt.format, transferFmt.dataType, &data[0]);
2968
2969                 // Fill data with grid.
2970                 {
2971                         int             rowLength               = m_rowLength > 0 ? m_rowLength : m_subW;
2972                         int             rowPitch                = deAlign32(rowLength*pixelSize, m_alignment);
2973                         int             imageHeight             = m_imageHeight > 0 ? m_imageHeight : m_subH;
2974                         int             slicePitch              = imageHeight*rowPitch;
2975                         Vec4    cScale                  = m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
2976                         Vec4    cBias                   = m_texFormatInfo.valueMin;
2977                         Vec4    colorA                  = Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
2978                         Vec4    colorB                  = Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
2979
2980                         data.resize(slicePitch*(m_depth+m_skipImages) + m_offset);
2981                         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);
2982                 }
2983
2984                 glGenBuffers(1, &buf);
2985                 glBindBuffer(GL_PIXEL_UNPACK_BUFFER,    buf);
2986                 glBufferData(GL_PIXEL_UNPACK_BUFFER,    (int)data.size(), &data[0], GL_STATIC_DRAW);
2987
2988                 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT,   m_imageHeight);
2989                 glPixelStorei(GL_UNPACK_ROW_LENGTH,             m_rowLength);
2990                 glPixelStorei(GL_UNPACK_SKIP_IMAGES,    m_skipImages);
2991                 glPixelStorei(GL_UNPACK_SKIP_ROWS,              m_skipRows);
2992                 glPixelStorei(GL_UNPACK_SKIP_PIXELS,    m_skipPixels);
2993                 glPixelStorei(GL_UNPACK_ALIGNMENT,              m_alignment);
2994                 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);
2995         }
2996
2997         deUint32        m_internalFormat;
2998         int                     m_subX;
2999         int                     m_subY;
3000         int                     m_subZ;
3001         int                     m_subW;
3002         int                     m_subH;
3003         int                     m_subD;
3004         int                     m_imageHeight;
3005         int                     m_rowLength;
3006         int                     m_skipImages;
3007         int                     m_skipRows;
3008         int                     m_skipPixels;
3009         int                     m_alignment;
3010         int                     m_offset;
3011 };
3012
3013 // TexImage2D() depth case.
3014 class TexImage2DDepthCase : public Texture2DSpecCase
3015 {
3016 public:
3017         TexImage2DDepthCase (Context&           context,
3018                                                  const char*    name,
3019                                                  const char*    desc,
3020                                                  deUint32               internalFormat,
3021                                                  int                    imageWidth,
3022                                                  int                    imageHeight)
3023                 : Texture2DSpecCase     (context, name, desc, glu::mapGLInternalFormat(internalFormat), imageWidth, imageHeight, maxLevelCount(imageWidth, imageHeight))
3024                 , m_internalFormat      (internalFormat)
3025         {
3026                 // we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
3027                 m_texFormatInfo.lookupBias = Vec4(0.25f, 0.0f, 0.0f, 1.0f);
3028                 m_texFormatInfo.lookupScale = Vec4(0.5f, 1.0f, 1.0f, 0.0f);
3029         }
3030
3031         void createTexture (void)
3032         {
3033                 glu::TransferFormat     fmt                     = glu::getTransferFormat(m_texFormat);
3034                 deUint32                        tex                     = 0;
3035                 tcu::TextureLevel       levelData       (glu::mapGLTransferFormat(fmt.format, fmt.dataType));
3036
3037                 glGenTextures(1, &tex);
3038                 glBindTexture(GL_TEXTURE_2D, tex);
3039                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
3040                 GLU_CHECK();
3041
3042                 for (int ndx = 0; ndx < m_numLevels; ndx++)
3043                 {
3044                         const int   levelW              = de::max(1, m_width >> ndx);
3045                         const int   levelH              = de::max(1, m_height >> ndx);
3046                         const Vec4  gMin                = Vec4(-1.5f, -2.0f, 1.7f, -1.5f);
3047                         const Vec4  gMax                = Vec4(2.0f, 1.5f, -1.0f, 2.0f);
3048
3049                         levelData.setSize(levelW, levelH);
3050                         tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
3051
3052                         glTexImage2D(GL_TEXTURE_2D, ndx, m_internalFormat, levelW, levelH, 0, fmt.format, fmt.dataType, levelData.getAccess().getDataPtr());
3053                 }
3054         }
3055
3056         const deUint32 m_internalFormat;
3057 };
3058
3059 // TexImage3D() depth case.
3060 class TexImage2DArrayDepthCase : public Texture2DArraySpecCase
3061 {
3062 public:
3063         TexImage2DArrayDepthCase (Context&              context,
3064                                                           const char*   name,
3065                                                           const char*   desc,
3066                                                           deUint32              internalFormat,
3067                                                           int                   imageWidth,
3068                                                           int                   imageHeight,
3069                                                           int                   numLayers)
3070                 : Texture2DArraySpecCase(context, name, desc, glu::mapGLInternalFormat(internalFormat), imageWidth, imageHeight, numLayers, maxLevelCount(imageWidth, imageHeight))
3071                 , m_internalFormat              (internalFormat)
3072         {
3073                 // we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
3074                 m_texFormatInfo.lookupBias = Vec4(0.25f, 0.0f, 0.0f, 1.0f);
3075                 m_texFormatInfo.lookupScale = Vec4(0.5f, 1.0f, 1.0f, 0.0f);
3076         }
3077
3078         void createTexture (void)
3079         {
3080                 glu::TransferFormat     fmt                     = glu::getTransferFormat(m_texFormat);
3081                 deUint32                        tex                     = 0;
3082                 tcu::TextureLevel       levelData       (glu::mapGLTransferFormat(fmt.format, fmt.dataType));
3083
3084                 glGenTextures(1, &tex);
3085                 glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
3086                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
3087                 GLU_CHECK();
3088
3089                 for (int ndx = 0; ndx < m_numLevels; ndx++)
3090                 {
3091                         const int   levelW              = de::max(1, m_width >> ndx);
3092                         const int   levelH              = de::max(1, m_height >> ndx);
3093                         const Vec4  gMin                = Vec4(-1.5f, -2.0f, 1.7f, -1.5f);
3094                         const Vec4  gMax                = Vec4(2.0f, 1.5f, -1.0f, 2.0f);
3095
3096                         levelData.setSize(levelW, levelH, m_numLayers);
3097                         tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
3098
3099                         glTexImage3D(GL_TEXTURE_2D_ARRAY, ndx, m_internalFormat, levelW, levelH, m_numLayers, 0, fmt.format, fmt.dataType, levelData.getAccess().getDataPtr());
3100                 }
3101         }
3102
3103         const deUint32 m_internalFormat;
3104 };
3105
3106 // TexSubImage2D() depth case.
3107 class TexSubImage2DDepthCase : public Texture2DSpecCase
3108 {
3109 public:
3110         TexSubImage2DDepthCase (Context&        context,
3111                                                         const char*     name,
3112                                                         const char*     desc,
3113                                                         deUint32        internalFormat,
3114                                                         int                     imageWidth,
3115                                                         int                     imageHeight)
3116                 : Texture2DSpecCase     (context, name, desc, glu::mapGLInternalFormat(internalFormat), imageWidth, imageHeight, maxLevelCount(imageWidth, imageHeight))
3117                 , m_internalFormat      (internalFormat)
3118         {
3119                 // we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
3120                 m_texFormatInfo.lookupBias = Vec4(0.25f, 0.0f, 0.0f, 1.0f);
3121                 m_texFormatInfo.lookupScale = Vec4(0.5f, 1.0f, 1.0f, 0.0f);
3122         }
3123
3124         void createTexture (void)
3125         {
3126                 glu::TransferFormat     fmt                     = glu::getTransferFormat(m_texFormat);
3127                 de::Random                      rnd                     (deStringHash(getName()));
3128                 deUint32                        tex                     = 0;
3129                 tcu::TextureLevel       levelData       (glu::mapGLTransferFormat(fmt.format, fmt.dataType));
3130
3131                 glGenTextures(1, &tex);
3132                 glBindTexture(GL_TEXTURE_2D, tex);
3133                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
3134                 GLU_CHECK();
3135
3136                 // First specify full texture.
3137                 for (int ndx = 0; ndx < m_numLevels; ndx++)
3138                 {
3139                         const int   levelW              = de::max(1, m_width >> ndx);
3140                         const int   levelH              = de::max(1, m_height >> ndx);
3141                         const Vec4  gMin                = Vec4(-1.5f, -2.0f, 1.7f, -1.5f);
3142                         const Vec4  gMax                = Vec4(2.0f, 1.5f, -1.0f, 2.0f);
3143
3144                         levelData.setSize(levelW, levelH);
3145                         tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
3146
3147                         glTexImage2D(GL_TEXTURE_2D, ndx, m_internalFormat, levelW, levelH, 0, fmt.format, fmt.dataType, levelData.getAccess().getDataPtr());
3148                 }
3149
3150                 // Re-specify parts of each level.
3151                 for (int ndx = 0; ndx < m_numLevels; ndx++)
3152                 {
3153                         const int       levelW          = de::max(1, m_width >> ndx);
3154                         const int       levelH          = de::max(1, m_height >> ndx);
3155
3156                         const int       w                       = rnd.getInt(1, levelW);
3157                         const int       h                       = rnd.getInt(1, levelH);
3158                         const int       x                       = rnd.getInt(0, levelW-w);
3159                         const int       y                       = rnd.getInt(0, levelH-h);
3160
3161                         const Vec4      colorA          = Vec4(2.0f, 1.5f, -1.0f, 2.0f);
3162                         const Vec4      colorB          = Vec4(-1.5f, -2.0f, 1.7f, -1.5f);
3163                         const int       cellSize        = rnd.getInt(2, 16);
3164
3165                         levelData.setSize(w, h);
3166                         tcu::fillWithGrid(levelData.getAccess(), cellSize, colorA, colorB);
3167
3168                         glTexSubImage2D(GL_TEXTURE_2D, ndx, x, y, w, h, fmt.format, fmt.dataType, levelData.getAccess().getDataPtr());
3169                 }
3170         }
3171
3172         const deUint32 m_internalFormat;
3173 };
3174
3175 // TexSubImage3D() depth case.
3176 class TexSubImage2DArrayDepthCase : public Texture2DArraySpecCase
3177 {
3178 public:
3179         TexSubImage2DArrayDepthCase (Context&           context,
3180                                                                  const char*    name,
3181                                                                  const char*    desc,
3182                                                                  deUint32               internalFormat,
3183                                                                  int                    imageWidth,
3184                                                                  int                    imageHeight,
3185                                                                  int                    numLayers)
3186                 : Texture2DArraySpecCase(context, name, desc, glu::mapGLInternalFormat(internalFormat), imageWidth, imageHeight, numLayers, maxLevelCount(imageWidth, imageHeight))
3187                 , m_internalFormat              (internalFormat)
3188         {
3189                 // we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
3190                 m_texFormatInfo.lookupBias = Vec4(0.25f, 0.0f, 0.0f, 1.0f);
3191                 m_texFormatInfo.lookupScale = Vec4(0.5f, 1.0f, 1.0f, 0.0f);
3192         }
3193
3194         void createTexture (void)
3195         {
3196                 glu::TransferFormat     fmt                     = glu::getTransferFormat(m_texFormat);
3197                 de::Random                      rnd                     (deStringHash(getName()));
3198                 deUint32                        tex                     = 0;
3199                 tcu::TextureLevel       levelData       (glu::mapGLTransferFormat(fmt.format, fmt.dataType));
3200
3201                 glGenTextures(1, &tex);
3202                 glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
3203                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
3204                 GLU_CHECK();
3205
3206                 // First specify full texture.
3207                 for (int ndx = 0; ndx < m_numLevels; ndx++)
3208                 {
3209                         const int   levelW              = de::max(1, m_width >> ndx);
3210                         const int   levelH              = de::max(1, m_height >> ndx);
3211                         const Vec4  gMin                = Vec4(-1.5f, -2.0f, 1.7f, -1.5f);
3212                         const Vec4  gMax                = Vec4(2.0f, 1.5f, -1.0f, 2.0f);
3213
3214                         levelData.setSize(levelW, levelH, m_numLayers);
3215                         tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
3216
3217                         glTexImage3D(GL_TEXTURE_2D_ARRAY, ndx, m_internalFormat, levelW, levelH, m_numLayers, 0, fmt.format, fmt.dataType, levelData.getAccess().getDataPtr());
3218                 }
3219
3220                 // Re-specify parts of each level.
3221                 for (int ndx = 0; ndx < m_numLevels; ndx++)
3222                 {
3223                         const int       levelW          = de::max(1, m_width >> ndx);
3224                         const int       levelH          = de::max(1, m_height >> ndx);
3225
3226                         const int       w                       = rnd.getInt(1, levelW);
3227                         const int       h                       = rnd.getInt(1, levelH);
3228                         const int       d                       = rnd.getInt(1, m_numLayers);
3229                         const int       x                       = rnd.getInt(0, levelW-w);
3230                         const int       y                       = rnd.getInt(0, levelH-h);
3231                         const int       z                       = rnd.getInt(0, m_numLayers-d);
3232
3233                         const Vec4      colorA          = Vec4(2.0f, 1.5f, -1.0f, 2.0f);
3234                         const Vec4      colorB          = Vec4(-1.5f, -2.0f, 1.7f, -1.5f);
3235                         const int       cellSize        = rnd.getInt(2, 16);
3236
3237                         levelData.setSize(w, h, d);
3238                         tcu::fillWithGrid(levelData.getAccess(), cellSize, colorA, colorB);
3239
3240                         glTexSubImage3D(GL_TEXTURE_2D_ARRAY, ndx, x, y, z, w, h, d, fmt.format, fmt.dataType, levelData.getAccess().getDataPtr());
3241                 }
3242         }
3243
3244         const deUint32 m_internalFormat;
3245 };
3246
3247 // TexImage2D() depth case with pbo.
3248 class TexImage2DDepthBufferCase : public Texture2DSpecCase
3249 {
3250 public:
3251         TexImage2DDepthBufferCase (Context&             context,
3252                                                            const char*  name,
3253                                                            const char*  desc,
3254                                                            deUint32             internalFormat,
3255                                                            int                  imageWidth,
3256                                                            int                  imageHeight)
3257                 : Texture2DSpecCase     (context, name, desc, glu::mapGLInternalFormat(internalFormat), imageWidth, imageHeight, 1)
3258                 , m_internalFormat      (internalFormat)
3259         {
3260                 // we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
3261                 m_texFormatInfo.lookupBias = Vec4(0.25f, 0.0f, 0.0f, 1.0f);
3262                 m_texFormatInfo.lookupScale = Vec4(0.5f, 1.0f, 1.0f, 0.0f);
3263         }
3264
3265         void createTexture (void)
3266         {
3267                 glu::TransferFormat             transferFmt             = glu::getTransferFormat(m_texFormat);
3268                 int                                             pixelSize               = m_texFormat.getPixelSize();
3269                 int                                             rowLength               = m_width;
3270                 int                                             alignment               = 4;
3271                 int                                             rowPitch                = deAlign32(rowLength*pixelSize, alignment);
3272                 int                                             height                  = m_height;
3273                 deUint32                                buf                             = 0;
3274                 deUint32                                tex                             = 0;
3275                 vector<deUint8>                 data;
3276
3277                 DE_ASSERT(m_numLevels == 1);
3278
3279                 // Fill data with gradient
3280                 data.resize(rowPitch*height);
3281                 {
3282                         const Vec4 gMin = Vec4(-1.5f, -2.0f, 1.7f, -1.5f);
3283                         const Vec4 gMax = Vec4(2.0f, 1.5f, -1.0f, 2.0f);
3284
3285                         tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, 1, rowPitch, 0, &data[0]), gMin, gMax);
3286                 }
3287
3288                 // Create buffer and upload.
3289                 glGenBuffers(1, &buf);
3290                 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf);
3291                 glBufferData(GL_PIXEL_UNPACK_BUFFER, (int)data.size(), &data[0], GL_STATIC_DRAW);
3292
3293                 glPixelStorei(GL_UNPACK_ROW_LENGTH,             rowLength);
3294                 glPixelStorei(GL_UNPACK_SKIP_ROWS,              0);
3295                 glPixelStorei(GL_UNPACK_SKIP_PIXELS,    0);
3296                 glPixelStorei(GL_UNPACK_ALIGNMENT,              alignment);
3297
3298                 glGenTextures(1, &tex);
3299                 glBindTexture(GL_TEXTURE_2D, tex);
3300                 glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_width, m_height, 0, transferFmt.format, transferFmt.dataType, DE_NULL);
3301                 glDeleteBuffers(1, &buf);
3302         }
3303
3304         const deUint32 m_internalFormat;
3305 };
3306
3307 // TexImage3D() depth case with pbo.
3308 class TexImage2DArrayDepthBufferCase : public Texture2DArraySpecCase
3309 {
3310 public:
3311         TexImage2DArrayDepthBufferCase (Context&        context,
3312                                                                         const char*     name,
3313                                                                         const char*     desc,
3314                                                                         deUint32        internalFormat,
3315                                                                         int                     imageWidth,
3316                                                                         int                     imageHeight,
3317                                                                         int                     numLayers)
3318                 : Texture2DArraySpecCase(context, name, desc, glu::mapGLInternalFormat(internalFormat), imageWidth, imageHeight, numLayers, 1)
3319                 , m_internalFormat              (internalFormat)
3320         {
3321                 // we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
3322                 m_texFormatInfo.lookupBias = Vec4(0.25f, 0.0f, 0.0f, 1.0f);
3323                 m_texFormatInfo.lookupScale = Vec4(0.5f, 1.0f, 1.0f, 0.0f);
3324         }
3325
3326         void createTexture (void)
3327         {
3328                 glu::TransferFormat             transferFmt             = glu::getTransferFormat(m_texFormat);
3329                 int                                             pixelSize               = m_texFormat.getPixelSize();
3330                 int                                             rowLength               = m_width;
3331                 int                                             alignment               = 4;
3332                 int                                             rowPitch                = deAlign32(rowLength*pixelSize, alignment);
3333                 int                                             imageHeight             = m_height;
3334                 int                                             slicePitch              = imageHeight*rowPitch;
3335                 deUint32                                tex                             = 0;
3336                 deUint32                                buf                             = 0;
3337                 vector<deUint8>                 data;
3338
3339                 DE_ASSERT(m_numLevels == 1);
3340
3341                 // Fill data with grid.
3342                 data.resize(slicePitch*m_numLayers);
3343                 {
3344                         const Vec4 gMin = Vec4(-1.5f, -2.0f, 1.7f, -1.5f);
3345                         const Vec4 gMax = Vec4(2.0f, 1.5f, -1.0f, 2.0f);
3346
3347                         tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, m_numLayers, rowPitch, slicePitch, &data[0]), gMin, gMax);
3348                 }
3349
3350                 glGenBuffers(1, &buf);
3351                 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf);
3352                 glBufferData(GL_PIXEL_UNPACK_BUFFER, (int)data.size(), &data[0], GL_STATIC_DRAW);
3353
3354                 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT,   imageHeight);
3355                 glPixelStorei(GL_UNPACK_ROW_LENGTH,             rowLength);
3356                 glPixelStorei(GL_UNPACK_SKIP_IMAGES,    0);
3357                 glPixelStorei(GL_UNPACK_SKIP_ROWS,              0);
3358                 glPixelStorei(GL_UNPACK_SKIP_PIXELS,    0);
3359                 glPixelStorei(GL_UNPACK_ALIGNMENT,              alignment);
3360
3361                 glGenTextures(1, &tex);
3362                 glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
3363                 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, m_internalFormat, m_width, m_height, m_numLayers, 0, transferFmt.format, transferFmt.dataType, DE_NULL);
3364                 glDeleteBuffers(1, &buf);
3365         }
3366
3367         const deUint32 m_internalFormat;
3368 };
3369
3370 TextureSpecificationTests::TextureSpecificationTests (Context& context)
3371         : TestCaseGroup(context, "specification", "Texture Specification Tests")
3372 {
3373 }
3374
3375 TextureSpecificationTests::~TextureSpecificationTests (void)
3376 {
3377 }
3378
3379 void TextureSpecificationTests::init (void)
3380 {
3381         struct
3382         {
3383                 const char*     name;
3384                 deUint32        format;
3385                 deUint32        dataType;
3386         } unsizedFormats[] =
3387         {
3388                 { "alpha_unsigned_byte",                        GL_ALPHA,                       GL_UNSIGNED_BYTE },
3389                 { "luminance_unsigned_byte",            GL_LUMINANCE,           GL_UNSIGNED_BYTE },
3390                 { "luminance_alpha_unsigned_byte",      GL_LUMINANCE_ALPHA,     GL_UNSIGNED_BYTE },
3391                 { "rgb_unsigned_short_5_6_5",           GL_RGB,                         GL_UNSIGNED_SHORT_5_6_5 },
3392                 { "rgb_unsigned_byte",                          GL_RGB,                         GL_UNSIGNED_BYTE },
3393                 { "rgba_unsigned_short_4_4_4_4",        GL_RGBA,                        GL_UNSIGNED_SHORT_4_4_4_4 },
3394                 { "rgba_unsigned_short_5_5_5_1",        GL_RGBA,                        GL_UNSIGNED_SHORT_5_5_5_1 },
3395                 { "rgba_unsigned_byte",                         GL_RGBA,                        GL_UNSIGNED_BYTE }
3396         };
3397
3398         struct
3399         {
3400                 const char*     name;
3401                 deUint32        internalFormat;
3402         } colorFormats[] =
3403         {
3404                 { "rgba32f",                    GL_RGBA32F,                     },
3405                 { "rgba32i",                    GL_RGBA32I,                     },
3406                 { "rgba32ui",                   GL_RGBA32UI,            },
3407                 { "rgba16f",                    GL_RGBA16F,                     },
3408                 { "rgba16i",                    GL_RGBA16I,                     },
3409                 { "rgba16ui",                   GL_RGBA16UI,            },
3410                 { "rgba8",                              GL_RGBA8,                       },
3411                 { "rgba8i",                             GL_RGBA8I,                      },
3412                 { "rgba8ui",                    GL_RGBA8UI,                     },
3413                 { "srgb8_alpha8",               GL_SRGB8_ALPHA8,        },
3414                 { "rgb10_a2",                   GL_RGB10_A2,            },
3415                 { "rgb10_a2ui",                 GL_RGB10_A2UI,          },
3416                 { "rgba4",                              GL_RGBA4,                       },
3417                 { "rgb5_a1",                    GL_RGB5_A1,                     },
3418                 { "rgba8_snorm",                GL_RGBA8_SNORM,         },
3419                 { "rgb8",                               GL_RGB8,                        },
3420                 { "rgb565",                             GL_RGB565,                      },
3421                 { "r11f_g11f_b10f",             GL_R11F_G11F_B10F,      },
3422                 { "rgb32f",                             GL_RGB32F,                      },
3423                 { "rgb32i",                             GL_RGB32I,                      },
3424                 { "rgb32ui",                    GL_RGB32UI,                     },
3425                 { "rgb16f",                             GL_RGB16F,                      },
3426                 { "rgb16i",                             GL_RGB16I,                      },
3427                 { "rgb16ui",                    GL_RGB16UI,                     },
3428                 { "rgb8_snorm",                 GL_RGB8_SNORM,          },
3429                 { "rgb8i",                              GL_RGB8I,                       },
3430                 { "rgb8ui",                             GL_RGB8UI,                      },
3431                 { "srgb8",                              GL_SRGB8,                       },
3432                 { "rgb9_e5",                    GL_RGB9_E5,                     },
3433                 { "rg32f",                              GL_RG32F,                       },
3434                 { "rg32i",                              GL_RG32I,                       },
3435                 { "rg32ui",                             GL_RG32UI,                      },
3436                 { "rg16f",                              GL_RG16F,                       },
3437                 { "rg16i",                              GL_RG16I,                       },
3438                 { "rg16ui",                             GL_RG16UI,                      },
3439                 { "rg8",                                GL_RG8,                         },
3440                 { "rg8i",                               GL_RG8I,                        },
3441                 { "rg8ui",                              GL_RG8UI,                       },
3442                 { "rg8_snorm",                  GL_RG8_SNORM,           },
3443                 { "r32f",                               GL_R32F,                        },
3444                 { "r32i",                               GL_R32I,                        },
3445                 { "r32ui",                              GL_R32UI,                       },
3446                 { "r16f",                               GL_R16F,                        },
3447                 { "r16i",                               GL_R16I,                        },
3448                 { "r16ui",                              GL_R16UI,                       },
3449                 { "r8",                                 GL_R8,                          },
3450                 { "r8i",                                GL_R8I,                         },
3451                 { "r8ui",                               GL_R8UI,                        },
3452                 { "r8_snorm",                   GL_R8_SNORM,            }
3453         };
3454
3455         static const struct
3456         {
3457                 const char*     name;
3458                 deUint32        internalFormat;
3459         } depthStencilFormats[] =
3460         {
3461                 // Depth and stencil formats
3462                 { "depth_component32f", GL_DEPTH_COMPONENT32F   },
3463                 { "depth_component24",  GL_DEPTH_COMPONENT24    },
3464                 { "depth_component16",  GL_DEPTH_COMPONENT16    },
3465                 { "depth32f_stencil8",  GL_DEPTH32F_STENCIL8    },
3466                 { "depth24_stencil8",   GL_DEPTH24_STENCIL8             }
3467         };
3468
3469         // Basic TexImage2D usage.
3470         {
3471                 tcu::TestCaseGroup* basicTexImageGroup = new tcu::TestCaseGroup(m_testCtx, "basic_teximage2d", "Basic glTexImage2D() usage");
3472                 addChild(basicTexImageGroup);
3473                 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++)
3474                 {
3475                         const char*     fmtName         = colorFormats[formatNdx].name;
3476                         deUint32        format          = colorFormats[formatNdx].internalFormat;
3477                         const int       tex2DWidth      = 64;
3478                         const int       tex2DHeight     = 128;
3479                         const int       texCubeSize     = 64;
3480
3481                         basicTexImageGroup->addChild(new BasicTexImage2DCase    (m_context,     (string(fmtName) + "_2d").c_str(),              "",     format, tex2DWidth, tex2DHeight));
3482                         basicTexImageGroup->addChild(new BasicTexImageCubeCase  (m_context,     (string(fmtName) + "_cube").c_str(),    "",     format, texCubeSize));
3483                 }
3484         }
3485
3486         // Randomized TexImage2D order.
3487         {
3488                 tcu::TestCaseGroup* randomTexImageGroup = new tcu::TestCaseGroup(m_testCtx, "random_teximage2d", "Randomized glTexImage2D() usage");
3489                 addChild(randomTexImageGroup);
3490
3491                 de::Random rnd(9);
3492
3493                 // 2D cases.
3494                 for (int ndx = 0; ndx < 10; ndx++)
3495                 {
3496                         int             formatNdx       = rnd.getInt(0, DE_LENGTH_OF_ARRAY(colorFormats)-1);
3497                         int             width           = 1 << rnd.getInt(2, 8);
3498                         int             height          = 1 << rnd.getInt(2, 8);
3499
3500                         randomTexImageGroup->addChild(new RandomOrderTexImage2DCase(m_context, (string("2d_") + de::toString(ndx)).c_str(), "", colorFormats[formatNdx].internalFormat, width, height));
3501                 }
3502
3503                 // Cubemap cases.
3504                 for (int ndx = 0; ndx < 10; ndx++)
3505                 {
3506                         int             formatNdx       = rnd.getInt(0, DE_LENGTH_OF_ARRAY(colorFormats)-1);
3507                         int             size            = 1 << rnd.getInt(2, 8);
3508
3509                         randomTexImageGroup->addChild(new RandomOrderTexImageCubeCase(m_context, (string("cube_") + de::toString(ndx)).c_str(), "", colorFormats[formatNdx].internalFormat, size));
3510                 }
3511         }
3512
3513         // TexImage2D unpack alignment.
3514         {
3515                 tcu::TestCaseGroup* alignGroup = new tcu::TestCaseGroup(m_testCtx, "teximage2d_align", "glTexImage2D() unpack alignment tests");
3516                 addChild(alignGroup);
3517
3518                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_r8_4_8",                        "",     GL_R8,                   4,  8, 4, 8));
3519                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_r8_63_1",                       "",     GL_R8,                  63, 30, 1, 1));
3520                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_r8_63_2",                       "",     GL_R8,                  63, 30, 1, 2));
3521                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_r8_63_4",                       "",     GL_R8,                  63, 30, 1, 4));
3522                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_r8_63_8",                       "",     GL_R8,                  63, 30, 1, 8));
3523                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_rgba4_51_1",            "",     GL_RGBA4,               51, 30, 1, 1));
3524                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_rgba4_51_2",            "",     GL_RGBA4,               51, 30, 1, 2));
3525                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_rgba4_51_4",            "",     GL_RGBA4,               51, 30, 1, 4));
3526                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_rgba4_51_8",            "",     GL_RGBA4,               51, 30, 1, 8));
3527                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_rgb8_39_1",                     "",     GL_RGB8,                39, 43, 1, 1));
3528                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_rgb8_39_2",                     "",     GL_RGB8,                39, 43, 1, 2));
3529                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_rgb8_39_4",                     "",     GL_RGB8,                39, 43, 1, 4));
3530                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_rgb8_39_8",                     "",     GL_RGB8,                39, 43, 1, 8));
3531                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_rgba8_47_1",            "",     GL_RGBA8,               47, 27, 1, 1));
3532                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_rgba8_47_2",            "",     GL_RGBA8,               47, 27, 1, 2));
3533                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_rgba8_47_4",            "",     GL_RGBA8,               47, 27, 1, 4));
3534                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_rgba8_47_8",            "",     GL_RGBA8,               47, 27, 1, 8));
3535
3536                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_r8_4_8",                      "",     GL_R8,                   4, 3, 8));
3537                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_r8_63_1",                     "",     GL_R8,                  63, 1, 1));
3538                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_r8_63_2",                     "",     GL_R8,                  63, 1, 2));
3539                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_r8_63_4",                     "",     GL_R8,                  63, 1, 4));
3540                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_r8_63_8",                     "",     GL_R8,                  63, 1, 8));
3541                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_rgba4_51_1",          "",     GL_RGBA4,               51, 1, 1));
3542                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_rgba4_51_2",          "",     GL_RGBA4,               51, 1, 2));
3543                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_rgba4_51_4",          "",     GL_RGBA4,               51, 1, 4));
3544                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_rgba4_51_8",          "",     GL_RGBA4,               51, 1, 8));
3545                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_rgb8_39_1",           "",     GL_RGB8,                39, 1, 1));
3546                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_rgb8_39_2",           "",     GL_RGB8,                39, 1, 2));
3547                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_rgb8_39_4",           "",     GL_RGB8,                39, 1, 4));
3548                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_rgb8_39_8",           "",     GL_RGB8,                39, 1, 8));
3549                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_rgba8_47_1",          "",     GL_RGBA8,               47, 1, 1));
3550                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_rgba8_47_2",          "",     GL_RGBA8,               47, 1, 2));
3551                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_rgba8_47_4",          "",     GL_RGBA8,               47, 1, 4));
3552                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_rgba8_47_8",          "",     GL_RGBA8,               47, 1, 8));
3553         }
3554
3555         // glTexImage2D() unpack parameter cases.
3556         {
3557                 tcu::TestCaseGroup* paramGroup = new tcu::TestCaseGroup(m_testCtx, "teximage2d_unpack_params", "glTexImage2D() pixel transfer mode cases");
3558                 addChild(paramGroup);
3559
3560                 static const struct
3561                 {
3562                         const char*     name;
3563                         deUint32        format;
3564                         int                     width;
3565                         int                     height;
3566                         int                     rowLength;
3567                         int                     skipRows;
3568                         int                     skipPixels;
3569                         int                     alignment;
3570                 } cases[] =
3571                 {
3572                         { "rgb8_alignment",             GL_RGB8,        31,     30,     0,      0,      0,      2 },
3573                         { "rgb8_row_length",    GL_RGB8,        31,     30,     50,     0,      0,      4 },
3574                         { "rgb8_skip_rows",             GL_RGB8,        31,     30,     0,      3,      0,      4 },
3575                         { "rgb8_skip_pixels",   GL_RGB8,        31,     30,     36,     0,      5,      4 },
3576                         { "r8_complex1",                GL_R8,          31, 30, 64, 1,  3,      1 },
3577                         { "r8_complex2",                GL_R8,          31, 30, 64, 1,  3,      2 },
3578                         { "r8_complex3",                GL_R8,          31, 30, 64, 1,  3,      4 },
3579                         { "r8_complex4",                GL_R8,          31, 30, 64, 1,  3,      8 },
3580                         { "rgba8_complex1",             GL_RGBA8,       56,     61,     69,     0,      0,      8 },
3581                         { "rgba8_complex2",             GL_RGBA8,       56,     61,     69,     0,      7,      8 },
3582                         { "rgba8_complex3",             GL_RGBA8,       56,     61,     69,     3,      0,      8 },
3583                         { "rgba8_complex4",             GL_RGBA8,       56,     61,     69,     3,      7,      8 },
3584                         { "rgba32f_complex",    GL_RGBA32F,     19,     10,     27,     1,      7,      8 }
3585                 };
3586
3587                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cases); ndx++)
3588                         paramGroup->addChild(new TexImage2DParamsCase(m_context, cases[ndx].name, "",
3589                                                                                                                   cases[ndx].format,
3590                                                                                                                   cases[ndx].width,
3591                                                                                                                   cases[ndx].height,
3592                                                                                                                   cases[ndx].rowLength,
3593                                                                                                                   cases[ndx].skipRows,
3594                                                                                                                   cases[ndx].skipPixels,
3595                                                                                                                   cases[ndx].alignment));
3596         }
3597
3598         // glTexImage2D() pbo cases.
3599         {
3600                 tcu::TestCaseGroup* pboGroup = new tcu::TestCaseGroup(m_testCtx, "teximage2d_pbo", "glTexImage2D() from PBO");
3601                 addChild(pboGroup);
3602
3603                 // Parameter cases
3604                 static const struct
3605                 {
3606                         const char*     name;
3607                         deUint32        format;
3608                         int                     width;
3609                         int                     height;
3610                         int                     rowLength;
3611                         int                     skipRows;
3612                         int                     skipPixels;
3613                         int                     alignment;
3614                         int                     offset;
3615                 } parameterCases[] =
3616                 {
3617                         { "rgb8_offset",                GL_RGB8,        31,     30,     0,      0,      0,      4,      67 },
3618                         { "rgb8_alignment",             GL_RGB8,        31,     30,     0,      0,      0,      2,      0 },
3619                         { "rgb8_row_length",    GL_RGB8,        31,     30,     50,     0,      0,      4,      0 },
3620                         { "rgb8_skip_rows",             GL_RGB8,        31,     30,     0,      3,      0,      4,      0 },
3621                         { "rgb8_skip_pixels",   GL_RGB8,        31,     30,     36,     0,      5,      4,      0 }
3622                 };
3623
3624                 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++)
3625                 {
3626                         const string    fmtName         = colorFormats[formatNdx].name;
3627                         const deUint32  format          = colorFormats[formatNdx].internalFormat;
3628                         const int               tex2DWidth      = 65;
3629                         const int               tex2DHeight     = 37;
3630                         const int               texCubeSize     = 64;
3631
3632                         pboGroup->addChild(new TexImage2DBufferCase             (m_context,     (fmtName + "_2d").c_str(),              "", format, tex2DWidth, tex2DHeight, 0, 0, 0, 4, 0));
3633                         pboGroup->addChild(new TexImageCubeBufferCase   (m_context,     (fmtName + "_cube").c_str(),    "", format, texCubeSize, 0, 0, 0, 4, 0));
3634                 }
3635
3636                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(parameterCases); ndx++)
3637                 {
3638                         pboGroup->addChild(new TexImage2DBufferCase(m_context, (string(parameterCases[ndx].name) + "_2d").c_str(), "",
3639                                                                                                                 parameterCases[ndx].format,
3640                                                                                                                 parameterCases[ndx].width,
3641                                                                                                                 parameterCases[ndx].height,
3642                                                                                                                 parameterCases[ndx].rowLength,
3643                                                                                                                 parameterCases[ndx].skipRows,
3644                                                                                                                 parameterCases[ndx].skipPixels,
3645                                                                                                                 parameterCases[ndx].alignment,
3646                                                                                                                 parameterCases[ndx].offset));
3647                         pboGroup->addChild(new TexImageCubeBufferCase(m_context, (string(parameterCases[ndx].name) + "_cube").c_str(), "",
3648                                                                                                                 parameterCases[ndx].format,
3649                                                                                                                 parameterCases[ndx].width,
3650                                                                                                                 parameterCases[ndx].rowLength,
3651                                                                                                                 parameterCases[ndx].skipRows,
3652                                                                                                                 parameterCases[ndx].skipPixels,
3653                                                                                                                 parameterCases[ndx].alignment,
3654                                                                                                                 parameterCases[ndx].offset));
3655                 }
3656         }
3657
3658         // glTexImage2D() depth cases.
3659         {
3660                 tcu::TestCaseGroup* shadow2dGroup = new tcu::TestCaseGroup(m_testCtx, "teximage2d_depth", "glTexImage2D() with depth or depth/stencil format");
3661                 addChild(shadow2dGroup);
3662
3663                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++)
3664                 {
3665                         const int tex2DWidth    = 64;
3666                         const int tex2DHeight   = 128;
3667
3668                         shadow2dGroup->addChild(new TexImage2DDepthCase(m_context, depthStencilFormats[ndx].name, "", depthStencilFormats[ndx].internalFormat, tex2DWidth, tex2DHeight));
3669                 }
3670         }
3671
3672         // glTexImage2D() depth cases with pbo.
3673         {
3674                 tcu::TestCaseGroup* shadow2dGroup = new tcu::TestCaseGroup(m_testCtx, "teximage2d_depth_pbo", "glTexImage2D() with depth or depth/stencil format with pbo");
3675                 addChild(shadow2dGroup);
3676
3677                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++)
3678                 {
3679                         const int tex2DWidth    = 64;
3680                         const int tex2DHeight   = 128;
3681
3682                         shadow2dGroup->addChild(new TexImage2DDepthBufferCase(m_context, depthStencilFormats[ndx].name, "", depthStencilFormats[ndx].internalFormat, tex2DWidth, tex2DHeight));
3683                 }
3684         }
3685
3686         // Basic TexSubImage2D usage.
3687         {
3688                 tcu::TestCaseGroup* basicTexSubImageGroup = new tcu::TestCaseGroup(m_testCtx, "basic_texsubimage2d", "Basic glTexSubImage2D() usage");
3689                 addChild(basicTexSubImageGroup);
3690                 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++)
3691                 {
3692                         const char*     fmtName         = colorFormats[formatNdx].name;
3693                         deUint32        format          = colorFormats[formatNdx].internalFormat;
3694                         const int       tex2DWidth      = 64;
3695                         const int       tex2DHeight     = 128;
3696                         const int       texCubeSize     = 64;
3697
3698                         basicTexSubImageGroup->addChild(new BasicTexSubImage2DCase              (m_context,     (string(fmtName) + "_2d").c_str(),              "",     format, tex2DWidth, tex2DHeight));
3699                         basicTexSubImageGroup->addChild(new BasicTexSubImageCubeCase    (m_context,     (string(fmtName) + "_cube").c_str(),    "",     format, texCubeSize));
3700                 }
3701         }
3702
3703         // TexSubImage2D to empty texture.
3704         {
3705                 tcu::TestCaseGroup* texSubImageEmptyTexGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage2d_empty_tex", "glTexSubImage2D() to texture that has storage but no data");
3706                 addChild(texSubImageEmptyTexGroup);
3707                 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(unsizedFormats); formatNdx++)
3708                 {
3709                         const char*     fmtName         = unsizedFormats[formatNdx].name;
3710                         deUint32        format          = unsizedFormats[formatNdx].format;
3711                         deUint32        dataType        = unsizedFormats[formatNdx].dataType;
3712                         const int       tex2DWidth      = 64;
3713                         const int       tex2DHeight     = 32;
3714                         const int       texCubeSize     = 32;
3715
3716                         texSubImageEmptyTexGroup->addChild(new TexSubImage2DEmptyTexCase        (m_context,     (string(fmtName) + "_2d").c_str(),              "",     format, dataType, tex2DWidth, tex2DHeight));
3717                         texSubImageEmptyTexGroup->addChild(new TexSubImageCubeEmptyTexCase      (m_context,     (string(fmtName) + "_cube").c_str(),    "",     format, dataType, texCubeSize));
3718                 }
3719         }
3720
3721         // TexSubImage2D alignment cases.
3722         {
3723                 tcu::TestCaseGroup* alignGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage2d_align", "glTexSubImage2D() unpack alignment tests");
3724                 addChild(alignGroup);
3725
3726                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_r8_1_1",                        "",     GL_R8,                  64, 64, 13, 17,  1,  6, 1));
3727                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_r8_1_2",                        "",     GL_R8,                  64, 64, 13, 17,  1,  6, 2));
3728                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_r8_1_4",                        "",     GL_R8,                  64, 64, 13, 17,  1,  6, 4));
3729                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_r8_1_8",                        "",     GL_R8,                  64, 64, 13, 17,  1,  6, 8));
3730                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_r8_63_1",                       "",     GL_R8,                  64, 64,  1,  9, 63, 30, 1));
3731                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_r8_63_2",                       "",     GL_R8,                  64, 64,  1,  9, 63, 30, 2));
3732                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_r8_63_4",                       "",     GL_R8,                  64, 64,  1,  9, 63, 30, 4));
3733                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_r8_63_8",                       "",     GL_R8,                  64, 64,  1,  9, 63, 30, 8));
3734                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_rgba4_51_1",            "",     GL_RGBA4,               64, 64,  7, 29, 51, 30, 1));
3735                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_rgba4_51_2",            "",     GL_RGBA4,               64, 64,  7, 29, 51, 30, 2));
3736                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_rgba4_51_4",            "",     GL_RGBA4,               64, 64,  7, 29, 51, 30, 4));
3737                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_rgba4_51_8",            "",     GL_RGBA4,               64, 64,  7, 29, 51, 30, 8));
3738                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_rgb8_39_1",                     "",     GL_RGB8,                64, 64, 11,  8, 39, 43, 1));
3739                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_rgb8_39_2",                     "",     GL_RGB8,                64, 64, 11,  8, 39, 43, 2));
3740                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_rgb8_39_4",                     "",     GL_RGB8,                64, 64, 11,  8, 39, 43, 4));
3741                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_rgb8_39_8",                     "",     GL_RGB8,                64, 64, 11,  8, 39, 43, 8));
3742                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_rgba8_47_1",            "",     GL_RGBA8,               64, 64, 10,  1, 47, 27, 1));
3743                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_rgba8_47_2",            "",     GL_RGBA8,               64, 64, 10,  1, 47, 27, 2));
3744                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_rgba8_47_4",            "",     GL_RGBA8,               64, 64, 10,  1, 47, 27, 4));
3745                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_rgba8_47_8",            "",     GL_RGBA8,               64, 64, 10,  1, 47, 27, 8));
3746
3747                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_r8_1_1",                      "",     GL_R8,                  64, 13, 17,  1,  6, 1));
3748                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_r8_1_2",                      "",     GL_R8,                  64, 13, 17,  1,  6, 2));
3749                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_r8_1_4",                      "",     GL_R8,                  64, 13, 17,  1,  6, 4));
3750                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_r8_1_8",                      "",     GL_R8,                  64, 13, 17,  1,  6, 8));
3751                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_r8_63_1",                     "",     GL_R8,                  64,  1,  9, 63, 30, 1));
3752                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_r8_63_2",                     "",     GL_R8,                  64,  1,  9, 63, 30, 2));
3753                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_r8_63_4",                     "",     GL_R8,                  64,  1,  9, 63, 30, 4));
3754                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_r8_63_8",                     "",     GL_R8,                  64,  1,  9, 63, 30, 8));
3755                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_rgba4_51_1",          "",     GL_RGBA4,               64,  7, 29, 51, 30, 1));
3756                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_rgba4_51_2",          "",     GL_RGBA4,               64,  7, 29, 51, 30, 2));
3757                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_rgba4_51_4",          "",     GL_RGBA4,               64,  7, 29, 51, 30, 4));
3758                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_rgba4_51_8",          "",     GL_RGBA4,               64,  7, 29, 51, 30, 8));
3759                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_rgb8_39_1",           "",     GL_RGB8,                64, 11,  8, 39, 43, 1));
3760                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_rgb8_39_2",           "",     GL_RGB8,                64, 11,  8, 39, 43, 2));
3761                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_rgb8_39_4",           "",     GL_RGB8,                64, 11,  8, 39, 43, 4));
3762                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_rgb8_39_8",           "",     GL_RGB8,                64, 11,  8, 39, 43, 8));
3763                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_rgba8_47_1",          "",     GL_RGBA8,               64, 10,  1, 47, 27, 1));
3764                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_rgba8_47_2",          "",     GL_RGBA8,               64, 10,  1, 47, 27, 2));
3765                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_rgba8_47_4",          "",     GL_RGBA8,               64, 10,  1, 47, 27, 4));
3766                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_rgba8_47_8",          "",     GL_RGBA8,               64, 10,  1, 47, 27, 8));
3767         }
3768
3769         // glTexSubImage2D() pixel transfer mode cases.
3770         {
3771                 tcu::TestCaseGroup* paramGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage2d_unpack_params", "glTexSubImage2D() pixel transfer mode cases");
3772                 addChild(paramGroup);
3773
3774                 static const struct
3775                 {
3776                         const char*     name;
3777                         deUint32        format;
3778                         int                     width;
3779                         int                     height;
3780                         int                     subX;
3781                         int                     subY;
3782                         int                     subW;
3783                         int                     subH;
3784                         int                     rowLength;
3785                         int                     skipRows;
3786                         int                     skipPixels;
3787                         int                     alignment;
3788                 } cases[] =
3789                 {
3790                         { "rgb8_alignment",             GL_RGB8,        54,     60,     11,     7,      31,     30,     0,      0,      0,      2 },
3791                         { "rgb8_row_length",    GL_RGB8,        54,     60,     11,     7,      31,     30,     50,     0,      0,      4 },
3792                         { "rgb8_skip_rows",             GL_RGB8,        54,     60,     11,     7,      31,     30,     0,      3,      0,      4 },
3793                         { "rgb8_skip_pixels",   GL_RGB8,        54,     60,     11,     7,      31,     30,     36,     0,      5,      4 },
3794                         { "r8_complex1",                GL_R8,          54,     60,     11,     7,      31, 30, 64, 1,  3,      1 },
3795                         { "r8_complex2",                GL_R8,          54,     60,     11,     7,      31, 30, 64, 1,  3,      2 },
3796                         { "r8_complex3",                GL_R8,          54,     60,     11,     7,      31, 30, 64, 1,  3,      4 },
3797                         { "r8_complex4",                GL_R8,          54,     60,     11,     7,      31, 30, 64, 1,  3,      8 },
3798                         { "rgba8_complex1",             GL_RGBA8,       92,     84,     13,     19,     56,     61,     69,     0,      0,      8 },
3799                         { "rgba8_complex2",             GL_RGBA8,       92,     84,     13,     19,     56,     61,     69,     0,      7,      8 },
3800                         { "rgba8_complex3",             GL_RGBA8,       92,     84,     13,     19,     56,     61,     69,     3,      0,      8 },
3801                         { "rgba8_complex4",             GL_RGBA8,       92,     84,     13,     19,     56,     61,     69,     3,      7,      8 },
3802                         { "rgba32f_complex",    GL_RGBA32F,     92,     84,     13,     19,     56,     61,     69,     3,      7,      8 }
3803                 };
3804
3805                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cases); ndx++)
3806                         paramGroup->addChild(new TexSubImage2DParamsCase(m_context, cases[ndx].name, "",
3807                                                                                                                          cases[ndx].format,
3808                                                                                                                          cases[ndx].width,
3809                                                                                                                          cases[ndx].height,
3810                                                                                                                          cases[ndx].subX,
3811                                                                                                                          cases[ndx].subY,
3812                                                                                                                          cases[ndx].subW,
3813                                                                                                                          cases[ndx].subH,
3814                                                                                                                          cases[ndx].rowLength,
3815                                                                                                                          cases[ndx].skipRows,
3816                                                                                                                          cases[ndx].skipPixels,
3817                                                                                                                          cases[ndx].alignment));
3818         }
3819
3820         // glTexSubImage2D() PBO cases.
3821         {
3822                 tcu::TestCaseGroup* pboGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage2d_pbo", "glTexSubImage2D() pixel buffer object tests");
3823                 addChild(pboGroup);
3824
3825                 static const struct
3826                 {
3827                         const char*     name;
3828                         deUint32        format;
3829                         int                     width;
3830                         int                     height;
3831                         int                     subX;
3832                         int                     subY;
3833                         int                     subW;
3834                         int                     subH;
3835                         int                     rowLength;
3836                         int                     skipRows;
3837                         int                     skipPixels;
3838                         int                     alignment;
3839                         int                     offset;
3840                 } paramCases[] =
3841                 {
3842                         { "rgb8_offset",                GL_RGB8,        54,     60,     11,     7,      31,     30,     0,      0,      0,      4,      67 },
3843                         { "rgb8_alignment",             GL_RGB8,        54,     60,     11,     7,      31,     30,     0,      0,      0,      2,      0 },
3844                         { "rgb8_row_length",    GL_RGB8,        54,     60,     11,     7,      31,     30,     50,     0,      0,      4,      0 },
3845                         { "rgb8_skip_rows",             GL_RGB8,        54,     60,     11,     7,      31,     30,     0,      3,      0,      4,      0 },
3846                         { "rgb8_skip_pixels",   GL_RGB8,        54,     60,     11,     7,      31,     30,     36,     0,      5,      4,      0 }
3847                 };
3848
3849                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(colorFormats); ndx++)
3850                 {
3851                         pboGroup->addChild(new TexSubImage2DBufferCase(m_context, (std::string(colorFormats[ndx].name) + "_2d").c_str(), "",
3852                                                                                                                    colorFormats[ndx].internalFormat,
3853                                                                                                                    54,  // Width
3854                                                                                                                    60,  // Height
3855                                                                                                                    11,  // Sub X
3856                                                                                                                    7,   // Sub Y
3857                                                                                                                    31,  // Sub W
3858                                                                                                                    30,  // Sub H
3859                                                                                                                    0,   // Row len
3860                                                                                                                    0,   // Skip rows
3861                                                                                                                    0,   // Skip pixels
3862                                                                                                                    4,   // Alignment
3863                                                                                                                    0    /* offset */));
3864                         pboGroup->addChild(new TexSubImageCubeBufferCase(m_context, (std::string(colorFormats[ndx].name) + "_cube").c_str(), "",
3865                                                                                                                    colorFormats[ndx].internalFormat,
3866                                                                                                                    64,  // Size
3867                                                                                                                    11,  // Sub X
3868                                                                                                                    7,   // Sub Y
3869                                                                                                                    31,  // Sub W
3870                                                                                                                    30,  // Sub H
3871                                                                                                                    0,   // Row len
3872                                                                                                                    0,   // Skip rows
3873                                                                                                                    0,   // Skip pixels
3874                                                                                                                    4,   // Alignment
3875                                                                                                                    0    /* offset */));
3876                 }
3877
3878                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(paramCases); ndx++)
3879                 {
3880                         pboGroup->addChild(new TexSubImage2DBufferCase(m_context, (std::string(paramCases[ndx].name) + "_2d").c_str(), "",
3881                                                                                                                    paramCases[ndx].format,
3882                                                                                                                    paramCases[ndx].width,
3883                                                                                                                    paramCases[ndx].height,
3884                                                                                                                    paramCases[ndx].subX,
3885                                                                                                                    paramCases[ndx].subY,
3886                                                                                                                    paramCases[ndx].subW,
3887                                                                                                                    paramCases[ndx].subH,
3888                                                                                                                    paramCases[ndx].rowLength,
3889                                                                                                                    paramCases[ndx].skipRows,
3890                                                                                                                    paramCases[ndx].skipPixels,
3891                                                                                                                    paramCases[ndx].alignment,
3892                                                                                                                    paramCases[ndx].offset));
3893                         pboGroup->addChild(new TexSubImageCubeBufferCase(m_context, (std::string(paramCases[ndx].name) + "_cube").c_str(), "",
3894                                                                                                                    paramCases[ndx].format,
3895                                                                                                                    paramCases[ndx].width,
3896                                                                                                                    paramCases[ndx].subX,
3897                                                                                                                    paramCases[ndx].subY,
3898                                                                                                                    paramCases[ndx].subW,
3899                                                                                                                    paramCases[ndx].subH,
3900                                                                                                                    paramCases[ndx].rowLength,
3901                                                                                                                    paramCases[ndx].skipRows,
3902                                                                                                                    paramCases[ndx].skipPixels,
3903                                                                                                                    paramCases[ndx].alignment,
3904                                                                                                                    paramCases[ndx].offset));
3905                 }
3906         }
3907
3908         // glTexSubImage2D() depth cases.
3909         {
3910                 tcu::TestCaseGroup* shadow2dGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage2d_depth", "glTexSubImage2D() with depth or depth/stencil format");
3911                 addChild(shadow2dGroup);
3912
3913                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++)
3914                 {
3915                         const int       tex2DWidth      = 64;
3916                         const int       tex2DHeight     = 32;
3917
3918                         shadow2dGroup->addChild(new TexSubImage2DDepthCase(m_context, depthStencilFormats[ndx].name, "", depthStencilFormats[ndx].internalFormat, tex2DWidth, tex2DHeight));
3919                 }
3920         }
3921
3922         // Basic glCopyTexImage2D() cases
3923         {
3924                 tcu::TestCaseGroup* copyTexImageGroup = new tcu::TestCaseGroup(m_testCtx, "basic_copyteximage2d", "Basic glCopyTexImage2D() usage");
3925                 addChild(copyTexImageGroup);
3926
3927                 copyTexImageGroup->addChild(new BasicCopyTexImage2DCase         (m_context, "2d_alpha",                         "",     GL_ALPHA,                       128, 64));
3928                 copyTexImageGroup->addChild(new BasicCopyTexImage2DCase         (m_context, "2d_luminance",                     "",     GL_LUMINANCE,           128, 64));
3929                 copyTexImageGroup->addChild(new BasicCopyTexImage2DCase         (m_context, "2d_luminance_alpha",       "",     GL_LUMINANCE_ALPHA,     128, 64));
3930                 copyTexImageGroup->addChild(new BasicCopyTexImage2DCase         (m_context, "2d_rgb",                           "",     GL_RGB,                         128, 64));
3931                 copyTexImageGroup->addChild(new BasicCopyTexImage2DCase         (m_context, "2d_rgba",                          "",     GL_RGBA,                        128, 64));
3932
3933                 copyTexImageGroup->addChild(new BasicCopyTexImageCubeCase       (m_context, "cube_alpha",                       "",     GL_ALPHA,                       64));
3934                 copyTexImageGroup->addChild(new BasicCopyTexImageCubeCase       (m_context, "cube_luminance",           "",     GL_LUMINANCE,           64));
3935                 copyTexImageGroup->addChild(new BasicCopyTexImageCubeCase       (m_context, "cube_luminance_alpha",     "",     GL_LUMINANCE_ALPHA,     64));
3936                 copyTexImageGroup->addChild(new BasicCopyTexImageCubeCase       (m_context, "cube_rgb",                         "",     GL_RGB,                         64));
3937                 copyTexImageGroup->addChild(new BasicCopyTexImageCubeCase       (m_context, "cube_rgba",                        "",     GL_RGBA,                        64));
3938         }
3939
3940         // Basic glCopyTexSubImage2D() cases
3941         {
3942                 tcu::TestCaseGroup* copyTexSubImageGroup = new tcu::TestCaseGroup(m_testCtx, "basic_copytexsubimage2d", "Basic glCopyTexSubImage2D() usage");
3943                 addChild(copyTexSubImageGroup);
3944
3945                 copyTexSubImageGroup->addChild(new BasicCopyTexSubImage2DCase   (m_context, "2d_alpha",                         "",     GL_ALPHA,                       GL_UNSIGNED_BYTE, 128, 64));
3946                 copyTexSubImageGroup->addChild(new BasicCopyTexSubImage2DCase   (m_context, "2d_luminance",                     "",     GL_LUMINANCE,           GL_UNSIGNED_BYTE, 128, 64));
3947                 copyTexSubImageGroup->addChild(new BasicCopyTexSubImage2DCase   (m_context, "2d_luminance_alpha",       "",     GL_LUMINANCE_ALPHA,     GL_UNSIGNED_BYTE, 128, 64));
3948                 copyTexSubImageGroup->addChild(new BasicCopyTexSubImage2DCase   (m_context, "2d_rgb",                           "",     GL_RGB,                         GL_UNSIGNED_BYTE, 128, 64));
3949                 copyTexSubImageGroup->addChild(new BasicCopyTexSubImage2DCase   (m_context, "2d_rgba",                          "",     GL_RGBA,                        GL_UNSIGNED_BYTE, 128, 64));
3950
3951                 copyTexSubImageGroup->addChild(new BasicCopyTexSubImageCubeCase (m_context, "cube_alpha",                       "",     GL_ALPHA,                       GL_UNSIGNED_BYTE, 64));
3952                 copyTexSubImageGroup->addChild(new BasicCopyTexSubImageCubeCase (m_context, "cube_luminance",           "",     GL_LUMINANCE,           GL_UNSIGNED_BYTE, 64));
3953                 copyTexSubImageGroup->addChild(new BasicCopyTexSubImageCubeCase (m_context, "cube_luminance_alpha",     "",     GL_LUMINANCE_ALPHA,     GL_UNSIGNED_BYTE, 64));
3954                 copyTexSubImageGroup->addChild(new BasicCopyTexSubImageCubeCase (m_context, "cube_rgb",                         "",     GL_RGB,                         GL_UNSIGNED_BYTE, 64));
3955                 copyTexSubImageGroup->addChild(new BasicCopyTexSubImageCubeCase (m_context, "cube_rgba",                        "",     GL_RGBA,                        GL_UNSIGNED_BYTE, 64));
3956         }
3957
3958         // Basic TexImage3D usage.
3959         {
3960                 tcu::TestCaseGroup* basicTexImageGroup = new tcu::TestCaseGroup(m_testCtx, "basic_teximage3d", "Basic glTexImage3D() usage");
3961                 addChild(basicTexImageGroup);
3962                 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++)
3963                 {
3964                         const char*     fmtName                         = colorFormats[formatNdx].name;
3965                         deUint32        format                          = colorFormats[formatNdx].internalFormat;
3966                         const int       tex2DArrayWidth         = 57;
3967                         const int       tex2DArrayHeight        = 44;
3968                         const int       tex2DArrayLevels        = 5;
3969                         const int       tex3DWidth                      = 63;
3970                         const int       tex3DHeight                     = 29;
3971                         const int       tex3DDepth                      = 11;
3972
3973                         basicTexImageGroup->addChild(new BasicTexImage2DArrayCase       (m_context,     (string(fmtName) + "_2d_array").c_str(),        "",     format, tex2DArrayWidth, tex2DArrayHeight, tex2DArrayLevels));
3974                         basicTexImageGroup->addChild(new BasicTexImage3DCase            (m_context,     (string(fmtName) + "_3d").c_str(),                      "",     format, tex3DWidth, tex3DHeight, tex3DDepth));
3975                 }
3976         }
3977
3978         // glTexImage3D() unpack params cases.
3979         {
3980                 tcu::TestCaseGroup* paramGroup = new tcu::TestCaseGroup(m_testCtx, "teximage3d_unpack_params", "glTexImage3D() unpack parameters");
3981                 addChild(paramGroup);
3982
3983                 static const struct
3984                 {
3985                         const char*     name;
3986                         deUint32        format;
3987                         int                     width;
3988                         int                     height;
3989                         int                     depth;
3990                         int                     imageHeight;
3991                         int                     rowLength;
3992                         int                     skipImages;
3993                         int                     skipRows;
3994                         int                     skipPixels;
3995                         int                     alignment;
3996                 } cases[] =
3997                 {
3998                         { "rgb8_image_height",  GL_RGB8,        23,     19,     8,      26,     0,      0,      0,      0,      4 },
3999                         { "rgb8_row_length",    GL_RGB8,        23,     19,     8,      0,      27,     0,      0,      0,      4 },
4000                         { "rgb8_skip_images",   GL_RGB8,        23,     19,     8,      0,      0,      3,      0,      0,      4 },
4001                         { "rgb8_skip_rows",             GL_RGB8,        23,     19,     8,      22,     0,      0,      3,      0,      4 },
4002                         { "rgb8_skip_pixels",   GL_RGB8,        23,     19,     8,      0,      25,     0,      0,      2,      4 },
4003                         { "r8_complex1",                GL_R8,          13, 17, 11,     23,     15,     2,      3,      1,      1 },
4004                         { "r8_complex2",                GL_R8,          13, 17, 11,     23,     15,     2,      3,      1,      2 },
4005                         { "r8_complex3",                GL_R8,          13, 17, 11,     23,     15,     2,      3,      1,      4 },
4006                         { "r8_complex4",                GL_R8,          13, 17, 11,     23,     15,     2,      3,      1,      8 },
4007                         { "rgba8_complex1",             GL_RGBA8,       11,     20,     8,      25,     14,     0,      0,      0,      8 },
4008                         { "rgba8_complex2",             GL_RGBA8,       11,     20,     8,      25,     14,     0,      2,      0,      8 },
4009                         { "rgba8_complex3",             GL_RGBA8,       11,     20,     8,      25,     14,     0,      0,      3,      8 },
4010                         { "rgba8_complex4",             GL_RGBA8,       11,     20,     8,      25,     14,     0,      2,      3,      8 },
4011                         { "rgba32f_complex",    GL_RGBA32F,     11,     20,     8,      25,     14,     0,      2,      3,      8 }
4012                 };
4013
4014                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cases); ndx++)
4015                         paramGroup->addChild(new TexImage3DParamsCase(m_context, cases[ndx].name, "",
4016                                                                                                                   cases[ndx].format,
4017                                                                                                                   cases[ndx].width,
4018                                                                                                                   cases[ndx].height,
4019                                                                                                                   cases[ndx].depth,
4020                                                                                                                   cases[ndx].imageHeight,
4021                                                                                                                   cases[ndx].rowLength,
4022                                                                                                                   cases[ndx].skipImages,
4023                                                                                                                   cases[ndx].skipRows,
4024                                                                                                                   cases[ndx].skipPixels,
4025                                                                                                                   cases[ndx].alignment));
4026         }
4027
4028         // glTexImage3D() pbo cases.
4029         {
4030                 tcu::TestCaseGroup* pboGroup = new tcu::TestCaseGroup(m_testCtx, "teximage3d_pbo", "glTexImage3D() from PBO");
4031                 addChild(pboGroup);
4032
4033                 // Parameter cases
4034                 static const struct
4035                 {
4036                         const char*     name;
4037                         deUint32        format;
4038                         int                     width;
4039                         int                     height;
4040                         int                     depth;
4041                         int                     imageHeight;
4042                         int                     rowLength;
4043                         int                     skipImages;
4044                         int                     skipRows;
4045                         int                     skipPixels;
4046                         int                     alignment;
4047                         int                     offset;
4048                 } parameterCases[] =
4049                 {
4050                         { "rgb8_offset",                GL_RGB8,        23,     19,     8,      0,      0,      0,      0,      0,      1,      67 },
4051                         { "rgb8_alignment",             GL_RGB8,        23,     19,     8,      0,      0,      0,      0,      0,      2,      0 },
4052                         { "rgb8_image_height",  GL_RGB8,        23,     19,     8,      26,     0,      0,      0,      0,      4,      0 },
4053                         { "rgb8_row_length",    GL_RGB8,        23,     19,     8,      0,      27,     0,      0,      0,      4,      0 },
4054                         { "rgb8_skip_images",   GL_RGB8,        23,     19,     8,      0,      0,      3,      0,      0,      4,      0 },
4055                         { "rgb8_skip_rows",             GL_RGB8,        23,     19,     8,      22,     0,      0,      3,      0,      4,      0 },
4056                         { "rgb8_skip_pixels",   GL_RGB8,        23,     19,     8,      0,      25,     0,      0,      2,      4,      0 }
4057                 };
4058
4059                 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++)
4060                 {
4061                         const string    fmtName         = colorFormats[formatNdx].name;
4062                         const deUint32  format          = colorFormats[formatNdx].internalFormat;
4063                         const int               tex3DWidth      = 11;
4064                         const int               tex3DHeight     = 20;
4065                         const int               tex3DDepth      = 8;
4066
4067                         pboGroup->addChild(new TexImage2DArrayBufferCase        (m_context, (fmtName + "_2d_array").c_str(),    "", format, tex3DWidth, tex3DHeight, tex3DDepth, 0, 0, 0, 0, 0, 4, 0));
4068                         pboGroup->addChild(new TexImage3DBufferCase                     (m_context, (fmtName + "_3d").c_str(),                  "", format, tex3DWidth, tex3DHeight, tex3DDepth, 0, 0, 0, 0, 0, 4, 0));
4069                 }
4070
4071                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(parameterCases); ndx++)
4072                 {
4073                         pboGroup->addChild(new TexImage2DArrayBufferCase(m_context, (string(parameterCases[ndx].name) + "_2d_array").c_str(), "",
4074                                                                                                                 parameterCases[ndx].format,
4075                                                                                                                 parameterCases[ndx].width,
4076                                                                                                                 parameterCases[ndx].depth,
4077                                                                                                                 parameterCases[ndx].height,
4078                                                                                                                 parameterCases[ndx].imageHeight,
4079                                                                                                                 parameterCases[ndx].rowLength,
4080                                                                                                                 parameterCases[ndx].skipImages,
4081                                                                                                                 parameterCases[ndx].skipRows,
4082                                                                                                                 parameterCases[ndx].skipPixels,
4083                                                                                                                 parameterCases[ndx].alignment,
4084                                                                                                                 parameterCases[ndx].offset));
4085                         pboGroup->addChild(new TexImage3DBufferCase(m_context, (string(parameterCases[ndx].name) + "_3d").c_str(), "",
4086                                                                                                                 parameterCases[ndx].format,
4087                                                                                                                 parameterCases[ndx].width,
4088                                                                                                                 parameterCases[ndx].depth,
4089                                                                                                                 parameterCases[ndx].height,
4090                                                                                                                 parameterCases[ndx].imageHeight,
4091                                                                                                                 parameterCases[ndx].rowLength,
4092                                                                                                                 parameterCases[ndx].skipImages,
4093                                                                                                                 parameterCases[ndx].skipRows,
4094                                                                                                                 parameterCases[ndx].skipPixels,
4095                                                                                                                 parameterCases[ndx].alignment,
4096                                                                                                                 parameterCases[ndx].offset));
4097                 }
4098         }
4099
4100         // glTexImage3D() depth cases.
4101         {
4102                 tcu::TestCaseGroup* shadow3dGroup = new tcu::TestCaseGroup(m_testCtx, "teximage3d_depth", "glTexImage3D() with depth or depth/stencil format");
4103                 addChild(shadow3dGroup);
4104
4105                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++)
4106                 {
4107                         const int       tex3DWidth      = 32;
4108                         const int       tex3DHeight     = 64;
4109                         const int       tex3DDepth      = 8;
4110
4111                         shadow3dGroup->addChild(new TexImage2DArrayDepthCase(m_context, (std::string(depthStencilFormats[ndx].name) + "_2d_array").c_str(), "", depthStencilFormats[ndx].internalFormat, tex3DWidth, tex3DHeight, tex3DDepth));
4112                 }
4113         }
4114
4115         // glTexImage3D() depth cases with pbo.
4116         {
4117                 tcu::TestCaseGroup* shadow3dGroup = new tcu::TestCaseGroup(m_testCtx, "teximage3d_depth_pbo", "glTexImage3D() with depth or depth/stencil format with pbo");
4118                 addChild(shadow3dGroup);
4119
4120                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++)
4121                 {
4122                         const int       tex3DWidth      = 32;
4123                         const int       tex3DHeight     = 64;
4124                         const int       tex3DDepth      = 8;
4125
4126                         shadow3dGroup->addChild(new TexImage2DArrayDepthBufferCase(m_context, (std::string(depthStencilFormats[ndx].name) + "_2d_array").c_str(), "", depthStencilFormats[ndx].internalFormat, tex3DWidth, tex3DHeight, tex3DDepth));
4127                 }
4128         }
4129
4130         // Basic TexSubImage3D usage.
4131         {
4132                 tcu::TestCaseGroup* basicTexSubImageGroup = new tcu::TestCaseGroup(m_testCtx, "basic_texsubimage3d", "Basic glTexSubImage3D() usage");
4133                 addChild(basicTexSubImageGroup);
4134                 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++)
4135                 {
4136                         const char*     fmtName         = colorFormats[formatNdx].name;
4137                         deUint32        format          = colorFormats[formatNdx].internalFormat;
4138                         const int       tex3DWidth      = 32;
4139                         const int       tex3DHeight     = 64;
4140                         const int       tex3DDepth      = 8;
4141
4142                         basicTexSubImageGroup->addChild(new BasicTexSubImage3DCase(m_context, (string(fmtName) + "_3d").c_str(), "", format, tex3DWidth, tex3DHeight, tex3DDepth));
4143                 }
4144         }
4145
4146         // glTexSubImage3D() unpack params cases.
4147         {
4148                 tcu::TestCaseGroup* paramGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage3d_unpack_params", "glTexSubImage3D() unpack parameters");
4149                 addChild(paramGroup);
4150
4151                 static const struct
4152                 {
4153                         const char*     name;
4154                         deUint32        format;
4155                         int                     width;
4156                         int                     height;
4157                         int                     depth;
4158                         int                     subX;
4159                         int                     subY;
4160                         int                     subZ;
4161                         int                     subW;
4162                         int                     subH;
4163                         int                     subD;
4164                         int                     imageHeight;
4165                         int                     rowLength;
4166                         int                     skipImages;
4167                         int                     skipRows;
4168                         int                     skipPixels;
4169                         int                     alignment;
4170                 } cases[] =
4171                 {
4172                         { "rgb8_image_height",  GL_RGB8,        26, 25, 10,     1,      2,      1,      23,     19,     8,      26,     0,      0,      0,      0,      4 },
4173                         { "rgb8_row_length",    GL_RGB8,        26, 25, 10,     1,      2,      1,      23,     19,     8,      0,      27,     0,      0,      0,      4 },
4174                         { "rgb8_skip_images",   GL_RGB8,        26, 25, 10,     1,      2,      1,      23,     19,     8,      0,      0,      3,      0,      0,      4 },
4175                         { "rgb8_skip_rows",             GL_RGB8,        26, 25, 10,     1,      2,      1,      23,     19,     8,      22,     0,      0,      3,      0,      4 },
4176                         { "rgb8_skip_pixels",   GL_RGB8,        26, 25, 10,     1,      2,      1,      23,     19,     8,      0,      25,     0,      0,      2,      4 },
4177                         { "r8_complex1",                GL_R8,          15,     20,     11,     1,      1,      0,      13, 17, 11,     23,     15,     2,      3,      1,      1 },
4178                         { "r8_complex2",                GL_R8,          15,     20,     11,     1,      1,      0,      13, 17, 11,     23,     15,     2,      3,      1,      2 },
4179                         { "r8_complex3",                GL_R8,          15,     20,     11,     1,      1,      0,      13, 17, 11,     23,     15,     2,      3,      1,      4 },
4180                         { "r8_complex4",                GL_R8,          15,     20,     11,     1,      1,      0,      13, 17, 11,     23,     15,     2,      3,      1,      8 },
4181                         { "rgba8_complex1",             GL_RGBA8,       15,     25,     10,     0,      5,      1,      11,     20,     8,      25,     14,     0,      0,      0,      8 },
4182                         { "rgba8_complex2",             GL_RGBA8,       15,     25,     10,     0,      5,      1,      11,     20,     8,      25,     14,     0,      2,      0,      8 },
4183                         { "rgba8_complex3",             GL_RGBA8,       15,     25,     10,     0,      5,      1,      11,     20,     8,      25,     14,     0,      0,      3,      8 },
4184                         { "rgba8_complex4",             GL_RGBA8,       15,     25,     10,     0,      5,      1,      11,     20,     8,      25,     14,     0,      2,      3,      8 },
4185                         { "rgba32f_complex",    GL_RGBA32F,     15,     25,     10,     0,      5,      1,      11,     20,     8,      25,     14,     0,      2,      3,      8 }
4186                 };
4187
4188                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cases); ndx++)
4189                         paramGroup->addChild(new TexSubImage3DParamsCase(m_context, cases[ndx].name, "",
4190                                                                                                                          cases[ndx].format,
4191                                                                                                                          cases[ndx].width,
4192                                                                                                                          cases[ndx].height,
4193                                                                                                                          cases[ndx].depth,
4194                                                                                                                          cases[ndx].subX,
4195                                                                                                                          cases[ndx].subY,
4196                                                                                                                          cases[ndx].subZ,
4197                                                                                                                          cases[ndx].subW,
4198                                                                                                                          cases[ndx].subH,
4199                                                                                                                          cases[ndx].subD,
4200                                                                                                                          cases[ndx].imageHeight,
4201                                                                                                                          cases[ndx].rowLength,
4202                                                                                                                          cases[ndx].skipImages,
4203                                                                                                                          cases[ndx].skipRows,
4204                                                                                                                          cases[ndx].skipPixels,
4205                                                                                                                          cases[ndx].alignment));
4206         }
4207
4208         // glTexSubImage3D() PBO cases.
4209         {
4210                 tcu::TestCaseGroup* pboGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage3d_pbo", "glTexSubImage3D() pixel buffer object tests");
4211                 addChild(pboGroup);
4212
4213                 static const struct
4214                 {
4215                         const char*     name;
4216                         deUint32        format;
4217                         int                     width;
4218                         int                     height;
4219                         int                     depth;
4220                         int                     subX;
4221                         int                     subY;
4222                         int                     subZ;
4223                         int                     subW;
4224                         int                     subH;
4225                         int                     subD;
4226                         int                     imageHeight;
4227                         int                     rowLength;
4228                         int                     skipImages;
4229                         int                     skipRows;
4230                         int                     skipPixels;
4231                         int                     alignment;
4232                         int                     offset;
4233                 } paramCases[] =
4234                 {
4235                         { "rgb8_offset",                GL_RGB8,        26, 25, 10,     1,      2,      1,      23,     19,     8,      0,      0,      0,      0,      0,      4,      67 },
4236                         { "rgb8_image_height",  GL_RGB8,        26, 25, 10,     1,      2,      1,      23,     19,     8,      26,     0,      0,      0,      0,      4,      0 },
4237                         { "rgb8_row_length",    GL_RGB8,        26, 25, 10,     1,      2,      1,      23,     19,     8,      0,      27,     0,      0,      0,      4,      0 },
4238                         { "rgb8_skip_images",   GL_RGB8,        26, 25, 10,     1,      2,      1,      23,     19,     8,      0,      0,      3,      0,      0,      4,      0 },
4239                         { "rgb8_skip_rows",             GL_RGB8,        26, 25, 10,     1,      2,      1,      23,     19,     8,      22,     0,      0,      3,      0,      4,      0 },
4240                         { "rgb8_skip_pixels",   GL_RGB8,        26, 25, 10,     1,      2,      1,      23,     19,     8,      0,      25,     0,      0,      2,      4,      0 }
4241                 };
4242
4243                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(colorFormats); ndx++)
4244                 {
4245                         pboGroup->addChild(new TexSubImage2DArrayBufferCase(m_context, (std::string(colorFormats[ndx].name) + "_2d_array").c_str(), "",
4246                                                                                                                    colorFormats[ndx].internalFormat,
4247                                                                                                                    26,  // Width
4248                                                                                                                    25,  // Height
4249                                                                                                                    10,  // Depth
4250                                                                                                                    1,   // Sub X
4251                                                                                                                    2,   // Sub Y
4252                                                                                                                    0,   // Sub Z
4253                                                                                                                    23,  // Sub W
4254                                                                                                                    19,  // Sub H
4255                                                                                                                    8,   // Sub D
4256                                                                                                                    0,   // Image height
4257                                                                                                                    0,   // Row length
4258                                                                                                                    0,   // Skip images
4259                                                                                                                    0,   // Skip rows
4260                                                                                                                    0,   // Skip pixels
4261                                                                                                                    4,   // Alignment
4262                                                                                                                    0    /* offset */));
4263                         pboGroup->addChild(new TexSubImage3DBufferCase(m_context, (std::string(colorFormats[ndx].name) + "_3d").c_str(), "",
4264                                                                                                                    colorFormats[ndx].internalFormat,
4265                                                                                                                    26,  // Width
4266                                                                                                                    25,  // Height
4267                                                                                                                    10,  // Depth
4268                                                                                                                    1,   // Sub X
4269                                                                                                                    2,   // Sub Y
4270                                                                                                                    0,   // Sub Z
4271                                                                                                                    23,  // Sub W
4272                                                                                                                    19,  // Sub H
4273                                                                                                                    8,   // Sub D
4274                                                                                                                    0,   // Image height
4275                                                                                                                    0,   // Row length
4276                                                                                                                    0,   // Skip images
4277                                                                                                                    0,   // Skip rows
4278                                                                                                                    0,   // Skip pixels
4279                                                                                                                    4,   // Alignment
4280                                                                                                                    0    /* offset */));
4281                 }
4282
4283                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(paramCases); ndx++)
4284                 {
4285                         pboGroup->addChild(new TexSubImage2DArrayBufferCase(m_context, (std::string(paramCases[ndx].name) + "_2d_array").c_str(), "",
4286                                                                                                                    paramCases[ndx].format,
4287                                                                                                                    paramCases[ndx].width,
4288                                                                                                                    paramCases[ndx].height,
4289                                                                                                                    paramCases[ndx].depth,
4290                                                                                                                    paramCases[ndx].subX,
4291                                                                                                                    paramCases[ndx].subY,
4292                                                                                                                    paramCases[ndx].subZ,
4293                                                                                                                    paramCases[ndx].subW,
4294                                                                                                                    paramCases[ndx].subH,
4295                                                                                                                    paramCases[ndx].subD,
4296                                                                                                                    paramCases[ndx].imageHeight,
4297                                                                                                                    paramCases[ndx].rowLength,
4298                                                                                                                    paramCases[ndx].skipImages,
4299                                                                                                                    paramCases[ndx].skipRows,
4300                                                                                                                    paramCases[ndx].skipPixels,
4301                                                                                                                    paramCases[ndx].alignment,
4302                                                                                                                    paramCases[ndx].offset));
4303                         pboGroup->addChild(new TexSubImage3DBufferCase(m_context, (std::string(paramCases[ndx].name) + "_3d").c_str(), "",
4304                                                                                                                    paramCases[ndx].format,
4305                                                                                                                    paramCases[ndx].width,
4306                                                                                                                    paramCases[ndx].height,
4307                                                                                                                    paramCases[ndx].depth,
4308                                                                                                                    paramCases[ndx].subX,
4309                                                                                                                    paramCases[ndx].subY,
4310                                                                                                                    paramCases[ndx].subZ,
4311                                                                                                                    paramCases[ndx].subW,
4312                                                                                                                    paramCases[ndx].subH,
4313                                                                                                                    paramCases[ndx].subD,
4314                                                                                                                    paramCases[ndx].imageHeight,
4315                                                                                                                    paramCases[ndx].rowLength,
4316                                                                                                                    paramCases[ndx].skipImages,
4317                                                                                                                    paramCases[ndx].skipRows,
4318                                                                                                                    paramCases[ndx].skipPixels,
4319                                                                                                                    paramCases[ndx].alignment,
4320                                                                                                                    paramCases[ndx].offset));
4321                 }
4322         }
4323
4324         // glTexSubImage3D() depth cases.
4325         {
4326                 tcu::TestCaseGroup* shadow3dGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage3d_depth", "glTexSubImage3D() with depth or depth/stencil format");
4327                 addChild(shadow3dGroup);
4328
4329                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++)
4330                 {
4331                         const int       tex2DArrayWidth         = 57;
4332                         const int       tex2DArrayHeight        = 44;
4333                         const int       tex2DArrayLevels        = 5;
4334
4335                         shadow3dGroup->addChild(new TexSubImage2DArrayDepthCase(m_context, (std::string(depthStencilFormats[ndx].name) + "_2d_array").c_str(), "", depthStencilFormats[ndx].internalFormat, tex2DArrayWidth, tex2DArrayHeight, tex2DArrayLevels));
4336                 }
4337         }
4338
4339         // glTexStorage2D() cases.
4340         {
4341                 tcu::TestCaseGroup* texStorageGroup = new tcu::TestCaseGroup(m_testCtx, "texstorage2d", "Basic glTexStorage2D() usage");
4342                 addChild(texStorageGroup);
4343
4344                 // All formats.
4345                 tcu::TestCaseGroup* formatGroup = new tcu::TestCaseGroup(m_testCtx, "format", "glTexStorage2D() with all formats");
4346                 texStorageGroup->addChild(formatGroup);
4347
4348                 // Color formats.
4349                 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++)
4350                 {
4351                         const char*     fmtName                 = colorFormats[formatNdx].name;
4352                         deUint32        internalFormat  = colorFormats[formatNdx].internalFormat;
4353                         const int       tex2DWidth              = 117;
4354                         const int       tex2DHeight             = 97;
4355                         int                     tex2DLevels             = maxLevelCount(tex2DWidth, tex2DHeight);
4356                         const int       cubeSize                = 57;
4357                         int                     cubeLevels              = maxLevelCount(cubeSize, cubeSize);
4358
4359                         formatGroup->addChild(new BasicTexStorage2DCase         (m_context, (string(fmtName) + "_2d").c_str(),          "", internalFormat, tex2DWidth, tex2DHeight, tex2DLevels));
4360                         formatGroup->addChild(new BasicTexStorageCubeCase       (m_context, (string(fmtName) + "_cube").c_str(),        "", internalFormat, cubeSize, cubeLevels));
4361                 }
4362
4363                 // Depth / stencil formats.
4364                 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(depthStencilFormats); formatNdx++)
4365                 {
4366                         const char*     fmtName                 = depthStencilFormats[formatNdx].name;
4367                         deUint32        internalFormat  = depthStencilFormats[formatNdx].internalFormat;
4368                         const int       tex2DWidth              = 117;
4369                         const int       tex2DHeight             = 97;
4370                         int                     tex2DLevels             = maxLevelCount(tex2DWidth, tex2DHeight);
4371                         const int       cubeSize                = 57;
4372                         int                     cubeLevels              = maxLevelCount(cubeSize, cubeSize);
4373
4374                         formatGroup->addChild(new BasicTexStorage2DCase         (m_context, (string(fmtName) + "_2d").c_str(),          "", internalFormat, tex2DWidth, tex2DHeight, tex2DLevels));
4375                         formatGroup->addChild(new BasicTexStorageCubeCase       (m_context, (string(fmtName) + "_cube").c_str(),        "", internalFormat, cubeSize, cubeLevels));
4376                 }
4377
4378                 // Sizes.
4379                 static const struct
4380                 {
4381                         int                             width;
4382                         int                             height;
4383                         int                             levels;
4384                 } tex2DSizes[] =
4385                 {
4386                         //      W       H       L
4387                         {       1,      1,      1 },
4388                         {       2,      2,      2 },
4389                         {       64,     32,     7 },
4390                         {       32,     64,     4 },
4391                         {       57,     63,     1 },
4392                         {       57,     63,     2 },
4393                         {       57,     63,     6 }
4394                 };
4395                 static const struct
4396                 {
4397                         int             size;
4398                         int             levels;
4399                 } cubeSizes[] =
4400                 {
4401                         //      S       L
4402                         {       1,      1 },
4403                         {       2,      2 },
4404                         {       57,     1 },
4405                         {       57,     2 },
4406                         {       57,     6 },
4407                         {       64,     4 },
4408                         {       64,     7 },
4409                 };
4410
4411                 tcu::TestCaseGroup* sizeGroup = new tcu::TestCaseGroup(m_testCtx, "size", "glTexStorage2D() with various sizes");
4412                 texStorageGroup->addChild(sizeGroup);
4413
4414                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(tex2DSizes); ndx++)
4415                 {
4416                         const deUint32          format          = GL_RGBA8;
4417                         int                                     width           = tex2DSizes[ndx].width;
4418                         int                                     height          = tex2DSizes[ndx].height;
4419                         int                                     levels          = tex2DSizes[ndx].levels;
4420                         string                          name            = string("2d_") + de::toString(width) + "x" + de::toString(height) + "_" + de::toString(levels) + "_levels";
4421
4422                         sizeGroup->addChild(new BasicTexStorage2DCase(m_context, name.c_str(), "", format, width, height, levels));
4423                 }
4424
4425                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cubeSizes); ndx++)
4426                 {
4427                         const deUint32          format          = GL_RGBA8;
4428                         int                                     size            = cubeSizes[ndx].size;
4429                         int                                     levels          = cubeSizes[ndx].levels;
4430                         string                          name            = string("cube_") + de::toString(size) + "x" + de::toString(size) + "_" + de::toString(levels) + "_levels";
4431
4432                         sizeGroup->addChild(new BasicTexStorageCubeCase(m_context, name.c_str(), "", format, size, levels));
4433                 }
4434         }
4435
4436         // glTexStorage3D() cases.
4437         {
4438                 tcu::TestCaseGroup* texStorageGroup = new tcu::TestCaseGroup(m_testCtx, "texstorage3d", "Basic glTexStorage3D() usage");
4439                 addChild(texStorageGroup);
4440
4441                 // All formats.
4442                 tcu::TestCaseGroup* formatGroup = new tcu::TestCaseGroup(m_testCtx, "format", "glTexStorage3D() with all formats");
4443                 texStorageGroup->addChild(formatGroup);
4444
4445                 // Color formats.
4446                 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++)
4447                 {
4448                         const char*     fmtName                         = colorFormats[formatNdx].name;
4449                         deUint32        internalFormat          = colorFormats[formatNdx].internalFormat;
4450                         const int       tex2DArrayWidth         = 57;
4451                         const int       tex2DArrayHeight        = 13;
4452                         const int       tex2DArrayLayers        = 7;
4453                         int                     tex2DArrayLevels        = maxLevelCount(tex2DArrayWidth, tex2DArrayHeight);
4454                         const int       tex3DWidth                      = 59;
4455                         const int       tex3DHeight                     = 37;
4456                         const int       tex3DDepth                      = 11;
4457                         int                     tex3DLevels                     = maxLevelCount(tex3DWidth, tex3DHeight, tex3DDepth);
4458
4459                         formatGroup->addChild(new BasicTexStorage2DArrayCase    (m_context, (string(fmtName) + "_2d_array").c_str(),    "", internalFormat, tex2DArrayWidth, tex2DArrayHeight, tex2DArrayLayers, tex2DArrayLevels));
4460                         formatGroup->addChild(new BasicTexStorage3DCase                 (m_context, (string(fmtName) + "_3d").c_str(),                  "", internalFormat, tex3DWidth, tex3DHeight, tex3DDepth, tex3DLevels));
4461                 }
4462
4463                 // Depth/stencil formats (only 2D texture array is supported).
4464                 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(depthStencilFormats); formatNdx++)
4465                 {
4466                         const char*     fmtName                         = depthStencilFormats[formatNdx].name;
4467                         deUint32        internalFormat          = depthStencilFormats[formatNdx].internalFormat;
4468                         const int       tex2DArrayWidth         = 57;
4469                         const int       tex2DArrayHeight        = 13;
4470                         const int       tex2DArrayLayers        = 7;
4471                         int                     tex2DArrayLevels        = maxLevelCount(tex2DArrayWidth, tex2DArrayHeight);
4472
4473                         formatGroup->addChild(new BasicTexStorage2DArrayCase    (m_context, (string(fmtName) + "_2d_array").c_str(),    "", internalFormat, tex2DArrayWidth, tex2DArrayHeight, tex2DArrayLayers, tex2DArrayLevels));
4474                 }
4475
4476                 // Sizes.
4477                 static const struct
4478                 {
4479                         int                             width;
4480                         int                             height;
4481                         int                             layers;
4482                         int                             levels;
4483                 } tex2DArraySizes[] =
4484                 {
4485                         //      W       H       La      Le
4486                         {       1,      1,      1,      1 },
4487                         {       2,      2,      2,      2 },
4488                         {       64,     32,     3,      7 },
4489                         {       32,     64,     3,      4 },
4490                         {       57,     63,     5,      1 },
4491                         {       57,     63,     5,      2 },
4492                         {       57,     63,     5,      6 }
4493                 };
4494                 static const struct
4495                 {
4496                         int                             width;
4497                         int                             height;
4498                         int                             depth;
4499                         int                             levels;
4500                 } tex3DSizes[] =
4501                 {
4502                         //      W       H       D       L
4503                         {       1,      1,      1,      1 },
4504                         {       2,      2,      2,      2 },
4505                         {       64,     32,     16,     7 },
4506                         {       32,     64,     16,     4 },
4507                         {       32,     16,     64,     4 },
4508                         {       57,     63,     11,     1 },
4509                         {       57,     63,     11,     2 },
4510                         {       57,     63,     11,     6 }
4511                 };
4512
4513                 tcu::TestCaseGroup* sizeGroup = new tcu::TestCaseGroup(m_testCtx, "size", "glTexStorage2D() with various sizes");
4514                 texStorageGroup->addChild(sizeGroup);
4515
4516                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(tex2DArraySizes); ndx++)
4517                 {
4518                         const deUint32          format          = GL_RGBA8;
4519                         int                                     width           = tex2DArraySizes[ndx].width;
4520                         int                                     height          = tex2DArraySizes[ndx].height;
4521                         int                                     layers          = tex2DArraySizes[ndx].layers;
4522                         int                                     levels          = tex2DArraySizes[ndx].levels;
4523                         string                          name            = string("2d_array_") + de::toString(width) + "x" + de::toString(height) + "x" + de::toString(layers) + "_" + de::toString(levels) + "_levels";
4524
4525                         sizeGroup->addChild(new BasicTexStorage2DArrayCase(m_context, name.c_str(), "", format, width, height, layers, levels));
4526                 }
4527
4528                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(tex3DSizes); ndx++)
4529                 {
4530                         const deUint32          format          = GL_RGBA8;
4531                         int                                     width           = tex3DSizes[ndx].width;
4532                         int                                     height          = tex3DSizes[ndx].height;
4533                         int                                     depth           = tex3DSizes[ndx].depth;
4534                         int                                     levels          = tex3DSizes[ndx].levels;
4535                         string                          name            = string("3d_") + de::toString(width) + "x" + de::toString(height) + "x" + de::toString(depth) + "_" + de::toString(levels) + "_levels";
4536
4537                         sizeGroup->addChild(new BasicTexStorage3DCase(m_context, name.c_str(), "", format, width, height, depth, levels));
4538                 }
4539         }
4540 }
4541
4542 } // Functional
4543 } // gles3
4544 } // deqp