Fix PIPELINE_STAGE_TOP_OF_PIPE_BIT usage in api tests
[platform/upstream/VK-GL-CTS.git] / modules / gles31 / functional / es31fTextureSpecificationTests.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 "es31fTextureSpecificationTests.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 "es31fFboTestUtil.hpp"
47
48 #include "glwEnums.hpp"
49
50 namespace deqp
51 {
52 namespace gles31
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 enum
67 {
68         VIEWPORT_WIDTH  = 256,
69         VIEWPORT_HEIGHT = 256
70 };
71
72 static inline int maxLevelCount (int size)
73 {
74         return (int)deLog2Floor32(size)+1;
75 }
76
77 template <int Size>
78 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))
79 {
80         tcu::Vector<float, Size> res;
81         for (int ndx = 0; ndx < Size; ndx++)
82                 res[ndx] = rnd.getFloat(minVal[ndx], maxVal[ndx]);
83         return res;
84 }
85
86 static tcu::CubeFace getCubeFaceFromNdx (int ndx)
87 {
88         switch (ndx)
89         {
90                 case 0: return tcu::CUBEFACE_POSITIVE_X;
91                 case 1: return tcu::CUBEFACE_NEGATIVE_X;
92                 case 2: return tcu::CUBEFACE_POSITIVE_Y;
93                 case 3: return tcu::CUBEFACE_NEGATIVE_Y;
94                 case 4: return tcu::CUBEFACE_POSITIVE_Z;
95                 case 5: return tcu::CUBEFACE_NEGATIVE_Z;
96                 default:
97                         DE_ASSERT(false);
98                         return tcu::CUBEFACE_LAST;
99         }
100 }
101
102 class TextureSpecCase : public TestCase, public sglr::ContextWrapper
103 {
104 public:
105                                                 TextureSpecCase                 (Context& context, const char* name, const char* desc);
106                                                 ~TextureSpecCase                (void);
107
108         IterateResult           iterate                                 (void);
109
110 protected:
111         virtual bool            checkExtensionSupport   (void)  { return true; }
112
113         virtual void            createTexture                   (void)                                                                                                                          = DE_NULL;
114         virtual void            verifyTexture                   (sglr::GLContext& gles3Context, sglr::ReferenceContext& refContext)     = DE_NULL;
115
116         // Utilities.
117         void                            renderTex                               (tcu::Surface& dst, deUint32 program, int width, int height);
118         void                            readPixels                              (tcu::Surface& dst, int x, int y, int width, int height);
119
120 private:
121                                                 TextureSpecCase                 (const TextureSpecCase& other);
122         TextureSpecCase&        operator=                               (const TextureSpecCase& other);
123 };
124
125 TextureSpecCase::TextureSpecCase (Context& context, const char* name, const char* desc)
126         : TestCase(context, name, desc)
127 {
128 }
129
130 TextureSpecCase::~TextureSpecCase (void)
131 {
132 }
133
134 TextureSpecCase::IterateResult TextureSpecCase::iterate (void)
135 {
136         glu::RenderContext&                     renderCtx                               = TestCase::m_context.getRenderContext();
137         const tcu::RenderTarget&        renderTarget                    = renderCtx.getRenderTarget();
138         tcu::TestLog&                           log                                             = m_testCtx.getLog();
139
140         if (renderTarget.getWidth() < VIEWPORT_WIDTH || renderTarget.getHeight() < VIEWPORT_HEIGHT)
141                 throw tcu::NotSupportedError("Too small viewport", "", __FILE__, __LINE__);
142
143         if (!checkExtensionSupport())
144                 throw tcu::NotSupportedError("Extension not supported", "", __FILE__, __LINE__);
145
146         // Context size, and viewport for GLES3.1
147         de::Random      rnd                     (deStringHash(getName()));
148         int                     width           = deMin32(renderTarget.getWidth(),      VIEWPORT_WIDTH);
149         int                     height          = deMin32(renderTarget.getHeight(),     VIEWPORT_HEIGHT);
150         int                     x                       = rnd.getInt(0, renderTarget.getWidth()         - width);
151         int                     y                       = rnd.getInt(0, renderTarget.getHeight()        - height);
152
153         // Contexts.
154         sglr::GLContext                                 gles31Context   (renderCtx, log, sglr::GLCONTEXT_LOG_CALLS, tcu::IVec4(x, y, width, height));
155         sglr::ReferenceContextBuffers   refBuffers              (tcu::PixelFormat(8,8,8,renderTarget.getPixelFormat().alphaBits?8:0), 0 /* depth */, 0 /* stencil */, width, height);
156         sglr::ReferenceContext                  refContext              (sglr::ReferenceContextLimits(renderCtx), refBuffers.getColorbuffer(), refBuffers.getDepthbuffer(), refBuffers.getStencilbuffer());
157
158         // Clear color buffer.
159         for (int ndx = 0; ndx < 2; ndx++)
160         {
161                 setContext(ndx ? (sglr::Context*)&refContext : (sglr::Context*)&gles31Context);
162                 glClearColor(0.125f, 0.25f, 0.5f, 1.0f);
163                 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
164         }
165
166         // Construct texture using both GLES3.1 and reference contexts.
167         for (int ndx = 0; ndx < 2; ndx++)
168         {
169                 setContext(ndx ? (sglr::Context*)&refContext : (sglr::Context*)&gles31Context);
170                 createTexture();
171                 TCU_CHECK(glGetError() == GL_NO_ERROR);
172         }
173
174         // Initialize case result to pass.
175         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
176
177         // Disable logging.
178         gles31Context.enableLogging(0);
179
180         // Verify results.
181         verifyTexture(gles31Context, refContext);
182
183         return STOP;
184 }
185
186 void TextureSpecCase::renderTex (tcu::Surface& dst, deUint32 program, int width, int height)
187 {
188         int             targetW         = getWidth();
189         int             targetH         = getHeight();
190
191         float   w                       = (float)width  / (float)targetW;
192         float   h                       = (float)height / (float)targetH;
193
194         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));
195
196         // Read pixels back.
197         readPixels(dst, 0, 0, width, height);
198 }
199
200 void TextureSpecCase::readPixels (tcu::Surface& dst, int x, int y, int width, int height)
201 {
202         dst.setSize(width, height);
203         glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, dst.getAccess().getDataPtr());
204 }
205
206 class TextureCubeArraySpecCase : public TextureSpecCase
207 {
208 public:
209                                                         TextureCubeArraySpecCase        (Context& context, const char* name, const char* desc, const tcu::TextureFormat& format, int size, int depth, int numLevels);
210                                                         ~TextureCubeArraySpecCase       (void);
211
212 protected:
213         virtual bool                    checkExtensionSupport           (void);
214         virtual void                    verifyTexture                           (sglr::GLContext& gles3Context, sglr::ReferenceContext& refContext);
215
216         tcu::TextureFormat              m_texFormat;
217         tcu::TextureFormatInfo  m_texFormatInfo;
218         int                                             m_size;
219         int                                             m_depth;
220         int                                             m_numLevels;
221 };
222
223 TextureCubeArraySpecCase::TextureCubeArraySpecCase (Context& context, const char* name, const char* desc, const tcu::TextureFormat& format, int size, int depth, int numLevels)
224         : TextureSpecCase               (context, name, desc)
225         , m_texFormat                   (format)
226         , m_texFormatInfo               (tcu::getTextureFormatInfo(format))
227         , m_size                                (size)
228         , m_depth                               (depth)
229         , m_numLevels                   (numLevels)
230 {
231 }
232
233 TextureCubeArraySpecCase::~TextureCubeArraySpecCase (void)
234 {
235 }
236
237 bool TextureCubeArraySpecCase::checkExtensionSupport (void)
238 {
239         const bool supportsES32 = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
240         return supportsES32 || m_context.getContextInfo().isExtensionSupported("GL_EXT_texture_cube_map_array");
241 }
242
243 void TextureCubeArraySpecCase::verifyTexture (sglr::GLContext& gles3Context, sglr::ReferenceContext& refContext)
244 {
245         const glu::GLSLVersion  glslVersion             = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
246         TextureCubeArrayShader  shader                  (glu::getSamplerCubeArrayType(m_texFormat), glu::TYPE_FLOAT_VEC4, glslVersion);
247         deUint32                                shaderIDgles    = gles3Context.createProgram(&shader);
248         deUint32                                shaderIDRef             = refContext.createProgram(&shader);
249
250         shader.setTexScaleBias(m_texFormatInfo.lookupScale, m_texFormatInfo.lookupBias);
251
252         // Set state.
253         for (int ndx = 0; ndx < 2; ndx++)
254         {
255                 sglr::Context* ctx = ndx ? static_cast<sglr::Context*>(&refContext) : static_cast<sglr::Context*>(&gles3Context);
256
257                 setContext(ctx);
258
259                 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER,       GL_NEAREST_MIPMAP_NEAREST);
260                 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER,       GL_NEAREST);
261                 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_S,           GL_CLAMP_TO_EDGE);
262                 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_T,           GL_CLAMP_TO_EDGE);
263                 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_R,           GL_CLAMP_TO_EDGE);
264                 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAX_LEVEL,        m_numLevels-1);
265         }
266
267         for (int layerFaceNdx = 0; layerFaceNdx < m_depth; layerFaceNdx++)
268         {
269                 const int                       layerNdx        = layerFaceNdx / 6;
270                 const tcu::CubeFace     face            = getCubeFaceFromNdx(layerFaceNdx % 6);
271                 bool                            layerOk         = true;
272
273                 shader.setLayer(layerNdx);
274                 shader.setFace(face);
275
276                 for (int levelNdx = 0; levelNdx < m_numLevels; levelNdx++)
277                 {
278                         int                             levelSize       = de::max(1, m_size     >> levelNdx);
279                         tcu::Surface    reference;
280                         tcu::Surface    result;
281
282                         if (levelSize <= 2)
283                                 continue; // Fuzzy compare doesn't work for images this small.
284
285                         for (int ndx = 0; ndx < 2; ndx++)
286                         {
287                                 tcu::Surface&   dst                     = ndx ? reference                                                                       : result;
288                                 sglr::Context*  ctx                     = ndx ? static_cast<sglr::Context*>(&refContext)        : static_cast<sglr::Context*>(&gles3Context);
289                                 deUint32                shaderID        = ndx ? shaderIDRef                                                                     : shaderIDgles;
290
291                                 setContext(ctx);
292                                 shader.setUniforms(*ctx, shaderID);
293                                 renderTex(dst, shaderID, levelSize, levelSize);
294                         }
295
296                         const float             threshold               = 0.02f;
297                         string                  levelStr                = de::toString(levelNdx);
298                         string                  layerFaceStr    = de::toString(layerFaceNdx);
299                         string                  name                    = string("LayerFace") + layerFaceStr + "Level" + levelStr;
300                         string                  desc                    = string("Layer-face ") + layerFaceStr + ", Level " + levelStr;
301                         bool                    isFaceOk                = tcu::fuzzyCompare(m_testCtx.getLog(), name.c_str(), desc.c_str(), reference, result, threshold,
302                                                                                                                                 (levelNdx == 0 && layerFaceNdx == 0) == 0 ? tcu::COMPARE_LOG_RESULT : tcu::COMPARE_LOG_ON_ERROR);
303
304                         if (!isFaceOk)
305                         {
306                                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
307                                 layerOk = false;
308                                 break;
309                         }
310                 }
311
312                 if (!layerOk)
313                         break;
314         }
315 }
316
317 // Basic TexImage3D() with cube map array texture usage
318 class BasicTexImageCubeArrayCase : public TextureCubeArraySpecCase
319 {
320 public:
321         BasicTexImageCubeArrayCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int size, int numLayers)
322                 : TextureCubeArraySpecCase      (context, name, desc, glu::mapGLInternalFormat(internalFormat), size, numLayers, maxLevelCount(size))
323                 , m_internalFormat                      (internalFormat)
324         {
325         }
326
327 protected:
328         void createTexture (void)
329         {
330                 deUint32                                tex                     = 0;
331                 de::Random                              rnd                     (deStringHash(getName()));
332                 glu::TransferFormat             transferFmt     = glu::getTransferFormat(m_texFormat);
333                 tcu::TextureLevel               levelData       (glu::mapGLTransferFormat(transferFmt.format, transferFmt.dataType));
334
335                 glGenTextures(1, &tex);
336                 glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, tex);
337                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
338
339                 for (int ndx = 0; ndx < m_numLevels; ndx++)
340                 {
341                         int             levelW          = de::max(1, m_size     >> ndx);
342                         Vec4    gMin            = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
343                         Vec4    gMax            = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
344
345                         levelData.setSize(levelW, levelW, m_depth);
346                         tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
347
348                         glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, ndx, m_internalFormat, levelW, levelW, m_depth, 0, transferFmt.format, transferFmt.dataType, levelData.getAccess().getDataPtr());
349                 }
350         }
351
352         deUint32 m_internalFormat;
353 };
354
355 // Basic glTexStorage3D() with cube map array texture usage
356 class BasicTexStorageCubeArrayCase : public TextureCubeArraySpecCase
357 {
358 public:
359         BasicTexStorageCubeArrayCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int size, int numLayers, int numLevels)
360                 : TextureCubeArraySpecCase      (context, name, desc, glu::mapGLInternalFormat(internalFormat), size, numLayers, numLevels)
361                 , m_internalFormat                      (internalFormat)
362         {
363         }
364
365 protected:
366         void createTexture (void)
367         {
368                 deUint32                                tex                     = 0;
369                 de::Random                              rnd                     (deStringHash(getName()));
370                 glu::TransferFormat             transferFmt     = glu::getTransferFormat(m_texFormat);
371                 tcu::TextureLevel               levelData       (glu::mapGLTransferFormat(transferFmt.format, transferFmt.dataType));
372
373                 glGenTextures   (1, &tex);
374                 glBindTexture   (GL_TEXTURE_CUBE_MAP_ARRAY, tex);
375                 glTexStorage3D  (GL_TEXTURE_CUBE_MAP_ARRAY, m_numLevels, m_internalFormat, m_size, m_size, m_depth);
376
377                 glPixelStorei   (GL_UNPACK_ALIGNMENT, 1);
378
379                 for (int ndx = 0; ndx < m_numLevels; ndx++)
380                 {
381                         int             levelW          = de::max(1, m_size     >> ndx);
382                         Vec4    gMin            = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
383                         Vec4    gMax            = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
384
385                         levelData.setSize(levelW, levelW, m_depth);
386                         tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
387
388                         glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, ndx, 0, 0, 0, levelW, levelW, m_depth, transferFmt.format, transferFmt.dataType, levelData.getAccess().getDataPtr());
389                 }
390         }
391
392         deUint32 m_internalFormat;
393 };
394
395 // Pixel buffer object cases.
396
397 // TexImage3D() cube map array from pixel buffer object.
398 class TexImageCubeArrayBufferCase : public TextureCubeArraySpecCase
399 {
400 public:
401         TexImageCubeArrayBufferCase (Context&           context,
402                                                            const char*  name,
403                                                            const char*  desc,
404                                                            deUint32             internalFormat,
405                                                            int                  size,
406                                                            int                  depth,
407                                                            int                  imageHeight,
408                                                            int                  rowLength,
409                                                            int                  skipImages,
410                                                            int                  skipRows,
411                                                            int                  skipPixels,
412                                                            int                  alignment,
413                                                            int                  offset)
414                 : TextureCubeArraySpecCase      (context, name, desc, glu::mapGLInternalFormat(internalFormat), size, depth, 1)
415                 , m_internalFormat                      (internalFormat)
416                 , m_imageHeight                         (imageHeight)
417                 , m_rowLength                           (rowLength)
418                 , m_skipImages                          (skipImages)
419                 , m_skipRows                            (skipRows)
420                 , m_skipPixels                          (skipPixels)
421                 , m_alignment                           (alignment)
422                 , m_offset                                      (offset)
423         {
424         }
425
426 protected:
427         void createTexture (void)
428         {
429                 glu::TransferFormat             transferFmt             = glu::getTransferFormat(m_texFormat);
430                 int                                             pixelSize               = m_texFormat.getPixelSize();
431                 int                                             rowLength               = m_rowLength > 0 ? m_rowLength : m_size;
432                 int                                             rowPitch                = deAlign32(rowLength*pixelSize, m_alignment);
433                 int                                             imageHeight             = m_imageHeight > 0 ? m_imageHeight : m_size;
434                 int                                             slicePitch              = imageHeight*rowPitch;
435                 deUint32                                tex                             = 0;
436                 deUint32                                buf                             = 0;
437                 vector<deUint8>                 data;
438
439                 DE_ASSERT(m_numLevels == 1);
440
441                 // Fill data with grid.
442                 data.resize(slicePitch*(m_depth+m_skipImages) + m_offset);
443                 {
444                         Vec4    cScale          = m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
445                         Vec4    cBias           = m_texFormatInfo.valueMin;
446                         Vec4    colorA          = Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
447                         Vec4    colorB          = Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
448
449                         tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, m_size, m_size, m_depth, rowPitch, slicePitch, &data[0] + m_skipImages*slicePitch + m_skipRows*rowPitch + m_skipPixels*pixelSize + m_offset), 4, colorA, colorB);
450                 }
451
452                 glGenBuffers(1, &buf);
453                 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf);
454                 glBufferData(GL_PIXEL_UNPACK_BUFFER, (int)data.size(), &data[0], GL_STATIC_DRAW);
455
456                 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT,   m_imageHeight);
457                 glPixelStorei(GL_UNPACK_ROW_LENGTH,             m_rowLength);
458                 glPixelStorei(GL_UNPACK_SKIP_IMAGES,    m_skipImages);
459                 glPixelStorei(GL_UNPACK_SKIP_ROWS,              m_skipRows);
460                 glPixelStorei(GL_UNPACK_SKIP_PIXELS,    m_skipPixels);
461                 glPixelStorei(GL_UNPACK_ALIGNMENT,              m_alignment);
462
463                 glGenTextures(1, &tex);
464                 glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, tex);
465                 glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, m_internalFormat, m_size, m_size, m_depth, 0, transferFmt.format, transferFmt.dataType, (const void*)(deUintptr)m_offset);
466         }
467
468         deUint32        m_internalFormat;
469         int                     m_imageHeight;
470         int                     m_rowLength;
471         int                     m_skipImages;
472         int                     m_skipRows;
473         int                     m_skipPixels;
474         int                     m_alignment;
475         int                     m_offset;
476 };
477
478 // TexSubImage3D() cube map array PBO case.
479 class TexSubImageCubeArrayBufferCase : public TextureCubeArraySpecCase
480 {
481 public:
482         TexSubImageCubeArrayBufferCase (Context&                context,
483                                                                  const char*    name,
484                                                                  const char*    desc,
485                                                                  deUint32               internalFormat,
486                                                                  int                    size,
487                                                                  int                    depth,
488                                                                  int                    subX,
489                                                                  int                    subY,
490                                                                  int                    subZ,
491                                                                  int                    subW,
492                                                                  int                    subH,
493                                                                  int                    subD,
494                                                                  int                    imageHeight,
495                                                                  int                    rowLength,
496                                                                  int                    skipImages,
497                                                                  int                    skipRows,
498                                                                  int                    skipPixels,
499                                                                  int                    alignment,
500                                                                  int                    offset)
501                 : TextureCubeArraySpecCase      (context, name, desc, glu::mapGLInternalFormat(internalFormat), size, depth, 1)
502                 , m_internalFormat                      (internalFormat)
503                 , m_subX                                        (subX)
504                 , m_subY                                        (subY)
505                 , m_subZ                                        (subZ)
506                 , m_subW                                        (subW)
507                 , m_subH                                        (subH)
508                 , m_subD                                        (subD)
509                 , m_imageHeight                         (imageHeight)
510                 , m_rowLength                           (rowLength)
511                 , m_skipImages                          (skipImages)
512                 , m_skipRows                            (skipRows)
513                 , m_skipPixels                          (skipPixels)
514                 , m_alignment                           (alignment)
515                 , m_offset                                      (offset)
516         {
517         }
518
519 protected:
520         void createTexture (void)
521         {
522                 glu::TransferFormat             transferFmt             = glu::getTransferFormat(m_texFormat);
523                 int                                             pixelSize               = m_texFormat.getPixelSize();
524                 deUint32                                tex                             = 0;
525                 deUint32                                buf                             = 0;
526                 vector<deUint8>                 data;
527
528                 DE_ASSERT(m_numLevels == 1);
529
530                 glGenTextures(1, &tex);
531                 glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, tex);
532
533                 // Fill with gradient.
534                 {
535                         int             rowPitch                = deAlign32(pixelSize*m_size,  4);
536                         int             slicePitch              = rowPitch*m_size;
537
538                         data.resize(slicePitch*m_depth);
539                         tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_size, m_size, m_depth, rowPitch, slicePitch, &data[0]), m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
540                 }
541
542                 glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, m_internalFormat, m_size, m_size, m_depth, 0, transferFmt.format, transferFmt.dataType, &data[0]);
543
544                 // Fill data with grid.
545                 {
546                         int             rowLength               = m_rowLength > 0 ? m_rowLength : m_subW;
547                         int             rowPitch                = deAlign32(rowLength*pixelSize, m_alignment);
548                         int             imageHeight             = m_imageHeight > 0 ? m_imageHeight : m_subH;
549                         int             slicePitch              = imageHeight*rowPitch;
550                         Vec4    cScale                  = m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
551                         Vec4    cBias                   = m_texFormatInfo.valueMin;
552                         Vec4    colorA                  = Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
553                         Vec4    colorB                  = Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
554
555                         data.resize(slicePitch*(m_depth+m_skipImages) + m_offset);
556                         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);
557                 }
558
559                 glGenBuffers(1, &buf);
560                 glBindBuffer(GL_PIXEL_UNPACK_BUFFER,    buf);
561                 glBufferData(GL_PIXEL_UNPACK_BUFFER,    (int)data.size(), &data[0], GL_STATIC_DRAW);
562
563                 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT,   m_imageHeight);
564                 glPixelStorei(GL_UNPACK_ROW_LENGTH,             m_rowLength);
565                 glPixelStorei(GL_UNPACK_SKIP_IMAGES,    m_skipImages);
566                 glPixelStorei(GL_UNPACK_SKIP_ROWS,              m_skipRows);
567                 glPixelStorei(GL_UNPACK_SKIP_PIXELS,    m_skipPixels);
568                 glPixelStorei(GL_UNPACK_ALIGNMENT,              m_alignment);
569                 glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, m_subX, m_subY, m_subZ, m_subW, m_subH, m_subD, transferFmt.format, transferFmt.dataType, (const void*)(deIntptr)m_offset);
570         }
571
572         deUint32        m_internalFormat;
573         int                     m_subX;
574         int                     m_subY;
575         int                     m_subZ;
576         int                     m_subW;
577         int                     m_subH;
578         int                     m_subD;
579         int                     m_imageHeight;
580         int                     m_rowLength;
581         int                     m_skipImages;
582         int                     m_skipRows;
583         int                     m_skipPixels;
584         int                     m_alignment;
585         int                     m_offset;
586 };
587
588 // TexImage3D() depth case.
589 class TexImageCubeArrayDepthCase : public TextureCubeArraySpecCase
590 {
591 public:
592         TexImageCubeArrayDepthCase (Context&    context,
593                                                           const char*   name,
594                                                           const char*   desc,
595                                                           deUint32              internalFormat,
596                                                           int                   imageSize,
597                                                           int                   numLayers)
598                 : TextureCubeArraySpecCase(context, name, desc, glu::mapGLInternalFormat(internalFormat), imageSize, numLayers, maxLevelCount(imageSize))
599                 , m_internalFormat              (internalFormat)
600         {
601                 // we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
602                 m_texFormatInfo.lookupBias = Vec4(0.25f, 0.0f, 0.0f, 1.0f);
603                 m_texFormatInfo.lookupScale = Vec4(0.5f, 1.0f, 1.0f, 0.0f);
604         }
605
606         void createTexture (void)
607         {
608                 glu::TransferFormat     fmt                     = glu::getTransferFormat(m_texFormat);
609                 deUint32                        tex                     = 0;
610                 tcu::TextureLevel       levelData       (glu::mapGLTransferFormat(fmt.format, fmt.dataType));
611
612                 glGenTextures(1, &tex);
613                 glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, tex);
614                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
615                 GLU_CHECK();
616
617                 for (int ndx = 0; ndx < m_numLevels; ndx++)
618                 {
619                         const int   levelW              = de::max(1, m_size >> ndx);
620                         const Vec4  gMin                = Vec4(-1.5f, -2.0f, 1.7f, -1.5f);
621                         const Vec4  gMax                = Vec4(2.0f, 1.5f, -1.0f, 2.0f);
622
623                         levelData.setSize(levelW, levelW, m_depth);
624                         tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
625
626                         glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, ndx, m_internalFormat, levelW, levelW, m_depth, 0, fmt.format, fmt.dataType, levelData.getAccess().getDataPtr());
627                 }
628         }
629
630         const deUint32 m_internalFormat;
631 };
632
633 // TexSubImage3D() depth case.
634 class TexSubImageCubeArrayDepthCase : public TextureCubeArraySpecCase
635 {
636 public:
637         TexSubImageCubeArrayDepthCase (Context&         context,
638                                                                  const char*    name,
639                                                                  const char*    desc,
640                                                                  deUint32               internalFormat,
641                                                                  int                    imageSize,
642                                                                  int                    numLayers)
643                 : TextureCubeArraySpecCase(context, name, desc, glu::mapGLInternalFormat(internalFormat), imageSize, numLayers, maxLevelCount(imageSize))
644                 , m_internalFormat              (internalFormat)
645         {
646                 // we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
647                 m_texFormatInfo.lookupBias = Vec4(0.25f, 0.0f, 0.0f, 1.0f);
648                 m_texFormatInfo.lookupScale = Vec4(0.5f, 1.0f, 1.0f, 0.0f);
649         }
650
651         void createTexture (void)
652         {
653                 glu::TransferFormat     fmt                     = glu::getTransferFormat(m_texFormat);
654                 de::Random                      rnd                     (deStringHash(getName()));
655                 deUint32                        tex                     = 0;
656                 tcu::TextureLevel       levelData       (glu::mapGLTransferFormat(fmt.format, fmt.dataType));
657
658                 glGenTextures(1, &tex);
659                 glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, tex);
660                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
661                 GLU_CHECK();
662
663                 // First specify full texture.
664                 for (int ndx = 0; ndx < m_numLevels; ndx++)
665                 {
666                         const int   levelW              = de::max(1, m_size >> ndx);
667                         const Vec4  gMin                = Vec4(-1.5f, -2.0f, 1.7f, -1.5f);
668                         const Vec4  gMax                = Vec4(2.0f, 1.5f, -1.0f, 2.0f);
669
670                         levelData.setSize(levelW, levelW, m_depth);
671                         tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
672
673                         glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, ndx, m_internalFormat, levelW, levelW, m_depth, 0, fmt.format, fmt.dataType, levelData.getAccess().getDataPtr());
674                 }
675
676                 // Re-specify parts of each level.
677                 for (int ndx = 0; ndx < m_numLevels; ndx++)
678                 {
679                         const int       levelW          = de::max(1, m_size >> ndx);
680
681                         const int       w                       = rnd.getInt(1, levelW);
682                         const int       h                       = rnd.getInt(1, levelW);
683                         const int       d                       = rnd.getInt(1, m_depth);
684                         const int       x                       = rnd.getInt(0, levelW-w);
685                         const int       y                       = rnd.getInt(0, levelW-h);
686                         const int       z                       = rnd.getInt(0, m_depth-d);
687
688                         const Vec4      colorA          = Vec4(2.0f, 1.5f, -1.0f, 2.0f);
689                         const Vec4      colorB          = Vec4(-1.5f, -2.0f, 1.7f, -1.5f);
690                         const int       cellSize        = rnd.getInt(2, 16);
691
692                         levelData.setSize(w, h, d);
693                         tcu::fillWithGrid(levelData.getAccess(), cellSize, colorA, colorB);
694
695                         glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, ndx, x, y, z, w, h, d, fmt.format, fmt.dataType, levelData.getAccess().getDataPtr());
696                 }
697         }
698
699         const deUint32 m_internalFormat;
700 };
701
702 // TexImage3D() depth case with pbo.
703 class TexImageCubeArrayDepthBufferCase : public TextureCubeArraySpecCase
704 {
705 public:
706         TexImageCubeArrayDepthBufferCase (Context&      context,
707                                                                         const char*     name,
708                                                                         const char*     desc,
709                                                                         deUint32        internalFormat,
710                                                                         int                     imageSize,
711                                                                         int                     numLayers)
712                 : TextureCubeArraySpecCase(context, name, desc, glu::mapGLInternalFormat(internalFormat), imageSize, numLayers, 1)
713                 , m_internalFormat              (internalFormat)
714         {
715                 // we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
716                 m_texFormatInfo.lookupBias = Vec4(0.25f, 0.0f, 0.0f, 1.0f);
717                 m_texFormatInfo.lookupScale = Vec4(0.5f, 1.0f, 1.0f, 0.0f);
718         }
719
720         void createTexture (void)
721         {
722                 glu::TransferFormat             transferFmt             = glu::getTransferFormat(m_texFormat);
723                 int                                             pixelSize               = m_texFormat.getPixelSize();
724                 int                                             rowLength               = m_size;
725                 int                                             alignment               = 4;
726                 int                                             rowPitch                = deAlign32(rowLength*pixelSize, alignment);
727                 int                                             imageHeight             = m_size;
728                 int                                             slicePitch              = imageHeight*rowPitch;
729                 deUint32                                tex                             = 0;
730                 deUint32                                buf                             = 0;
731                 vector<deUint8>                 data;
732
733                 DE_ASSERT(m_numLevels == 1);
734
735                 // Fill data with grid.
736                 data.resize(slicePitch*m_depth);
737                 {
738                         const Vec4 gMin = Vec4(-1.5f, -2.0f, 1.7f, -1.5f);
739                         const Vec4 gMax = Vec4(2.0f, 1.5f, -1.0f, 2.0f);
740
741                         tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_size, m_size, m_depth, rowPitch, slicePitch, &data[0]), gMin, gMax);
742                 }
743
744                 glGenBuffers(1, &buf);
745                 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf);
746                 glBufferData(GL_PIXEL_UNPACK_BUFFER, (int)data.size(), &data[0], GL_STATIC_DRAW);
747
748                 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT,   imageHeight);
749                 glPixelStorei(GL_UNPACK_ROW_LENGTH,             rowLength);
750                 glPixelStorei(GL_UNPACK_SKIP_IMAGES,    0);
751                 glPixelStorei(GL_UNPACK_SKIP_ROWS,              0);
752                 glPixelStorei(GL_UNPACK_SKIP_PIXELS,    0);
753                 glPixelStorei(GL_UNPACK_ALIGNMENT,              alignment);
754
755                 glGenTextures(1, &tex);
756                 glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, tex);
757                 glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, m_internalFormat, m_size, m_size, m_depth, 0, transferFmt.format, transferFmt.dataType, DE_NULL);
758                 glDeleteBuffers(1, &buf);
759         }
760
761         const deUint32 m_internalFormat;
762 };
763
764 TextureSpecificationTests::TextureSpecificationTests (Context& context)
765         : TestCaseGroup(context, "specification", "Texture Specification Tests")
766 {
767 }
768
769 TextureSpecificationTests::~TextureSpecificationTests (void)
770 {
771 }
772
773 void TextureSpecificationTests::init (void)
774 {
775         struct
776         {
777                 const char*     name;
778                 deUint32        internalFormat;
779         } colorFormats[] =
780         {
781                 { "rgba32f",                    GL_RGBA32F,                     },
782                 { "rgba32i",                    GL_RGBA32I,                     },
783                 { "rgba32ui",                   GL_RGBA32UI,            },
784                 { "rgba16f",                    GL_RGBA16F,                     },
785                 { "rgba16i",                    GL_RGBA16I,                     },
786                 { "rgba16ui",                   GL_RGBA16UI,            },
787                 { "rgba8",                              GL_RGBA8,                       },
788                 { "rgba8i",                             GL_RGBA8I,                      },
789                 { "rgba8ui",                    GL_RGBA8UI,                     },
790                 { "srgb8_alpha8",               GL_SRGB8_ALPHA8,        },
791                 { "rgb10_a2",                   GL_RGB10_A2,            },
792                 { "rgb10_a2ui",                 GL_RGB10_A2UI,          },
793                 { "rgba4",                              GL_RGBA4,                       },
794                 { "rgb5_a1",                    GL_RGB5_A1,                     },
795                 { "rgba8_snorm",                GL_RGBA8_SNORM,         },
796                 { "rgb8",                               GL_RGB8,                        },
797                 { "rgb565",                             GL_RGB565,                      },
798                 { "r11f_g11f_b10f",             GL_R11F_G11F_B10F,      },
799                 { "rgb32f",                             GL_RGB32F,                      },
800                 { "rgb32i",                             GL_RGB32I,                      },
801                 { "rgb32ui",                    GL_RGB32UI,                     },
802                 { "rgb16f",                             GL_RGB16F,                      },
803                 { "rgb16i",                             GL_RGB16I,                      },
804                 { "rgb16ui",                    GL_RGB16UI,                     },
805                 { "rgb8_snorm",                 GL_RGB8_SNORM,          },
806                 { "rgb8i",                              GL_RGB8I,                       },
807                 { "rgb8ui",                             GL_RGB8UI,                      },
808                 { "srgb8",                              GL_SRGB8,                       },
809                 { "rgb9_e5",                    GL_RGB9_E5,                     },
810                 { "rg32f",                              GL_RG32F,                       },
811                 { "rg32i",                              GL_RG32I,                       },
812                 { "rg32ui",                             GL_RG32UI,                      },
813                 { "rg16f",                              GL_RG16F,                       },
814                 { "rg16i",                              GL_RG16I,                       },
815                 { "rg16ui",                             GL_RG16UI,                      },
816                 { "rg8",                                GL_RG8,                         },
817                 { "rg8i",                               GL_RG8I,                        },
818                 { "rg8ui",                              GL_RG8UI,                       },
819                 { "rg8_snorm",                  GL_RG8_SNORM,           },
820                 { "r32f",                               GL_R32F,                        },
821                 { "r32i",                               GL_R32I,                        },
822                 { "r32ui",                              GL_R32UI,                       },
823                 { "r16f",                               GL_R16F,                        },
824                 { "r16i",                               GL_R16I,                        },
825                 { "r16ui",                              GL_R16UI,                       },
826                 { "r8",                                 GL_R8,                          },
827                 { "r8i",                                GL_R8I,                         },
828                 { "r8ui",                               GL_R8UI,                        },
829                 { "r8_snorm",                   GL_R8_SNORM,            }
830         };
831
832         static const struct
833         {
834                 const char*     name;
835                 deUint32        internalFormat;
836         } depthStencilFormats[] =
837         {
838                 // Depth and stencil formats
839                 { "depth_component32f", GL_DEPTH_COMPONENT32F   },
840                 { "depth_component24",  GL_DEPTH_COMPONENT24    },
841                 { "depth_component16",  GL_DEPTH_COMPONENT16    },
842                 { "depth32f_stencil8",  GL_DEPTH32F_STENCIL8    },
843                 { "depth24_stencil8",   GL_DEPTH24_STENCIL8             }
844         };
845
846         // Basic TexImage3D usage.
847         {
848                 tcu::TestCaseGroup* basicTexImageGroup = new tcu::TestCaseGroup(m_testCtx, "basic_teximage3d", "Basic glTexImage3D() usage");
849                 addChild(basicTexImageGroup);
850                 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++)
851                 {
852                         const char*     fmtName                         = colorFormats[formatNdx].name;
853                         deUint32        format                          = colorFormats[formatNdx].internalFormat;
854                         const int       texCubeArraySize        = 64;
855                         const int       texCubeArrayLayers      = 6;
856
857                         basicTexImageGroup->addChild(new BasicTexImageCubeArrayCase     (m_context,     (string(fmtName) + "_cube_array").c_str(),      "",     format, texCubeArraySize, texCubeArrayLayers));
858                 }
859         }
860
861         // glTexImage3D() pbo cases.
862         {
863                 tcu::TestCaseGroup* pboGroup = new tcu::TestCaseGroup(m_testCtx, "teximage3d_pbo", "glTexImage3D() from PBO");
864                 addChild(pboGroup);
865
866                 // Parameter cases
867                 static const struct
868                 {
869                         const char*     name;
870                         deUint32        format;
871                         int                     size;
872                         int                     depth;
873                         int                     imageHeight;
874                         int                     rowLength;
875                         int                     skipImages;
876                         int                     skipRows;
877                         int                     skipPixels;
878                         int                     alignment;
879                         int                     offset;
880                 } parameterCases[] =
881                 {
882                         { "rgb8_offset",                GL_RGB8,        23,     6,      0,      0,      0,      0,      0,      1,      67 },
883                         { "rgb8_alignment",             GL_RGB8,        23,     6,      0,      0,      0,      0,      0,      2,      0 },
884                         { "rgb8_image_height",  GL_RGB8,        23,     6,      26,     0,      0,      0,      0,      4,      0 },
885                         { "rgb8_row_length",    GL_RGB8,        23,     6,      0,      27,     0,      0,      0,      4,      0 },
886                         { "rgb8_skip_images",   GL_RGB8,        23,     6,      0,      0,      3,      0,      0,      4,      0 },
887                         { "rgb8_skip_rows",             GL_RGB8,        23,     6,      26,     0,      0,      3,      0,      4,      0 },
888                         { "rgb8_skip_pixels",   GL_RGB8,        23,     6,      0,      25,     0,      0,      2,      4,      0 }
889                 };
890
891                 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++)
892                 {
893                         const string    fmtName                         = colorFormats[formatNdx].name;
894                         const deUint32  format                          = colorFormats[formatNdx].internalFormat;
895                         const int               texCubeArraySize        = 20;
896                         const int               texCubeDepth            = 6;
897
898                         pboGroup->addChild(new TexImageCubeArrayBufferCase      (m_context, (fmtName + "_cube_array").c_str(),  "", format, texCubeArraySize, texCubeDepth, 0, 0, 0, 0, 0, 4, 0));
899                 }
900
901                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(parameterCases); ndx++)
902                 {
903                         pboGroup->addChild(new TexImageCubeArrayBufferCase(m_context, (string(parameterCases[ndx].name) + "_cube_array").c_str(), "",
904                                                                                                                 parameterCases[ndx].format,
905                                                                                                                 parameterCases[ndx].size,
906                                                                                                                 parameterCases[ndx].depth,
907                                                                                                                 parameterCases[ndx].imageHeight,
908                                                                                                                 parameterCases[ndx].rowLength,
909                                                                                                                 parameterCases[ndx].skipImages,
910                                                                                                                 parameterCases[ndx].skipRows,
911                                                                                                                 parameterCases[ndx].skipPixels,
912                                                                                                                 parameterCases[ndx].alignment,
913                                                                                                                 parameterCases[ndx].offset));
914                 }
915         }
916
917         // glTexImage3D() depth cases.
918         {
919                 tcu::TestCaseGroup* shadow3dGroup = new tcu::TestCaseGroup(m_testCtx, "teximage3d_depth", "glTexImage3D() with depth or depth/stencil format");
920                 addChild(shadow3dGroup);
921
922                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++)
923                 {
924                         const int       texCubeArraySize        = 64;
925                         const int       texCubeArrayDepth       = 6;
926
927                         shadow3dGroup->addChild(new TexImageCubeArrayDepthCase(m_context, (std::string(depthStencilFormats[ndx].name) + "_cube_array").c_str(), "", depthStencilFormats[ndx].internalFormat, texCubeArraySize, texCubeArrayDepth));
928                 }
929         }
930
931         // glTexImage3D() depth cases with pbo.
932         {
933                 tcu::TestCaseGroup* shadow3dGroup = new tcu::TestCaseGroup(m_testCtx, "teximage3d_depth_pbo", "glTexImage3D() with depth or depth/stencil format with pbo");
934                 addChild(shadow3dGroup);
935
936                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++)
937                 {
938                         const int       texCubeArraySize        = 64;
939                         const int       texCubeArrayDepth       = 6;
940
941                         shadow3dGroup->addChild(new TexImageCubeArrayDepthBufferCase(m_context, (std::string(depthStencilFormats[ndx].name) + "_cube_array").c_str(), "", depthStencilFormats[ndx].internalFormat, texCubeArraySize, texCubeArrayDepth));
942                 }
943         }
944
945         // glTexSubImage3D() PBO cases.
946         {
947                 tcu::TestCaseGroup* pboGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage3d_pbo", "glTexSubImage3D() pixel buffer object tests");
948                 addChild(pboGroup);
949
950                 static const struct
951                 {
952                         const char*     name;
953                         deUint32        format;
954                         int                     size;
955                         int                     depth;
956                         int                     subX;
957                         int                     subY;
958                         int                     subZ;
959                         int                     subW;
960                         int                     subH;
961                         int                     subD;
962                         int                     imageHeight;
963                         int                     rowLength;
964                         int                     skipImages;
965                         int                     skipRows;
966                         int                     skipPixels;
967                         int                     alignment;
968                         int                     offset;
969                 } paramCases[] =
970                 {
971                         { "rgb8_offset",                GL_RGB8,        26, 12, 1,      2,      1,      23,     19,     8,      0,      0,      0,      0,      0,      4,      67 },
972                         { "rgb8_image_height",  GL_RGB8,        26, 12, 1,      2,      1,      23,     19,     8,      26,     0,      0,      0,      0,      4,      0 },
973                         { "rgb8_row_length",    GL_RGB8,        26, 12, 1,      2,      1,      23,     19,     8,      0,      27,     0,      0,      0,      4,      0 },
974                         { "rgb8_skip_images",   GL_RGB8,        26, 12, 1,      2,      1,      23,     19,     8,      0,      0,      3,      0,      0,      4,      0 },
975                         { "rgb8_skip_rows",             GL_RGB8,        26, 12, 1,      2,      1,      23,     19,     8,      22,     0,      0,      3,      0,      4,      0 },
976                         { "rgb8_skip_pixels",   GL_RGB8,        26, 12, 1,      2,      1,      23,     19,     8,      0,      25,     0,      0,      2,      4,      0 }
977                 };
978
979                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(colorFormats); ndx++)
980                 {
981                         pboGroup->addChild(new TexSubImageCubeArrayBufferCase(m_context, (std::string(colorFormats[ndx].name) + "_cube_array").c_str(), "",
982                                                                                                                    colorFormats[ndx].internalFormat,
983                                                                                                                    26,  // Size
984                                                                                                                    12,  // Depth
985                                                                                                                    1,   // Sub X
986                                                                                                                    2,   // Sub Y
987                                                                                                                    0,   // Sub Z
988                                                                                                                    23,  // Sub W
989                                                                                                                    19,  // Sub H
990                                                                                                                    8,   // Sub D
991                                                                                                                    0,   // Image height
992                                                                                                                    0,   // Row length
993                                                                                                                    0,   // Skip images
994                                                                                                                    0,   // Skip rows
995                                                                                                                    0,   // Skip pixels
996                                                                                                                    4,   // Alignment
997                                                                                                                    0    /* offset */));
998                 }
999
1000                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(paramCases); ndx++)
1001                 {
1002                         pboGroup->addChild(new TexSubImageCubeArrayBufferCase(m_context, (std::string(paramCases[ndx].name) + "_cube_array").c_str(), "",
1003                                                                                                                    paramCases[ndx].format,
1004                                                                                                                    paramCases[ndx].size,
1005                                                                                                                    paramCases[ndx].depth,
1006                                                                                                                    paramCases[ndx].subX,
1007                                                                                                                    paramCases[ndx].subY,
1008                                                                                                                    paramCases[ndx].subZ,
1009                                                                                                                    paramCases[ndx].subW,
1010                                                                                                                    paramCases[ndx].subH,
1011                                                                                                                    paramCases[ndx].subD,
1012                                                                                                                    paramCases[ndx].imageHeight,
1013                                                                                                                    paramCases[ndx].rowLength,
1014                                                                                                                    paramCases[ndx].skipImages,
1015                                                                                                                    paramCases[ndx].skipRows,
1016                                                                                                                    paramCases[ndx].skipPixels,
1017                                                                                                                    paramCases[ndx].alignment,
1018                                                                                                                    paramCases[ndx].offset));
1019                 }
1020         }
1021
1022         // glTexSubImage3D() depth cases.
1023         {
1024                 tcu::TestCaseGroup* shadow3dGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage3d_depth", "glTexSubImage3D() with depth or depth/stencil format");
1025                 addChild(shadow3dGroup);
1026
1027                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++)
1028                 {
1029                         const int       texCubeArraySize        = 57;
1030                         const int       texCubeArrayLayers      = 6;
1031
1032                         shadow3dGroup->addChild(new TexSubImageCubeArrayDepthCase(m_context, (std::string(depthStencilFormats[ndx].name) + "_cube_array").c_str(), "", depthStencilFormats[ndx].internalFormat, texCubeArraySize, texCubeArrayLayers));
1033                 }
1034         }
1035
1036         // glTexStorage3D() cases.
1037         {
1038                 tcu::TestCaseGroup* texStorageGroup = new tcu::TestCaseGroup(m_testCtx, "texstorage3d", "Basic glTexStorage3D() usage");
1039                 addChild(texStorageGroup);
1040
1041                 // All formats.
1042                 tcu::TestCaseGroup* formatGroup = new tcu::TestCaseGroup(m_testCtx, "format", "glTexStorage3D() with all formats");
1043                 texStorageGroup->addChild(formatGroup);
1044
1045                 // Color formats.
1046                 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++)
1047                 {
1048                         const char*     fmtName                         = colorFormats[formatNdx].name;
1049                         deUint32        internalFormat          = colorFormats[formatNdx].internalFormat;
1050                         const int       texCubeArraySize        = 57;
1051                         const int       texCubeArrayLayers      = 6;
1052                         int                     texCubeArrayLevels      = maxLevelCount(texCubeArraySize);
1053
1054                         formatGroup->addChild(new BasicTexStorageCubeArrayCase  (m_context, (string(fmtName) + "_cube_array").c_str(),  "", internalFormat, texCubeArraySize, texCubeArrayLayers, texCubeArrayLevels));
1055                 }
1056
1057                 // Depth/stencil formats (only 2D texture array is supported).
1058                 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(depthStencilFormats); formatNdx++)
1059                 {
1060                         const char*     fmtName                         = depthStencilFormats[formatNdx].name;
1061                         deUint32        internalFormat          = depthStencilFormats[formatNdx].internalFormat;
1062                         const int       texCubeArraySize        = 57;
1063                         const int       texCubeArrayLayers      = 6;
1064                         int                     texCubeArrayLevels      = maxLevelCount(texCubeArraySize);
1065
1066                         formatGroup->addChild(new BasicTexStorageCubeArrayCase  (m_context, (string(fmtName) + "_cube_array").c_str(),  "", internalFormat, texCubeArraySize, texCubeArrayLayers, texCubeArrayLevels));
1067                 }
1068
1069                 // Sizes.
1070                 static const struct
1071                 {
1072                         int                             size;
1073                         int                             layers;
1074                         int                             levels;
1075                 } texCubeArraySizes[] =
1076                 {
1077                         //      Sz      La      Le
1078                         {       1,      6,      1 },
1079                         {       2,      6,      2 },
1080                         {       32,     6,      3 },
1081                         {       64,     6,      4 },
1082                         {       57,     12,     1 },
1083                         {       57,     12,     2 },
1084                         {       57,     12,     6 }
1085                 };
1086
1087                 tcu::TestCaseGroup* sizeGroup = new tcu::TestCaseGroup(m_testCtx, "size", "glTexStorage3D() with various sizes");
1088                 texStorageGroup->addChild(sizeGroup);
1089
1090                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(texCubeArraySizes); ndx++)
1091                 {
1092                         const deUint32          format          = GL_RGBA8;
1093                         int                                     size            = texCubeArraySizes[ndx].size;
1094                         int                                     layers          = texCubeArraySizes[ndx].layers;
1095                         int                                     levels          = texCubeArraySizes[ndx].levels;
1096                         string                          name            = string("cube_array_") + de::toString(size) + "x" + de::toString(size) + "x" + de::toString(layers) + "_" + de::toString(levels) + "_levels";
1097
1098                         sizeGroup->addChild(new BasicTexStorageCubeArrayCase(m_context, name.c_str(), "", format, size, layers, levels));
1099                 }
1100         }
1101 }
1102
1103 } // Functional
1104 } // gles3
1105 } // deqp