Add new framebuffer fetch extension tests am: 2a609fb223
[platform/upstream/VK-GL-CTS.git] / modules / gles2 / functional / es2fTextureSpecificationTests.cpp
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES 2.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 "es2fTextureSpecificationTests.hpp"
30 #include "tcuTestLog.hpp"
31 #include "tcuImageCompare.hpp"
32 #include "gluTextureUtil.hpp"
33 #include "sglrContextUtil.hpp"
34 #include "sglrContextWrapper.hpp"
35 #include "sglrGLContext.hpp"
36 #include "sglrReferenceContext.hpp"
37 #include "glsTextureTestUtil.hpp"
38 #include "tcuTextureUtil.hpp"
39 #include "tcuFormatUtil.hpp"
40 #include "tcuVectorUtil.hpp"
41 #include "deRandom.hpp"
42 #include "deStringUtil.hpp"
43
44 #include "glwEnums.hpp"
45 #include "glwFunctions.hpp"
46
47 namespace deqp
48 {
49 namespace gles2
50 {
51 namespace Functional
52 {
53
54 using std::string;
55 using std::vector;
56 using std::pair;
57 using tcu::TestLog;
58 using tcu::Vec4;
59 using tcu::IVec4;
60 using tcu::UVec4;
61
62 tcu::TextureFormat mapGLUnsizedInternalFormat (deUint32 internalFormat)
63 {
64         using tcu::TextureFormat;
65         switch (internalFormat)
66         {
67                 case GL_ALPHA:                          return TextureFormat(TextureFormat::A,          TextureFormat::UNORM_INT8);
68                 case GL_LUMINANCE:                      return TextureFormat(TextureFormat::L,          TextureFormat::UNORM_INT8);
69                 case GL_LUMINANCE_ALPHA:        return TextureFormat(TextureFormat::LA,         TextureFormat::UNORM_INT8);
70                 case GL_RGB:                            return TextureFormat(TextureFormat::RGB,        TextureFormat::UNORM_INT8);
71                 case GL_RGBA:                           return TextureFormat(TextureFormat::RGBA,       TextureFormat::UNORM_INT8);
72                 default:
73                         throw tcu::InternalError(string("Can't map GL unsized internal format (") + tcu::toHex(internalFormat).toString() + ") to texture format");
74         }
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::IVec4 getPixelFormatCompareDepth (const tcu::PixelFormat& pixelFormat, tcu::TextureFormat textureFormat)
87 {
88         switch (textureFormat.order)
89         {
90                 case tcu::TextureFormat::L:
91                 case tcu::TextureFormat::LA:
92                         return tcu::IVec4(pixelFormat.redBits, pixelFormat.redBits, pixelFormat.redBits, pixelFormat.alphaBits);
93                 default:
94                         return tcu::IVec4(pixelFormat.redBits, pixelFormat.greenBits, pixelFormat.blueBits, pixelFormat.alphaBits);
95         }
96 }
97
98 static tcu::UVec4 computeCompareThreshold (const tcu::PixelFormat& pixelFormat, tcu::TextureFormat textureFormat)
99 {
100         const IVec4             texFormatBits           = tcu::getTextureFormatBitDepth(textureFormat);
101         const IVec4             pixelFormatBits         = getPixelFormatCompareDepth(pixelFormat, textureFormat);
102         const IVec4             accurateFmtBits         = min(pixelFormatBits, texFormatBits);
103         const IVec4             compareBits                     = select(accurateFmtBits, IVec4(8), greaterThan(accurateFmtBits, IVec4(0))) - 1;
104
105         return (IVec4(1) << (8-compareBits)).asUint();
106 }
107
108 class GradientShader : public sglr::ShaderProgram
109 {
110 public:
111         GradientShader (void)
112                 : ShaderProgram(sglr::pdec::ShaderProgramDeclaration()
113                                         << sglr::pdec::VertexAttribute("a_position", rr::GENERICVECTYPE_FLOAT)
114                                         << sglr::pdec::VertexAttribute("a_coord", rr::GENERICVECTYPE_FLOAT)
115                                         << sglr::pdec::VertexToFragmentVarying(rr::GENERICVECTYPE_FLOAT)
116                                         << sglr::pdec::FragmentOutput(rr::GENERICVECTYPE_FLOAT)
117                                         << sglr::pdec::VertexSource("attribute highp vec4 a_position;\n"
118                                                                                                 "attribute mediump vec2 a_coord;\n"
119                                                                                                 "varying mediump vec2 v_coord;\n"
120                                                                                                 "void main (void)\n"
121                                                                                                 "{\n"
122                                                                                                 "       gl_Position = a_position;\n"
123                                                                                                 "       v_coord = a_coord;\n"
124                                                                                                 "}\n")
125                                         << sglr::pdec::FragmentSource("varying mediump vec2 v_coord;\n"
126                                                                                                   "void main (void)\n"
127                                                                                                   "{\n"
128                                                                                                   "     mediump float x = v_coord.x;\n"
129                                                                                                   "     mediump float y = v_coord.y;\n"
130                                                                                                   "     mediump float f0 = (x + y) * 0.5;\n"
131                                                                                                   "     mediump float f1 = 0.5 + (x - y) * 0.5;\n"
132                                                                                                   "     gl_FragColor = vec4(f0, f1, 1.0-f0, 1.0-f1);\n"
133                                                                                                   "}\n"))
134         {
135         }
136
137         void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const
138         {
139                 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
140                 {
141                         rr::VertexPacket& packet = *packets[packetNdx];
142
143                         packet.position         = rr::readVertexAttribFloat(inputs[0], packet.instanceNdx, packet.vertexNdx);
144                         packet.outputs[0]       = rr::readVertexAttribFloat(inputs[1], packet.instanceNdx, packet.vertexNdx);
145                 }
146         }
147
148         void shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const
149         {
150                 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
151                 for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
152                 {
153                         const tcu::Vec4         coord   = rr::readTriangleVarying<float>(packets[packetNdx], context, 0, fragNdx);
154                         const float                     x               = coord.x();
155                         const float                     y               = coord.y();
156                         const float                     f0              = (x + y) * 0.5f;
157                         const float                     f1              = 0.5f + (x - y) * 0.5f;
158
159                         rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, tcu::Vec4(f0, f1, 1.0f-f0, 1.0f-f1));
160                 }
161         }
162 };
163
164 class Tex2DShader : public sglr::ShaderProgram
165 {
166 public:
167         Tex2DShader (void)
168                 : ShaderProgram(sglr::pdec::ShaderProgramDeclaration()
169                                         << sglr::pdec::VertexAttribute("a_position", rr::GENERICVECTYPE_FLOAT)
170                                         << sglr::pdec::VertexAttribute("a_coord", rr::GENERICVECTYPE_FLOAT)
171                                         << sglr::pdec::VertexToFragmentVarying(rr::GENERICVECTYPE_FLOAT)
172                                         << sglr::pdec::FragmentOutput(rr::GENERICVECTYPE_FLOAT)
173                                         << sglr::pdec::Uniform("u_sampler0", glu::TYPE_SAMPLER_2D)
174                                         << sglr::pdec::VertexSource("attribute highp vec4 a_position;\n"
175                                                                                                 "attribute mediump vec2 a_coord;\n"
176                                                                                                 "varying mediump vec2 v_coord;\n"
177                                                                                                 "void main (void)\n"
178                                                                                                 "{\n"
179                                                                                                 "       gl_Position = a_position;\n"
180                                                                                                 "       v_coord = a_coord;\n"
181                                                                                                 "}\n")
182                                         << sglr::pdec::FragmentSource("uniform sampler2D u_sampler0;\n"
183                                                                                                   "varying mediump vec2 v_coord;\n"
184                                                                                                   "void main (void)\n"
185                                                                                                   "{\n"
186                                                                                                   "     gl_FragColor = texture2D(u_sampler0, v_coord);\n"
187                                                                                                   "}\n"))
188         {
189         }
190
191         void setUniforms (sglr::Context& ctx, deUint32 program) const
192         {
193                 ctx.useProgram(program);
194                 ctx.uniform1i(ctx.getUniformLocation(program, "u_sampler0"), 0);
195         }
196
197         void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const
198         {
199                 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
200                 {
201                         rr::VertexPacket& packet = *packets[packetNdx];
202
203                         packet.position         = rr::readVertexAttribFloat(inputs[0], packet.instanceNdx, packet.vertexNdx);
204                         packet.outputs[0]       = rr::readVertexAttribFloat(inputs[1], packet.instanceNdx, packet.vertexNdx);
205                 }
206         }
207
208         void shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const
209         {
210                 tcu::Vec2 texCoords[4];
211                 tcu::Vec4 colors[4];
212
213                 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
214                 {
215                         // setup tex coords
216                         for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
217                         {
218                                 const tcu::Vec4 coord = rr::readTriangleVarying<float>(packets[packetNdx], context, 0, fragNdx);
219                                 texCoords[fragNdx] = tcu::Vec2(coord.x(), coord.y());
220                         }
221
222                         // Sample
223                         m_uniforms[0].sampler.tex2D->sample4(colors, texCoords);
224
225                         // Write out
226                         for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
227                                 rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, colors[fragNdx]);
228                 }
229         }
230 };
231
232 static const char* s_cubeSwizzles[] =
233 {
234         "vec3(-1, -y, +x)",
235         "vec3(+1, -y, -x)",
236         "vec3(+x, -1, -y)",
237         "vec3(+x, +1, +y)",
238         "vec3(-x, -y, -1)",
239         "vec3(+x, -y, +1)"
240 };
241
242 class TexCubeShader : public sglr::ShaderProgram
243 {
244 public:
245         TexCubeShader (tcu::CubeFace face)
246                 : ShaderProgram(sglr::pdec::ShaderProgramDeclaration()
247                                         << sglr::pdec::VertexAttribute("a_position", rr::GENERICVECTYPE_FLOAT)
248                                         << sglr::pdec::VertexAttribute("a_coord", rr::GENERICVECTYPE_FLOAT)
249                                         << sglr::pdec::VertexToFragmentVarying(rr::GENERICVECTYPE_FLOAT)
250                                         << sglr::pdec::FragmentOutput(rr::GENERICVECTYPE_FLOAT)
251                                         << sglr::pdec::Uniform("u_sampler0", glu::TYPE_SAMPLER_CUBE)
252                                         << sglr::pdec::VertexSource("attribute highp vec4 a_position;\n"
253                                                                                                 "attribute mediump vec2 a_coord;\n"
254                                                                                                 "varying mediump vec2 v_coord;\n"
255                                                                                                 "void main (void)\n"
256                                                                                                 "{\n"
257                                                                                                 "       gl_Position = a_position;\n"
258                                                                                                 "       v_coord = a_coord;\n"
259                                                                                                 "}\n")
260                                         << sglr::pdec::FragmentSource(string("") +
261                                                                                                   "uniform samplerCube u_sampler0;\n"
262                                                                                                   "varying mediump vec2 v_coord;\n"
263                                                                                                   "void main (void)\n"
264                                                                                                   "{\n"
265                                                                                                   "     mediump float x = v_coord.x*2.0 - 1.0;\n"
266                                                                                                   "     mediump float y = v_coord.y*2.0 - 1.0;\n"
267                                                                                                   "     gl_FragColor = textureCube(u_sampler0, " + s_cubeSwizzles[face] + ");\n"
268                                                                                                   "}\n"))
269                 , m_face(face)
270         {
271         }
272
273         void setUniforms (sglr::Context& ctx, deUint32 program) const
274         {
275                 ctx.useProgram(program);
276                 ctx.uniform1i(ctx.getUniformLocation(program, "u_sampler0"), 0);
277         }
278
279         void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const
280         {
281                 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
282                 {
283                         rr::VertexPacket& packet = *packets[packetNdx];
284
285                         packet.position         = rr::readVertexAttribFloat(inputs[0], packet.instanceNdx, packet.vertexNdx);
286                         packet.outputs[0]       = rr::readVertexAttribFloat(inputs[1], packet.instanceNdx, packet.vertexNdx);
287                 }
288         }
289
290         void shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const
291         {
292                 tcu::Vec3 texCoords[4];
293                 tcu::Vec4 colors[4];
294
295                 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
296                 {
297                         // setup tex coords
298                         for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
299                         {
300                                 const tcu::Vec4 coord   = rr::readTriangleVarying<float>(packets[packetNdx], context, 0, fragNdx);
301                                 const float             x               = coord.x()*2.0f - 1.0f;
302                                 const float             y               = coord.y()*2.0f - 1.0f;
303
304                                 // Swizzle tex coords
305                                 switch (m_face)
306                                 {
307                                         case tcu::CUBEFACE_NEGATIVE_X:  texCoords[fragNdx] = tcu::Vec3(-1.0f,    -y,    +x);            break;
308                                         case tcu::CUBEFACE_POSITIVE_X:  texCoords[fragNdx] = tcu::Vec3(+1.0f,    -y,    -x);            break;
309                                         case tcu::CUBEFACE_NEGATIVE_Y:  texCoords[fragNdx] = tcu::Vec3(   +x, -1.0f,    -y);            break;
310                                         case tcu::CUBEFACE_POSITIVE_Y:  texCoords[fragNdx] = tcu::Vec3(   +x, +1.0f,    +y);            break;
311                                         case tcu::CUBEFACE_NEGATIVE_Z:  texCoords[fragNdx] = tcu::Vec3(   -x,    -y, -1.0f);            break;
312                                         case tcu::CUBEFACE_POSITIVE_Z:  texCoords[fragNdx] = tcu::Vec3(   +x,    -y, +1.0f);            break;
313                                         default:
314                                                 DE_ASSERT(false);
315                                 }
316                         }
317
318                         // Sample
319                         m_uniforms[0].sampler.texCube->sample4(colors, texCoords);
320
321                         // Write out
322                         for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
323                                 rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, colors[fragNdx]);
324                 }
325         }
326 private:
327         tcu::CubeFace m_face;
328 };
329
330 enum TextureType
331 {
332         TEXTURETYPE_2D = 0,
333         TEXTURETYPE_CUBE,
334
335         TEXTURETYPE_LAST
336 };
337
338 enum Flags
339 {
340         MIPMAPS         = (1<<0)
341 };
342
343 static const deUint32 s_cubeMapFaces[] =
344 {
345         GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
346         GL_TEXTURE_CUBE_MAP_POSITIVE_X,
347         GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
348         GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
349         GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
350         GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
351 };
352
353 class TextureSpecCase : public TestCase, public sglr::ContextWrapper
354 {
355 public:
356                                                                 TextureSpecCase         (Context& context, const char* name, const char* desc, const TextureType type, const tcu::TextureFormat format, const deUint32 flags, int width, int height);
357                                                                 ~TextureSpecCase        (void);
358
359         IterateResult                           iterate                         (void);
360
361 protected:
362         virtual void                            createTexture           (void) = DE_NULL;
363
364         const TextureType                       m_texType;
365         const tcu::TextureFormat        m_texFormat;
366         const deUint32                          m_flags;
367         const int                                       m_width;
368         const int                                       m_height;
369
370 private:
371                                                                 TextureSpecCase         (const TextureSpecCase& other);
372         TextureSpecCase&                        operator=                       (const TextureSpecCase& other);
373
374         void                                            verifyTex2D                     (sglr::GLContext& gles2Context, sglr::ReferenceContext& refContext);
375         void                                            verifyTexCube           (sglr::GLContext& gles2Context, sglr::ReferenceContext& refContext);
376
377         void                                            renderTex2D                     (tcu::Surface& dst, int width, int height);
378         void                                            renderTexCube           (tcu::Surface& dst, int width, int height, tcu::CubeFace face);
379
380         void                                            readPixels                      (tcu::Surface& dst, int x, int y, int width, int height);
381
382         // \todo [2012-03-27 pyry] Renderer should be extended to allow custom attributes, that would clean up this cubemap mess.
383         Tex2DShader                                     m_tex2DShader;
384         TexCubeShader                           m_texCubeNegXShader;
385         TexCubeShader                           m_texCubePosXShader;
386         TexCubeShader                           m_texCubeNegYShader;
387         TexCubeShader                           m_texCubePosYShader;
388         TexCubeShader                           m_texCubeNegZShader;
389         TexCubeShader                           m_texCubePosZShader;
390 };
391
392 TextureSpecCase::TextureSpecCase (Context& context, const char* name, const char* desc, const TextureType type, const tcu::TextureFormat format, const deUint32 flags, int width, int height)
393         : TestCase                              (context, name, desc)
394         , m_texType                             (type)
395         , m_texFormat                   (format)
396         , m_flags                               (flags)
397         , m_width                               (width)
398         , m_height                              (height)
399         , m_texCubeNegXShader   (tcu::CUBEFACE_NEGATIVE_X)
400         , m_texCubePosXShader   (tcu::CUBEFACE_POSITIVE_X)
401         , m_texCubeNegYShader   (tcu::CUBEFACE_NEGATIVE_Y)
402         , m_texCubePosYShader   (tcu::CUBEFACE_POSITIVE_Y)
403         , m_texCubeNegZShader   (tcu::CUBEFACE_NEGATIVE_Z)
404         , m_texCubePosZShader   (tcu::CUBEFACE_POSITIVE_Z)
405 {
406 }
407
408 TextureSpecCase::~TextureSpecCase (void)
409 {
410 }
411
412 TextureSpecCase::IterateResult TextureSpecCase::iterate (void)
413 {
414         glu::RenderContext&                     renderCtx                               = TestCase::m_context.getRenderContext();
415         const tcu::RenderTarget&        renderTarget                    = renderCtx.getRenderTarget();
416         tcu::TestLog&                           log                                             = m_testCtx.getLog();
417
418         DE_ASSERT(m_width <= 256 && m_height <= 256);
419         if (renderTarget.getWidth() < m_width || renderTarget.getHeight() < m_height)
420                 throw tcu::NotSupportedError("Too small viewport", "", __FILE__, __LINE__);
421
422         // Context size, and viewport for GLES2
423         de::Random              rnd                     (deStringHash(getName()));
424         int                             width           = deMin32(renderTarget.getWidth(),      256);
425         int                             height          = deMin32(renderTarget.getHeight(),     256);
426         int                             x                       = rnd.getInt(0, renderTarget.getWidth()         - width);
427         int                             y                       = rnd.getInt(0, renderTarget.getHeight()        - height);
428
429         // Contexts.
430         sglr::GLContext                                 gles2Context    (renderCtx, log, sglr::GLCONTEXT_LOG_CALLS, tcu::IVec4(x, y, width, height));
431         sglr::ReferenceContextBuffers   refBuffers              (tcu::PixelFormat(8,8,8,renderTarget.getPixelFormat().alphaBits?8:0), 0 /* depth */, 0 /* stencil */, width, height);
432         sglr::ReferenceContext                  refContext              (sglr::ReferenceContextLimits(renderCtx), refBuffers.getColorbuffer(), refBuffers.getDepthbuffer(), refBuffers.getStencilbuffer());
433
434         // Clear color buffer.
435         for (int ndx = 0; ndx < 2; ndx++)
436         {
437                 setContext(ndx ? (sglr::Context*)&refContext : (sglr::Context*)&gles2Context);
438                 glClearColor(0.125f, 0.25f, 0.5f, 1.0f);
439                 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
440         }
441
442         // Construct texture using both GLES2 and reference contexts.
443         for (int ndx = 0; ndx < 2; ndx++)
444         {
445                 setContext(ndx ? (sglr::Context*)&refContext : (sglr::Context*)&gles2Context);
446                 createTexture();
447                 TCU_CHECK(glGetError() == GL_NO_ERROR);
448         }
449
450         // Setup texture filtering state.
451         for (int ndx = 0; ndx < 2; ndx++)
452         {
453                 setContext(ndx ? (sglr::Context*)&refContext : (sglr::Context*)&gles2Context);
454
455                 deUint32 texTarget = m_texType == TEXTURETYPE_2D ? GL_TEXTURE_2D : GL_TEXTURE_CUBE_MAP;
456                 glTexParameteri(texTarget, GL_TEXTURE_MIN_FILTER,       (m_flags & MIPMAPS) ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST);
457                 glTexParameteri(texTarget, GL_TEXTURE_MAG_FILTER,       GL_NEAREST);
458                 glTexParameteri(texTarget, GL_TEXTURE_WRAP_S,           GL_CLAMP_TO_EDGE);
459                 glTexParameteri(texTarget, GL_TEXTURE_WRAP_T,           GL_CLAMP_TO_EDGE);
460         }
461
462         // Initialize case result to pass.
463         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
464
465         // Disable logging.
466         gles2Context.enableLogging(0);
467
468         // Verify results.
469         switch (m_texType)
470         {
471                 case TEXTURETYPE_2D:    verifyTex2D             (gles2Context, refContext);     break;
472                 case TEXTURETYPE_CUBE:  verifyTexCube   (gles2Context, refContext);     break;
473                 default:
474                         DE_ASSERT(false);
475         }
476
477         return STOP;
478 }
479
480 void TextureSpecCase::verifyTex2D (sglr::GLContext& gles2Context, sglr::ReferenceContext& refContext)
481 {
482         int numLevels = (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;
483
484         DE_ASSERT(m_texType == TEXTURETYPE_2D);
485
486         for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
487         {
488                 int                             levelW          = de::max(1, m_width >> levelNdx);
489                 int                             levelH          = de::max(1, m_height >> levelNdx);
490                 tcu::Surface    reference;
491                 tcu::Surface    result;
492
493                 if (levelW <= 2 || levelH <= 2)
494                         continue; // Don't bother checking.
495
496                 // Render with GLES2
497                 setContext(&gles2Context);
498                 renderTex2D(result, levelW, levelH);
499
500                 // Render reference.
501                 setContext(&refContext);
502                 renderTex2D(reference, levelW, levelH);
503
504                 {
505                         tcu::UVec4      threshold       = computeCompareThreshold(m_context.getRenderTarget().getPixelFormat(), m_texFormat);
506                         bool            isOk            = tcu::intThresholdCompare(m_testCtx.getLog(), "Result", "Image comparison result", reference.getAccess(), result.getAccess(), threshold,
507                                                                                                                            levelNdx == 0 ? tcu::COMPARE_LOG_RESULT : tcu::COMPARE_LOG_ON_ERROR);
508
509                         if (!isOk)
510                         {
511                                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
512                                 break;
513                         }
514                 }
515         }
516 }
517
518 void TextureSpecCase::verifyTexCube (sglr::GLContext& gles2Context, sglr::ReferenceContext& refContext)
519 {
520         int numLevels = (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;
521
522         DE_ASSERT(m_texType == TEXTURETYPE_CUBE);
523
524         for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
525         {
526                 int             levelW  = de::max(1, m_width >> levelNdx);
527                 int             levelH  = de::max(1, m_height >> levelNdx);
528                 bool    isOk    = true;
529
530                 for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
531                 {
532                         tcu::Surface    reference;
533                         tcu::Surface    result;
534
535                         if (levelW <= 2 || levelH <= 2)
536                                 continue; // Don't bother checking.
537
538                         // Render with GLES2
539                         setContext(&gles2Context);
540                         renderTexCube(result, levelW, levelH, (tcu::CubeFace)face);
541
542                         // Render reference.
543                         setContext(&refContext);
544                         renderTexCube(reference, levelW, levelH, (tcu::CubeFace)face);
545
546                         const float     threshold       = 0.02f;
547                         isOk = tcu::fuzzyCompare(m_testCtx.getLog(), "Result", (string("Image comparison result: ") + de::toString((tcu::CubeFace)face)).c_str(), reference, result, threshold,
548                                                                          levelNdx == 0 ? tcu::COMPARE_LOG_RESULT : tcu::COMPARE_LOG_ON_ERROR);
549
550                         if (!isOk)
551                         {
552                                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
553                                 break;
554                         }
555                 }
556
557                 if (!isOk)
558                         break;
559         }
560 }
561
562 void TextureSpecCase::renderTex2D (tcu::Surface& dst, int width, int height)
563 {
564         int                     targetW         = getWidth();
565         int                     targetH         = getHeight();
566
567         float           w                       = (float)width  / (float)targetW;
568         float           h                       = (float)height / (float)targetH;
569
570         deUint32        shaderID        = getCurrentContext()->createProgram(&m_tex2DShader);
571
572         m_tex2DShader.setUniforms(*getCurrentContext(), shaderID);
573         sglr::drawQuad(*getCurrentContext(), shaderID, tcu::Vec3(-1.0f, -1.0f, 0.0f), tcu::Vec3(-1.0f + w*2.0f, -1.0f + h*2.0f, 0.0f));
574
575         // Read pixels back.
576         readPixels(dst, 0, 0, width, height);
577 }
578
579 void TextureSpecCase::renderTexCube (tcu::Surface& dst, int width, int height, tcu::CubeFace face)
580 {
581         int             targetW         = getWidth();
582         int             targetH         = getHeight();
583
584         float   w                       = (float)width  / (float)targetW;
585         float   h                       = (float)height / (float)targetH;
586
587         TexCubeShader* shaders[] =
588         {
589                 &m_texCubeNegXShader,
590                 &m_texCubePosXShader,
591                 &m_texCubeNegYShader,
592                 &m_texCubePosYShader,
593                 &m_texCubeNegZShader,
594                 &m_texCubePosZShader
595         };
596
597         deUint32        shaderID        = getCurrentContext()->createProgram(shaders[face]);
598
599         shaders[face]->setUniforms(*getCurrentContext(), shaderID);
600         sglr::drawQuad(*getCurrentContext(), shaderID, tcu::Vec3(-1.0f, -1.0f, 0.0f), tcu::Vec3(-1.0f + w*2.0f, -1.0f + h*2.0f, 0.0f));
601
602         // Read pixels back.
603         readPixels(dst, 0, 0, width, height);
604 }
605
606 void TextureSpecCase::readPixels (tcu::Surface& dst, int x, int y, int width, int height)
607 {
608         dst.setSize(width, height);
609         glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, dst.getAccess().getDataPtr());
610 }
611
612 // Basic TexImage2D() with 2D texture usage
613 class BasicTexImage2DCase : public TextureSpecCase
614 {
615 public:
616         BasicTexImage2DCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 flags, int width, int height)
617                 : TextureSpecCase       (context, name, desc, TEXTURETYPE_2D, glu::mapGLTransferFormat(format, dataType), flags, width, height)
618                 , m_format                      (format)
619                 , m_dataType            (dataType)
620         {
621         }
622
623 protected:
624         void createTexture (void)
625         {
626                 tcu::TextureFormat      fmt                     = m_texFormat;
627                 int                                     numLevels       = (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;
628                 deUint32                        tex                     = 0;
629                 tcu::TextureLevel       levelData       (fmt);
630                 de::Random                      rnd                     (deStringHash(getName()));
631
632                 glGenTextures(1, &tex);
633                 glBindTexture(GL_TEXTURE_2D, tex);
634                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
635
636                 for (int ndx = 0; ndx < numLevels; ndx++)
637                 {
638                         int             levelW          = de::max(1, m_width >> ndx);
639                         int             levelH          = de::max(1, m_height >> ndx);
640                         Vec4    gMin            = randomVector<4>(rnd);
641                         Vec4    gMax            = randomVector<4>(rnd);
642
643                         levelData.setSize(levelW, levelH);
644                         tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
645
646                         glTexImage2D(GL_TEXTURE_2D, ndx, m_format, levelW, levelH, 0, m_format, m_dataType, levelData.getAccess().getDataPtr());
647                 }
648         }
649
650         deUint32        m_format;
651         deUint32        m_dataType;
652 };
653
654 // Basic TexImage2D() with cubemap usage
655 class BasicTexImageCubeCase : public TextureSpecCase
656 {
657 public:
658         BasicTexImageCubeCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 flags, int width, int height)
659                 : TextureSpecCase       (context, name, desc, TEXTURETYPE_CUBE, glu::mapGLTransferFormat(format, dataType), flags, width, height)
660                 , m_format                      (format)
661                 , m_dataType            (dataType)
662         {
663         }
664
665 protected:
666         void createTexture (void)
667         {
668                 tcu::TextureFormat      fmt                     = m_texFormat;
669                 int                                     numLevels       = (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;
670                 deUint32                        tex                     = 0;
671                 tcu::TextureLevel       levelData       (fmt);
672                 de::Random                      rnd                     (deStringHash(getName()));
673
674                 DE_ASSERT(m_width == m_height); // Non-square cubemaps are not supported by GLES2.
675
676                 glGenTextures(1, &tex);
677                 glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
678                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
679
680                 for (int ndx = 0; ndx < numLevels; ndx++)
681                 {
682                         int             levelW          = de::max(1, m_width >> ndx);
683                         int             levelH          = de::max(1, m_height >> ndx);
684
685                         levelData.setSize(levelW, levelH);
686
687                         for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
688                         {
689                                 Vec4 gMin = randomVector<4>(rnd);
690                                 Vec4 gMax = randomVector<4>(rnd);
691
692                                 tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
693
694                                 glTexImage2D(s_cubeMapFaces[face], ndx, m_format, levelW, levelH, 0, m_format, m_dataType, levelData.getAccess().getDataPtr());
695                         }
696                 }
697         }
698
699         deUint32        m_format;
700         deUint32        m_dataType;
701 };
702
703 // Randomized 2D texture specification using TexImage2D
704 class RandomOrderTexImage2DCase : public TextureSpecCase
705 {
706 public:
707         RandomOrderTexImage2DCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 flags, int width, int height)
708                 : TextureSpecCase       (context, name, desc, TEXTURETYPE_2D, glu::mapGLTransferFormat(format, dataType), flags, width, height)
709                 , m_format                      (format)
710                 , m_dataType            (dataType)
711         {
712         }
713
714 protected:
715         void createTexture (void)
716         {
717                 tcu::TextureFormat      fmt                     = m_texFormat;
718                 int                                     numLevels       = (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;
719                 deUint32                        tex                     = 0;
720                 tcu::TextureLevel       levelData       (fmt);
721                 de::Random                      rnd                     (deStringHash(getName()));
722
723                 glGenTextures(1, &tex);
724                 glBindTexture(GL_TEXTURE_2D, tex);
725                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
726
727                 vector<int>                     levels          (numLevels);
728
729                 for (int i = 0; i < numLevels; i++)
730                         levels[i] = i;
731                 rnd.shuffle(levels.begin(), levels.end());
732
733                 for (int ndx = 0; ndx < numLevels; ndx++)
734                 {
735                         int             levelNdx        = levels[ndx];
736                         int             levelW          = de::max(1, m_width    >> levelNdx);
737                         int             levelH          = de::max(1, m_height   >> levelNdx);
738                         Vec4    gMin            = randomVector<4>(rnd);
739                         Vec4    gMax            = randomVector<4>(rnd);
740
741                         levelData.setSize(levelW, levelH);
742                         tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
743
744                         glTexImage2D(GL_TEXTURE_2D, levelNdx, m_format, levelW, levelH, 0, m_format, m_dataType, levelData.getAccess().getDataPtr());
745                 }
746         }
747
748         deUint32        m_format;
749         deUint32        m_dataType;
750 };
751
752 // Randomized cubemap texture specification using TexImage2D
753 class RandomOrderTexImageCubeCase : public TextureSpecCase
754 {
755 public:
756         RandomOrderTexImageCubeCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 flags, int width, int height)
757                 : TextureSpecCase       (context, name, desc, TEXTURETYPE_CUBE, glu::mapGLTransferFormat(format, dataType), flags, width, height)
758                 , m_format                      (format)
759                 , m_dataType            (dataType)
760         {
761         }
762
763 protected:
764         void createTexture (void)
765         {
766                 tcu::TextureFormat      fmt                     = m_texFormat;
767                 int                                     numLevels       = (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;
768                 deUint32                        tex                     = 0;
769                 tcu::TextureLevel       levelData       (fmt);
770                 de::Random                      rnd                     (deStringHash(getName()));
771
772                 DE_ASSERT(m_width == m_height); // Non-square cubemaps are not supported by GLES2.
773
774                 glGenTextures(1, &tex);
775                 glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
776                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
777
778                 // Level-face pairs.
779                 vector<pair<int, tcu::CubeFace> >       images  (numLevels*6);
780
781                 for (int ndx = 0; ndx < numLevels; ndx++)
782                         for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
783                                 images[ndx*6 + face] = std::make_pair(ndx, (tcu::CubeFace)face);
784
785                 rnd.shuffle(images.begin(), images.end());
786
787                 for (int ndx = 0; ndx < (int)images.size(); ndx++)
788                 {
789                         int                             levelNdx        = images[ndx].first;
790                         tcu::CubeFace   face            = images[ndx].second;
791                         int                             levelW          = de::max(1, m_width >> levelNdx);
792                         int                             levelH          = de::max(1, m_height >> levelNdx);
793                         Vec4                    gMin            = randomVector<4>(rnd);
794                         Vec4                    gMax            = randomVector<4>(rnd);
795
796                         levelData.setSize(levelW, levelH);
797                         tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
798
799                         glTexImage2D(s_cubeMapFaces[face], levelNdx, m_format, levelW, levelH, 0, m_format, m_dataType, levelData.getAccess().getDataPtr());
800                 }
801         }
802
803         deUint32        m_format;
804         deUint32        m_dataType;
805 };
806
807 static inline int getRowPitch (const tcu::TextureFormat& transferFmt, int rowLen, int alignment)
808 {
809         int basePitch = transferFmt.getPixelSize()*rowLen;
810         return alignment*(basePitch/alignment + ((basePitch % alignment) ? 1 : 0));
811 }
812
813 // TexImage2D() unpack alignment case.
814 class TexImage2DAlignCase : public TextureSpecCase
815 {
816 public:
817         TexImage2DAlignCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 flags, int width, int height, int alignment)
818                 : TextureSpecCase       (context, name, desc, TEXTURETYPE_2D, glu::mapGLTransferFormat(format, dataType), flags, width, height)
819                 , m_format                      (format)
820                 , m_dataType            (dataType)
821                 , m_alignment           (alignment)
822         {
823         }
824
825 protected:
826         void createTexture (void)
827         {
828                 tcu::TextureFormat      fmt                     = m_texFormat;
829                 int                                     numLevels       = (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;
830                 deUint32                        tex                     = 0;
831                 vector<deUint8>         data;
832
833                 glGenTextures(1, &tex);
834                 glBindTexture(GL_TEXTURE_2D, tex);
835                 glPixelStorei(GL_UNPACK_ALIGNMENT, m_alignment);
836
837                 for (int ndx = 0; ndx < numLevels; ndx++)
838                 {
839                         int             levelW          = de::max(1, m_width >> ndx);
840                         int             levelH          = de::max(1, m_height >> ndx);
841                         Vec4    colorA          (1.0f, 0.0f, 0.0f, 1.0f);
842                         Vec4    colorB          (0.0f, 1.0f, 0.0f, 1.0f);
843                         int             rowPitch        = getRowPitch(fmt, levelW, m_alignment);
844                         int             cellSize        = de::max(1, de::min(levelW >> 2, levelH >> 2));
845
846                         data.resize(rowPitch*levelH);
847                         tcu::fillWithGrid(tcu::PixelBufferAccess(fmt, levelW, levelH, 1, rowPitch, 0, &data[0]), cellSize, colorA, colorB);
848
849                         glTexImage2D(GL_TEXTURE_2D, ndx, m_format, levelW, levelH, 0, m_format, m_dataType, &data[0]);
850                 }
851         }
852
853         deUint32        m_format;
854         deUint32        m_dataType;
855         int                     m_alignment;
856 };
857
858 // TexImage2D() unpack alignment case.
859 class TexImageCubeAlignCase : public TextureSpecCase
860 {
861 public:
862         TexImageCubeAlignCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 flags, int width, int height, int alignment)
863                 : TextureSpecCase       (context, name, desc, TEXTURETYPE_CUBE, glu::mapGLTransferFormat(format, dataType), flags, width, height)
864                 , m_format                      (format)
865                 , m_dataType            (dataType)
866                 , m_alignment           (alignment)
867         {
868         }
869
870 protected:
871         void createTexture (void)
872         {
873                 tcu::TextureFormat      fmt                     = m_texFormat;
874                 int                                     numLevels       = (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;
875                 deUint32                        tex                     = 0;
876                 vector<deUint8>         data;
877
878                 DE_ASSERT(m_width == m_height); // Non-square cubemaps are not supported by GLES2.
879
880                 glGenTextures(1, &tex);
881                 glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
882                 glPixelStorei(GL_UNPACK_ALIGNMENT, m_alignment);
883
884                 for (int ndx = 0; ndx < numLevels; ndx++)
885                 {
886                         int             levelW          = de::max(1, m_width >> ndx);
887                         int             levelH          = de::max(1, m_height >> ndx);
888                         int             rowPitch        = getRowPitch(fmt, levelW, m_alignment);
889                         Vec4    colorA          (1.0f, 0.0f, 0.0f, 1.0f);
890                         Vec4    colorB          (0.0f, 1.0f, 0.0f, 1.0f);
891                         int             cellSize        = de::max(1, de::min(levelW >> 2, levelH >> 2));
892
893                         data.resize(rowPitch*levelH);
894                         tcu::fillWithGrid(tcu::PixelBufferAccess(fmt, levelW, levelH, 1, rowPitch, 0, &data[0]), cellSize, colorA, colorB);
895
896                         for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
897                                 glTexImage2D(s_cubeMapFaces[face], ndx, m_format, levelW, levelH, 0, m_format, m_dataType, &data[0]);
898                 }
899         }
900
901         deUint32        m_format;
902         deUint32        m_dataType;
903         int                     m_alignment;
904 };
905
906 // Basic TexSubImage2D() with 2D texture usage
907 class BasicTexSubImage2DCase : public TextureSpecCase
908 {
909 public:
910         BasicTexSubImage2DCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 flags, int width, int height)
911                 : TextureSpecCase       (context, name, desc, TEXTURETYPE_2D, glu::mapGLTransferFormat(format, dataType), flags, width, height)
912                 , m_format                      (format)
913                 , m_dataType            (dataType)
914         {
915         }
916
917 protected:
918         void createTexture (void)
919         {
920                 tcu::TextureFormat      fmt                     = m_texFormat;
921                 int                                     numLevels       = (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;
922                 deUint32                        tex                     = 0;
923                 tcu::TextureLevel       data            (fmt);
924                 de::Random                      rnd                     (deStringHash(getName()));
925
926                 glGenTextures(1, &tex);
927                 glBindTexture(GL_TEXTURE_2D, tex);
928                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
929
930                 // First specify full texture.
931                 for (int ndx = 0; ndx < numLevels; ndx++)
932                 {
933                         int             levelW          = de::max(1, m_width >> ndx);
934                         int             levelH          = de::max(1, m_height >> ndx);
935                         Vec4    gMin            = randomVector<4>(rnd);
936                         Vec4    gMax            = randomVector<4>(rnd);
937
938                         data.setSize(levelW, levelH);
939                         tcu::fillWithComponentGradients(data.getAccess(), gMin, gMax);
940
941                         glTexImage2D(GL_TEXTURE_2D, ndx, m_format, levelW, levelH, 0, m_format, m_dataType, data.getAccess().getDataPtr());
942                 }
943
944                 // Re-specify parts of each level.
945                 for (int ndx = 0; ndx < numLevels; ndx++)
946                 {
947                         int             levelW          = de::max(1, m_width >> ndx);
948                         int             levelH          = de::max(1, m_height >> ndx);
949
950                         int             w                       = rnd.getInt(1, levelW);
951                         int             h                       = rnd.getInt(1, levelH);
952                         int             x                       = rnd.getInt(0, levelW-w);
953                         int             y                       = rnd.getInt(0, levelH-h);
954
955                         Vec4    colorA          = randomVector<4>(rnd);
956                         Vec4    colorB          = randomVector<4>(rnd);
957                         int             cellSize        = rnd.getInt(2, 16);
958
959                         data.setSize(w, h);
960                         tcu::fillWithGrid(data.getAccess(), cellSize, colorA, colorB);
961
962                         glTexSubImage2D(GL_TEXTURE_2D, ndx, x, y, w, h, m_format, m_dataType, data.getAccess().getDataPtr());
963                 }
964         }
965
966         deUint32        m_format;
967         deUint32        m_dataType;
968 };
969
970 // Basic TexSubImage2D() with cubemap usage
971 class BasicTexSubImageCubeCase : public TextureSpecCase
972 {
973 public:
974         BasicTexSubImageCubeCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 flags, int width, int height)
975                 : TextureSpecCase       (context, name, desc, TEXTURETYPE_CUBE, glu::mapGLTransferFormat(format, dataType), flags, width, height)
976                 , m_format                      (format)
977                 , m_dataType            (dataType)
978         {
979         }
980
981 protected:
982         void createTexture (void)
983         {
984                 tcu::TextureFormat      fmt                     = m_texFormat;
985                 int                                     numLevels       = (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;
986                 deUint32                        tex                     = 0;
987                 tcu::TextureLevel       data            (fmt);
988                 de::Random                      rnd                     (deStringHash(getName()));
989
990                 DE_ASSERT(m_width == m_height); // Non-square cubemaps are not supported by GLES2.
991
992                 glGenTextures(1, &tex);
993                 glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
994                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
995
996                 for (int ndx = 0; ndx < numLevels; ndx++)
997                 {
998                         int             levelW          = de::max(1, m_width >> ndx);
999                         int             levelH          = de::max(1, m_height >> ndx);
1000
1001                         data.setSize(levelW, levelH);
1002
1003                         for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
1004                         {
1005                                 Vec4 gMin = randomVector<4>(rnd);
1006                                 Vec4 gMax = randomVector<4>(rnd);
1007
1008                                 tcu::fillWithComponentGradients(data.getAccess(), gMin, gMax);
1009
1010                                 glTexImage2D(s_cubeMapFaces[face], ndx, m_format, levelW, levelH, 0, m_format, m_dataType, data.getAccess().getDataPtr());
1011                         }
1012                 }
1013
1014                 // Re-specify parts of each face and level.
1015                 for (int ndx = 0; ndx < numLevels; ndx++)
1016                 {
1017                         int             levelW          = de::max(1, m_width >> ndx);
1018                         int             levelH          = de::max(1, m_height >> ndx);
1019
1020                         for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
1021                         {
1022                                 int             w                       = rnd.getInt(1, levelW);
1023                                 int             h                       = rnd.getInt(1, levelH);
1024                                 int             x                       = rnd.getInt(0, levelW-w);
1025                                 int             y                       = rnd.getInt(0, levelH-h);
1026
1027                                 Vec4    colorA          = randomVector<4>(rnd);
1028                                 Vec4    colorB          = randomVector<4>(rnd);
1029                                 int             cellSize        = rnd.getInt(2, 16);
1030
1031                                 data.setSize(w, h);
1032                                 tcu::fillWithGrid(data.getAccess(), cellSize, colorA, colorB);
1033
1034                                 glTexSubImage2D(s_cubeMapFaces[face], ndx, x, y, w, h, m_format, m_dataType, data.getAccess().getDataPtr());
1035                         }
1036                 }
1037         }
1038
1039         deUint32        m_format;
1040         deUint32        m_dataType;
1041 };
1042
1043 // TexSubImage2D() to texture initialized with empty data
1044 class TexSubImage2DEmptyTexCase : public TextureSpecCase
1045 {
1046 public:
1047         TexSubImage2DEmptyTexCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 flags, int width, int height)
1048                 : TextureSpecCase       (context, name, desc, TEXTURETYPE_2D, glu::mapGLTransferFormat(format, dataType), flags, width, height)
1049                 , m_format                      (format)
1050                 , m_dataType            (dataType)
1051         {
1052         }
1053
1054 protected:
1055         void createTexture (void)
1056         {
1057                 tcu::TextureFormat      fmt                     = m_texFormat;
1058                 int                                     numLevels       = (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;
1059                 deUint32                        tex                     = 0;
1060                 tcu::TextureLevel       data            (fmt);
1061                 de::Random                      rnd                     (deStringHash(getName()));
1062
1063                 glGenTextures(1, &tex);
1064                 glBindTexture(GL_TEXTURE_2D, tex);
1065                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1066
1067                 // First allocate storage for each level.
1068                 for (int ndx = 0; ndx < numLevels; ndx++)
1069                 {
1070                         int             levelW          = de::max(1, m_width >> ndx);
1071                         int             levelH          = de::max(1, m_height >> ndx);
1072
1073                         glTexImage2D(GL_TEXTURE_2D, ndx, m_format, levelW, levelH, 0, m_format, m_dataType, DE_NULL);
1074                 }
1075
1076                 // Specify pixel data to all levels using glTexSubImage2D()
1077                 for (int ndx = 0; ndx < numLevels; ndx++)
1078                 {
1079                         int             levelW          = de::max(1, m_width >> ndx);
1080                         int             levelH          = de::max(1, m_height >> ndx);
1081                         Vec4    gMin            = randomVector<4>(rnd);
1082                         Vec4    gMax            = randomVector<4>(rnd);
1083
1084                         data.setSize(levelW, levelH);
1085                         tcu::fillWithComponentGradients(data.getAccess(), gMin, gMax);
1086
1087                         glTexSubImage2D(GL_TEXTURE_2D, ndx, 0, 0, levelW, levelH, m_format, m_dataType, data.getAccess().getDataPtr());
1088                 }
1089         }
1090
1091         deUint32        m_format;
1092         deUint32        m_dataType;
1093 };
1094
1095 // TexSubImage2D() to empty cubemap texture
1096 class TexSubImageCubeEmptyTexCase : public TextureSpecCase
1097 {
1098 public:
1099         TexSubImageCubeEmptyTexCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 flags, int width, int height)
1100                 : TextureSpecCase       (context, name, desc, TEXTURETYPE_CUBE, glu::mapGLTransferFormat(format, dataType), flags, width, height)
1101                 , m_format                      (format)
1102                 , m_dataType            (dataType)
1103         {
1104         }
1105
1106 protected:
1107         void createTexture (void)
1108         {
1109                 tcu::TextureFormat      fmt                     = m_texFormat;
1110                 int                                     numLevels       = (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;
1111                 deUint32                        tex                     = 0;
1112                 tcu::TextureLevel       data            (fmt);
1113                 de::Random                      rnd                     (deStringHash(getName()));
1114
1115                 DE_ASSERT(m_width == m_height); // Non-square cubemaps are not supported by GLES2.
1116
1117                 glGenTextures(1, &tex);
1118                 glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
1119                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1120
1121                 // Specify storage for each level.
1122                 for (int ndx = 0; ndx < numLevels; ndx++)
1123                 {
1124                         int             levelW          = de::max(1, m_width >> ndx);
1125                         int             levelH          = de::max(1, m_height >> ndx);
1126
1127                         for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
1128                                 glTexImage2D(s_cubeMapFaces[face], ndx, m_format, levelW, levelH, 0, m_format, m_dataType, DE_NULL);
1129                 }
1130
1131                 // Specify data using glTexSubImage2D()
1132                 for (int ndx = 0; ndx < numLevels; ndx++)
1133                 {
1134                         int             levelW          = de::max(1, m_width >> ndx);
1135                         int             levelH          = de::max(1, m_height >> ndx);
1136
1137                         data.setSize(levelW, levelH);
1138
1139                         for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
1140                         {
1141                                 Vec4 gMin = randomVector<4>(rnd);
1142                                 Vec4 gMax = randomVector<4>(rnd);
1143
1144                                 tcu::fillWithComponentGradients(data.getAccess(), gMin, gMax);
1145
1146                                 glTexSubImage2D(s_cubeMapFaces[face], ndx, 0, 0, levelW, levelH, m_format, m_dataType, data.getAccess().getDataPtr());
1147                         }
1148                 }
1149         }
1150
1151         deUint32        m_format;
1152         deUint32        m_dataType;
1153 };
1154
1155 // TexSubImage2D() unpack alignment with 2D texture
1156 class TexSubImage2DAlignCase : public TextureSpecCase
1157 {
1158 public:
1159         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)
1160                 : TextureSpecCase       (context, name, desc, TEXTURETYPE_2D, glu::mapGLTransferFormat(format, dataType), 0 /* Mipmaps are never used */, width, height)
1161                 , m_format                      (format)
1162                 , m_dataType            (dataType)
1163                 , m_subX                        (subX)
1164                 , m_subY                        (subY)
1165                 , m_subW                        (subW)
1166                 , m_subH                        (subH)
1167                 , m_alignment           (alignment)
1168         {
1169         }
1170
1171 protected:
1172         void createTexture (void)
1173         {
1174                 tcu::TextureFormat      fmt                     = m_texFormat;
1175                 deUint32                        tex                     = 0;
1176                 vector<deUint8>         data;
1177
1178                 glGenTextures(1, &tex);
1179                 glBindTexture(GL_TEXTURE_2D, tex);
1180
1181                 // Specify base level.
1182                 data.resize(fmt.getPixelSize()*m_width*m_height);
1183                 tcu::fillWithComponentGradients(tcu::PixelBufferAccess(fmt, m_width, m_height, 1, &data[0]), Vec4(0.0f), Vec4(1.0f));
1184
1185                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1186                 glTexImage2D(GL_TEXTURE_2D, 0, m_format, m_width, m_height, 0, m_format, m_dataType, &data[0]);
1187
1188                 // Re-specify subrectangle.
1189                 int rowPitch = getRowPitch(fmt, m_subW, m_alignment);
1190                 data.resize(rowPitch*m_subH);
1191                 tcu::fillWithGrid(tcu::PixelBufferAccess(fmt, 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));
1192
1193                 glPixelStorei(GL_UNPACK_ALIGNMENT, m_alignment);
1194                 glTexSubImage2D(GL_TEXTURE_2D, 0, m_subX, m_subY, m_subW, m_subH, m_format, m_dataType, &data[0]);
1195         }
1196
1197         deUint32        m_format;
1198         deUint32        m_dataType;
1199         int                     m_subX;
1200         int                     m_subY;
1201         int                     m_subW;
1202         int                     m_subH;
1203         int                     m_alignment;
1204 };
1205
1206 // TexSubImage2D() unpack alignment with cubemap texture
1207 class TexSubImageCubeAlignCase : public TextureSpecCase
1208 {
1209 public:
1210         TexSubImageCubeAlignCase (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)
1211                 : TextureSpecCase       (context, name, desc, TEXTURETYPE_CUBE, glu::mapGLTransferFormat(format, dataType), 0 /* Mipmaps are never used */, width, height)
1212                 , m_format                      (format)
1213                 , m_dataType            (dataType)
1214                 , m_subX                        (subX)
1215                 , m_subY                        (subY)
1216                 , m_subW                        (subW)
1217                 , m_subH                        (subH)
1218                 , m_alignment           (alignment)
1219         {
1220         }
1221
1222 protected:
1223         void createTexture (void)
1224         {
1225                 tcu::TextureFormat      fmt                     = m_texFormat;
1226                 deUint32                        tex                     = 0;
1227                 vector<deUint8>         data;
1228
1229                 DE_ASSERT(m_width == m_height);
1230
1231                 glGenTextures(1, &tex);
1232                 glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
1233
1234                 // Specify base level.
1235                 data.resize(fmt.getPixelSize()*m_width*m_height);
1236                 tcu::fillWithComponentGradients(tcu::PixelBufferAccess(fmt, m_width, m_height, 1, &data[0]), Vec4(0.0f), Vec4(1.0f));
1237
1238                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1239                 for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
1240                         glTexImage2D(s_cubeMapFaces[face], 0, m_format, m_width, m_height, 0, m_format, m_dataType, &data[0]);
1241
1242                 // Re-specify subrectangle.
1243                 int rowPitch = getRowPitch(fmt, m_subW, m_alignment);
1244                 data.resize(rowPitch*m_subH);
1245                 tcu::fillWithGrid(tcu::PixelBufferAccess(fmt, 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));
1246
1247                 glPixelStorei(GL_UNPACK_ALIGNMENT, m_alignment);
1248                 for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
1249                         glTexSubImage2D(s_cubeMapFaces[face], 0, m_subX, m_subY, m_subW, m_subH, m_format, m_dataType, &data[0]);
1250         }
1251
1252         deUint32        m_format;
1253         deUint32        m_dataType;
1254         int                     m_subX;
1255         int                     m_subY;
1256         int                     m_subW;
1257         int                     m_subH;
1258         int                     m_alignment;
1259 };
1260
1261
1262
1263 // Basic CopyTexImage2D() with 2D texture usage
1264 class BasicCopyTexImage2DCase : public TextureSpecCase
1265 {
1266 public:
1267         BasicCopyTexImage2DCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, deUint32 flags, int width, int height)
1268                 : TextureSpecCase       (context, name, desc, TEXTURETYPE_2D, mapGLUnsizedInternalFormat(internalFormat), flags, width, height)
1269                 , m_internalFormat      (internalFormat)
1270         {
1271         }
1272
1273 protected:
1274         void createTexture (void)
1275         {
1276                 const tcu::RenderTarget&        renderTarget    = TestCase::m_context.getRenderContext().getRenderTarget();
1277                 bool                                            targetHasRGB    = renderTarget.getPixelFormat().redBits > 0 && renderTarget.getPixelFormat().greenBits > 0 && renderTarget.getPixelFormat().blueBits > 0;
1278                 bool                                            targetHasAlpha  = renderTarget.getPixelFormat().alphaBits > 0;
1279                 tcu::TextureFormat                      fmt                             = m_texFormat;
1280                 bool                                            texHasRGB               = fmt.order != tcu::TextureFormat::A;
1281                 bool                                            texHasAlpha             = fmt.order == tcu::TextureFormat::RGBA || fmt.order == tcu::TextureFormat::LA || fmt.order == tcu::TextureFormat::A;
1282                 int                                                     numLevels               = (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;
1283                 deUint32                                        tex                             = 0;
1284                 de::Random                                      rnd                             (deStringHash(getName()));
1285                 GradientShader                          shader;
1286                 deUint32                                        shaderID                = getCurrentContext()->createProgram(&shader);
1287
1288                 if ((texHasRGB && !targetHasRGB) || (texHasAlpha && !targetHasAlpha))
1289                         throw tcu::NotSupportedError("Copying from current framebuffer is not supported", "", __FILE__, __LINE__);
1290
1291                 // Fill render target with gradient.
1292                 sglr::drawQuad(*getCurrentContext(), shaderID, tcu::Vec3(-1.0f, -1.0f, 0.0f), tcu::Vec3(1.0f, 1.0f, 0.0f));
1293
1294                 glGenTextures(1, &tex);
1295                 glBindTexture(GL_TEXTURE_2D, tex);
1296
1297                 for (int ndx = 0; ndx < numLevels; ndx++)
1298                 {
1299                         int             levelW          = de::max(1, m_width >> ndx);
1300                         int             levelH          = de::max(1, m_height >> ndx);
1301                         int             x                       = rnd.getInt(0, getWidth()      - levelW);
1302                         int             y                       = rnd.getInt(0, getHeight()     - levelH);
1303
1304                         glCopyTexImage2D(GL_TEXTURE_2D, ndx, m_internalFormat, x, y, levelW, levelH, 0);
1305                 }
1306         }
1307
1308         deUint32 m_internalFormat;
1309 };
1310
1311 // Basic CopyTexImage2D() with cubemap usage
1312 class BasicCopyTexImageCubeCase : public TextureSpecCase
1313 {
1314 public:
1315         BasicCopyTexImageCubeCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, deUint32 flags, int width, int height)
1316                 : TextureSpecCase       (context, name, desc, TEXTURETYPE_CUBE, mapGLUnsizedInternalFormat(internalFormat), flags, width, height)
1317                 , m_internalFormat      (internalFormat)
1318         {
1319         }
1320
1321 protected:
1322         void createTexture (void)
1323         {
1324                 const tcu::RenderTarget&        renderTarget    = TestCase::m_context.getRenderContext().getRenderTarget();
1325                 bool                                            targetHasRGB    = renderTarget.getPixelFormat().redBits > 0 && renderTarget.getPixelFormat().greenBits > 0 && renderTarget.getPixelFormat().blueBits > 0;
1326                 bool                                            targetHasAlpha  = renderTarget.getPixelFormat().alphaBits > 0;
1327                 tcu::TextureFormat                      fmt                             = m_texFormat;
1328                 bool                                            texHasRGB               = fmt.order != tcu::TextureFormat::A;
1329                 bool                                            texHasAlpha             = fmt.order == tcu::TextureFormat::RGBA || fmt.order == tcu::TextureFormat::LA || fmt.order == tcu::TextureFormat::A;
1330                 int                                                     numLevels               = (m_flags & MIPMAPS) ? deLog2Floor32(m_width)+1 : 1;
1331                 deUint32                                        tex                             = 0;
1332                 de::Random                                      rnd                             (deStringHash(getName()));
1333                 GradientShader                          shader;
1334                 deUint32                                        shaderID                = getCurrentContext()->createProgram(&shader);
1335
1336                 DE_ASSERT(m_width == m_height); // Non-square cubemaps are not supported by GLES2.
1337
1338                 if ((texHasRGB && !targetHasRGB) || (texHasAlpha && !targetHasAlpha))
1339                         throw tcu::NotSupportedError("Copying from current framebuffer is not supported", "", __FILE__, __LINE__);
1340
1341                 // Fill render target with gradient.
1342                 sglr::drawQuad(*getCurrentContext(), shaderID, tcu::Vec3(-1.0f, -1.0f, 0.0f), tcu::Vec3(1.0f, 1.0f, 0.0f));
1343
1344                 glGenTextures(1, &tex);
1345                 glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
1346
1347                 for (int ndx = 0; ndx < numLevels; ndx++)
1348                 {
1349                         int levelW = de::max(1, m_width >> ndx);
1350                         int levelH = de::max(1, m_height >> ndx);
1351
1352                         for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
1353                         {
1354                                 int x = rnd.getInt(0, getWidth()        - levelW);
1355                                 int y = rnd.getInt(0, getHeight()       - levelH);
1356
1357                                 glCopyTexImage2D(s_cubeMapFaces[face], ndx, m_internalFormat, x, y, levelW, levelH, 0);
1358                         }
1359                 }
1360         }
1361
1362         deUint32 m_internalFormat;
1363 };
1364
1365
1366
1367 // Basic CopyTexSubImage2D() with 2D texture usage
1368 class BasicCopyTexSubImage2DCase : public TextureSpecCase
1369 {
1370 public:
1371         BasicCopyTexSubImage2DCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 flags, int width, int height)
1372                 : TextureSpecCase       (context, name, desc, TEXTURETYPE_2D, glu::mapGLTransferFormat(format, dataType), flags, width, height)
1373                 , m_format                      (format)
1374                 , m_dataType            (dataType)
1375         {
1376         }
1377
1378 protected:
1379         void createTexture (void)
1380         {
1381                 const tcu::RenderTarget&        renderTarget    = TestCase::m_context.getRenderContext().getRenderTarget();
1382                 bool                                            targetHasRGB    = renderTarget.getPixelFormat().redBits > 0 && renderTarget.getPixelFormat().greenBits > 0 && renderTarget.getPixelFormat().blueBits > 0;
1383                 bool                                            targetHasAlpha  = renderTarget.getPixelFormat().alphaBits > 0;
1384                 tcu::TextureFormat                      fmt                             = m_texFormat;
1385                 bool                                            texHasRGB               = fmt.order != tcu::TextureFormat::A;
1386                 bool                                            texHasAlpha             = fmt.order == tcu::TextureFormat::RGBA || fmt.order == tcu::TextureFormat::LA || fmt.order == tcu::TextureFormat::A;
1387                 int                                                     numLevels               = (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;
1388                 deUint32                                        tex                             = 0;
1389                 tcu::TextureLevel                       data                    (fmt);
1390                 de::Random                                      rnd                             (deStringHash(getName()));
1391                 GradientShader                          shader;
1392                 deUint32                                        shaderID                = getCurrentContext()->createProgram(&shader);
1393
1394                 if ((texHasRGB && !targetHasRGB) || (texHasAlpha && !targetHasAlpha))
1395                         throw tcu::NotSupportedError("Copying from current framebuffer is not supported", "", __FILE__, __LINE__);
1396
1397                 glGenTextures(1, &tex);
1398                 glBindTexture(GL_TEXTURE_2D, tex);
1399                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1400
1401                 // First specify full texture.
1402                 for (int ndx = 0; ndx < numLevels; ndx++)
1403                 {
1404                         int             levelW          = de::max(1, m_width >> ndx);
1405                         int             levelH          = de::max(1, m_height >> ndx);
1406
1407                         Vec4    colorA          = randomVector<4>(rnd);
1408                         Vec4    colorB          = randomVector<4>(rnd);
1409                         int             cellSize        = rnd.getInt(2, 16);
1410
1411                         data.setSize(levelW, levelH);
1412                         tcu::fillWithGrid(data.getAccess(), cellSize, colorA, colorB);
1413
1414                         glTexImage2D(GL_TEXTURE_2D, ndx, m_format, levelW, levelH, 0, m_format, m_dataType, data.getAccess().getDataPtr());
1415                 }
1416
1417                 // Fill render target with gradient.
1418                 sglr::drawQuad(*getCurrentContext(), shaderID, tcu::Vec3(-1.0f, -1.0f, 0.0f), tcu::Vec3(1.0f, 1.0f, 0.0f));
1419
1420                 // Re-specify parts of each level.
1421                 for (int ndx = 0; ndx < numLevels; ndx++)
1422                 {
1423                         int             levelW          = de::max(1, m_width >> ndx);
1424                         int             levelH          = de::max(1, m_height >> ndx);
1425
1426                         int             w                       = rnd.getInt(1, levelW);
1427                         int             h                       = rnd.getInt(1, levelH);
1428                         int             xo                      = rnd.getInt(0, levelW-w);
1429                         int             yo                      = rnd.getInt(0, levelH-h);
1430
1431                         int             x                       = rnd.getInt(0, getWidth() - w);
1432                         int             y                       = rnd.getInt(0, getHeight() - h);
1433
1434                         glCopyTexSubImage2D(GL_TEXTURE_2D, ndx, xo, yo, x, y, w, h);
1435                 }
1436         }
1437
1438         deUint32        m_format;
1439         deUint32        m_dataType;
1440 };
1441
1442 // Basic CopyTexSubImage2D() with cubemap usage
1443 class BasicCopyTexSubImageCubeCase : public TextureSpecCase
1444 {
1445 public:
1446         BasicCopyTexSubImageCubeCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 flags, int width, int height)
1447                 : TextureSpecCase       (context, name, desc, TEXTURETYPE_CUBE, glu::mapGLTransferFormat(format, dataType), flags, width, height)
1448                 , m_format                      (format)
1449                 , m_dataType            (dataType)
1450         {
1451         }
1452
1453 protected:
1454         void createTexture (void)
1455         {
1456                 const tcu::RenderTarget&        renderTarget    = TestCase::m_context.getRenderContext().getRenderTarget();
1457                 bool                                            targetHasRGB    = renderTarget.getPixelFormat().redBits > 0 && renderTarget.getPixelFormat().greenBits > 0 && renderTarget.getPixelFormat().blueBits > 0;
1458                 bool                                            targetHasAlpha  = renderTarget.getPixelFormat().alphaBits > 0;
1459                 tcu::TextureFormat                      fmt                             = m_texFormat;
1460                 bool                                            texHasRGB               = fmt.order != tcu::TextureFormat::A;
1461                 bool                                            texHasAlpha             = fmt.order == tcu::TextureFormat::RGBA || fmt.order == tcu::TextureFormat::LA || fmt.order == tcu::TextureFormat::A;
1462                 int                                                     numLevels               = (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;
1463                 deUint32                                        tex                             = 0;
1464                 tcu::TextureLevel                       data                    (fmt);
1465                 de::Random                                      rnd                             (deStringHash(getName()));
1466                 GradientShader                          shader;
1467                 deUint32                                        shaderID                = getCurrentContext()->createProgram(&shader);
1468
1469                 DE_ASSERT(m_width == m_height); // Non-square cubemaps are not supported by GLES2.
1470
1471                 if ((texHasRGB && !targetHasRGB) || (texHasAlpha && !targetHasAlpha))
1472                         throw tcu::NotSupportedError("Copying from current framebuffer is not supported", "", __FILE__, __LINE__);
1473
1474                 glGenTextures(1, &tex);
1475                 glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
1476                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1477
1478                 for (int ndx = 0; ndx < numLevels; ndx++)
1479                 {
1480                         int             levelW          = de::max(1, m_width >> ndx);
1481                         int             levelH          = de::max(1, m_height >> ndx);
1482
1483                         data.setSize(levelW, levelH);
1484
1485                         for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
1486                         {
1487                                 Vec4    colorA          = randomVector<4>(rnd);
1488                                 Vec4    colorB          = randomVector<4>(rnd);
1489                                 int             cellSize        = rnd.getInt(2, 16);
1490
1491                                 tcu::fillWithGrid(data.getAccess(), cellSize, colorA, colorB);
1492                                 glTexImage2D(s_cubeMapFaces[face], ndx, m_format, levelW, levelH, 0, m_format, m_dataType, data.getAccess().getDataPtr());
1493                         }
1494                 }
1495
1496                 // Fill render target with gradient.
1497                 sglr::drawQuad(*getCurrentContext(), shaderID, tcu::Vec3(-1.0f, -1.0f, 0.0f), tcu::Vec3(1.0f, 1.0f, 0.0f));
1498
1499                 // Re-specify parts of each face and level.
1500                 for (int ndx = 0; ndx < numLevels; ndx++)
1501                 {
1502                         int             levelW          = de::max(1, m_width >> ndx);
1503                         int             levelH          = de::max(1, m_height >> ndx);
1504
1505                         for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
1506                         {
1507                                 int             w                       = rnd.getInt(1, levelW);
1508                                 int             h                       = rnd.getInt(1, levelH);
1509                                 int             xo                      = rnd.getInt(0, levelW-w);
1510                                 int             yo                      = rnd.getInt(0, levelH-h);
1511
1512                                 int             x                       = rnd.getInt(0, getWidth() - w);
1513                                 int             y                       = rnd.getInt(0, getHeight() - h);
1514
1515                                 glCopyTexSubImage2D(s_cubeMapFaces[face], ndx, xo, yo, x, y, w, h);
1516                         }
1517                 }
1518         }
1519
1520         deUint32        m_format;
1521         deUint32        m_dataType;
1522 };
1523
1524 TextureSpecificationTests::TextureSpecificationTests (Context& context)
1525         : TestCaseGroup(context, "specification", "Texture Specification Tests")
1526 {
1527 }
1528
1529 TextureSpecificationTests::~TextureSpecificationTests (void)
1530 {
1531 }
1532
1533 void TextureSpecificationTests::init (void)
1534 {
1535         struct
1536         {
1537                 const char*     name;
1538                 deUint32        format;
1539                 deUint32        dataType;
1540         } texFormats[] =
1541         {
1542                 { "a8",                 GL_ALPHA,                       GL_UNSIGNED_BYTE },
1543                 { "l8",                 GL_LUMINANCE,           GL_UNSIGNED_BYTE },
1544                 { "la88",               GL_LUMINANCE_ALPHA,     GL_UNSIGNED_BYTE },
1545                 { "rgb565",             GL_RGB,                         GL_UNSIGNED_SHORT_5_6_5 },
1546                 { "rgb888",             GL_RGB,                         GL_UNSIGNED_BYTE },
1547                 { "rgba4444",   GL_RGBA,                        GL_UNSIGNED_SHORT_4_4_4_4 },
1548                 { "rgba5551",   GL_RGBA,                        GL_UNSIGNED_SHORT_5_5_5_1 },
1549                 { "rgba8888",   GL_RGBA,                        GL_UNSIGNED_BYTE }
1550         };
1551
1552         // Basic TexImage2D usage.
1553         {
1554                 tcu::TestCaseGroup* basicTexImageGroup = new tcu::TestCaseGroup(m_testCtx, "basic_teximage2d", "Basic glTexImage2D() usage");
1555                 addChild(basicTexImageGroup);
1556                 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(texFormats); formatNdx++)
1557                 {
1558                         const char*     fmtName         = texFormats[formatNdx].name;
1559                         deUint32        format          = texFormats[formatNdx].format;
1560                         deUint32        dataType        = texFormats[formatNdx].dataType;
1561                         const int       tex2DWidth      = 64;
1562                         const int       tex2DHeight     = 128;
1563                         const int       texCubeSize     = 64;
1564
1565                         basicTexImageGroup->addChild(new BasicTexImage2DCase    (m_context,     (string(fmtName) + "_2d").c_str(),              "",     format, dataType, MIPMAPS, tex2DWidth, tex2DHeight));
1566                         basicTexImageGroup->addChild(new BasicTexImageCubeCase  (m_context,     (string(fmtName) + "_cube").c_str(),    "",     format, dataType, MIPMAPS, texCubeSize, texCubeSize));
1567                 }
1568         }
1569
1570         // Randomized TexImage2D order.
1571         {
1572                 tcu::TestCaseGroup* randomTexImageGroup = new tcu::TestCaseGroup(m_testCtx, "random_teximage2d", "Randomized glTexImage2D() usage");
1573                 addChild(randomTexImageGroup);
1574
1575                 de::Random rnd(9);
1576
1577                 // 2D cases.
1578                 for (int ndx = 0; ndx < 10; ndx++)
1579                 {
1580                         int             formatNdx       = rnd.getInt(0, DE_LENGTH_OF_ARRAY(texFormats)-1);
1581                         int             width           = 1 << rnd.getInt(2, 8);
1582                         int             height          = 1 << rnd.getInt(2, 8);
1583
1584                         randomTexImageGroup->addChild(new RandomOrderTexImage2DCase(m_context, (string("2d_") + de::toString(ndx)).c_str(), "", texFormats[formatNdx].format, texFormats[formatNdx].dataType, MIPMAPS, width, height));
1585                 }
1586
1587                 // Cubemap cases.
1588                 for (int ndx = 0; ndx < 10; ndx++)
1589                 {
1590                         int             formatNdx       = rnd.getInt(0, DE_LENGTH_OF_ARRAY(texFormats)-1);
1591                         int             size            = 1 << rnd.getInt(2, 8);
1592
1593                         randomTexImageGroup->addChild(new RandomOrderTexImageCubeCase(m_context, (string("cube_") + de::toString(ndx)).c_str(), "", texFormats[formatNdx].format, texFormats[formatNdx].dataType, MIPMAPS, size, size));
1594                 }
1595         }
1596
1597         // TexImage2D unpack alignment.
1598         {
1599                 tcu::TestCaseGroup* alignGroup = new tcu::TestCaseGroup(m_testCtx, "teximage2d_align", "glTexImage2D() unpack alignment tests");
1600                 addChild(alignGroup);
1601
1602                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_l8_4_8",                        "",     GL_LUMINANCE,   GL_UNSIGNED_BYTE,                       MIPMAPS,         4, 8, 8));
1603                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_l8_63_1",                       "",     GL_LUMINANCE,   GL_UNSIGNED_BYTE,                       0,                      63, 30, 1));
1604                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_l8_63_2",                       "",     GL_LUMINANCE,   GL_UNSIGNED_BYTE,                       0,                      63, 30, 2));
1605                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_l8_63_4",                       "",     GL_LUMINANCE,   GL_UNSIGNED_BYTE,                       0,                      63, 30, 4));
1606                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_l8_63_8",                       "",     GL_LUMINANCE,   GL_UNSIGNED_BYTE,                       0,                      63, 30, 8));
1607                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_rgba4444_51_1",         "",     GL_RGBA,                GL_UNSIGNED_SHORT_4_4_4_4,      0,                      51, 30, 1));
1608                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_rgba4444_51_2",         "",     GL_RGBA,                GL_UNSIGNED_SHORT_4_4_4_4,      0,                      51, 30, 2));
1609                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_rgba4444_51_4",         "",     GL_RGBA,                GL_UNSIGNED_SHORT_4_4_4_4,      0,                      51, 30, 4));
1610                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_rgba4444_51_8",         "",     GL_RGBA,                GL_UNSIGNED_SHORT_4_4_4_4,      0,                      51, 30, 8));
1611                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_rgb888_39_1",           "",     GL_RGB,                 GL_UNSIGNED_BYTE,                       0,                      39, 43, 1));
1612                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_rgb888_39_2",           "",     GL_RGB,                 GL_UNSIGNED_BYTE,                       0,                      39, 43, 2));
1613                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_rgb888_39_4",           "",     GL_RGB,                 GL_UNSIGNED_BYTE,                       0,                      39, 43, 4));
1614                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_rgb888_39_8",           "",     GL_RGB,                 GL_UNSIGNED_BYTE,                       0,                      39, 43, 8));
1615                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_rgba8888_47_1",         "",     GL_RGBA,                GL_UNSIGNED_BYTE,                       0,                      47, 27, 1));
1616                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_rgba8888_47_2",         "",     GL_RGBA,                GL_UNSIGNED_BYTE,                       0,                      47, 27, 2));
1617                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_rgba8888_47_4",         "",     GL_RGBA,                GL_UNSIGNED_BYTE,                       0,                      47, 27, 4));
1618                 alignGroup->addChild(new TexImage2DAlignCase    (m_context, "2d_rgba8888_47_8",         "",     GL_RGBA,                GL_UNSIGNED_BYTE,                       0,                      47, 27, 8));
1619
1620                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_l8_4_8",                      "",     GL_LUMINANCE,   GL_UNSIGNED_BYTE,                       MIPMAPS,         4, 4, 8));
1621                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_l8_63_1",                     "",     GL_LUMINANCE,   GL_UNSIGNED_BYTE,                       0,                      63, 63, 1));
1622                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_l8_63_2",                     "",     GL_LUMINANCE,   GL_UNSIGNED_BYTE,                       0,                      63, 63, 2));
1623                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_l8_63_4",                     "",     GL_LUMINANCE,   GL_UNSIGNED_BYTE,                       0,                      63, 63, 4));
1624                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_l8_63_8",                     "",     GL_LUMINANCE,   GL_UNSIGNED_BYTE,                       0,                      63, 63, 8));
1625                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_rgba4444_51_1",       "",     GL_RGBA,                GL_UNSIGNED_SHORT_4_4_4_4,      0,                      51, 51, 1));
1626                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_rgba4444_51_2",       "",     GL_RGBA,                GL_UNSIGNED_SHORT_4_4_4_4,      0,                      51, 51, 2));
1627                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_rgba4444_51_4",       "",     GL_RGBA,                GL_UNSIGNED_SHORT_4_4_4_4,      0,                      51, 51, 4));
1628                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_rgba4444_51_8",       "",     GL_RGBA,                GL_UNSIGNED_SHORT_4_4_4_4,      0,                      51, 51, 8));
1629                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_rgb888_39_1",         "",     GL_RGB,                 GL_UNSIGNED_BYTE,                       0,                      39, 39, 1));
1630                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_rgb888_39_2",         "",     GL_RGB,                 GL_UNSIGNED_BYTE,                       0,                      39, 39, 2));
1631                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_rgb888_39_4",         "",     GL_RGB,                 GL_UNSIGNED_BYTE,                       0,                      39, 39, 4));
1632                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_rgb888_39_8",         "",     GL_RGB,                 GL_UNSIGNED_BYTE,                       0,                      39, 39, 8));
1633                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_rgba8888_47_1",       "",     GL_RGBA,                GL_UNSIGNED_BYTE,                       0,                      47, 47, 1));
1634                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_rgba8888_47_2",       "",     GL_RGBA,                GL_UNSIGNED_BYTE,                       0,                      47, 47, 2));
1635                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_rgba8888_47_4",       "",     GL_RGBA,                GL_UNSIGNED_BYTE,                       0,                      47, 47, 4));
1636                 alignGroup->addChild(new TexImageCubeAlignCase  (m_context, "cube_rgba8888_47_8",       "",     GL_RGBA,                GL_UNSIGNED_BYTE,                       0,                      47, 47, 8));
1637         }
1638
1639         // Basic TexSubImage2D usage.
1640         {
1641                 tcu::TestCaseGroup* basicTexSubImageGroup = new tcu::TestCaseGroup(m_testCtx, "basic_texsubimage2d", "Basic glTexSubImage2D() usage");
1642                 addChild(basicTexSubImageGroup);
1643                 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(texFormats); formatNdx++)
1644                 {
1645                         const char*     fmtName         = texFormats[formatNdx].name;
1646                         deUint32        format          = texFormats[formatNdx].format;
1647                         deUint32        dataType        = texFormats[formatNdx].dataType;
1648                         const int       tex2DWidth      = 64;
1649                         const int       tex2DHeight     = 128;
1650                         const int       texCubeSize     = 64;
1651
1652                         basicTexSubImageGroup->addChild(new BasicTexSubImage2DCase              (m_context,     (string(fmtName) + "_2d").c_str(),              "",     format, dataType, MIPMAPS, tex2DWidth, tex2DHeight));
1653                         basicTexSubImageGroup->addChild(new BasicTexSubImageCubeCase    (m_context,     (string(fmtName) + "_cube").c_str(),    "",     format, dataType, MIPMAPS, texCubeSize, texCubeSize));
1654                 }
1655         }
1656
1657         // TexSubImage2D to empty texture.
1658         {
1659                 tcu::TestCaseGroup* texSubImageEmptyTexGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage2d_empty_tex", "glTexSubImage2D() to texture that has storage but no data");
1660                 addChild(texSubImageEmptyTexGroup);
1661                 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(texFormats); formatNdx++)
1662                 {
1663                         const char*     fmtName         = texFormats[formatNdx].name;
1664                         deUint32        format          = texFormats[formatNdx].format;
1665                         deUint32        dataType        = texFormats[formatNdx].dataType;
1666                         const int       tex2DWidth      = 64;
1667                         const int       tex2DHeight     = 32;
1668                         const int       texCubeSize     = 32;
1669
1670                         texSubImageEmptyTexGroup->addChild(new TexSubImage2DEmptyTexCase        (m_context,     (string(fmtName) + "_2d").c_str(),              "",     format, dataType, MIPMAPS, tex2DWidth, tex2DHeight));
1671                         texSubImageEmptyTexGroup->addChild(new TexSubImageCubeEmptyTexCase      (m_context,     (string(fmtName) + "_cube").c_str(),    "",     format, dataType, MIPMAPS, texCubeSize, texCubeSize));
1672                 }
1673         }
1674
1675         // TexSubImage2D alignment cases.
1676         {
1677                 tcu::TestCaseGroup* alignGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage2d_align", "glTexSubImage2D() unpack alignment tests");
1678                 addChild(alignGroup);
1679
1680                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_l8_1_1",                        "",     GL_LUMINANCE,   GL_UNSIGNED_BYTE,                       64, 64, 13, 17,  1,  6, 1));
1681                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_l8_1_2",                        "",     GL_LUMINANCE,   GL_UNSIGNED_BYTE,                       64, 64, 13, 17,  1,  6, 2));
1682                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_l8_1_4",                        "",     GL_LUMINANCE,   GL_UNSIGNED_BYTE,                       64, 64, 13, 17,  1,  6, 4));
1683                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_l8_1_8",                        "",     GL_LUMINANCE,   GL_UNSIGNED_BYTE,                       64, 64, 13, 17,  1,  6, 8));
1684                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_l8_63_1",                       "",     GL_LUMINANCE,   GL_UNSIGNED_BYTE,                       64, 64,  1,  9, 63, 30, 1));
1685                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_l8_63_2",                       "",     GL_LUMINANCE,   GL_UNSIGNED_BYTE,                       64, 64,  1,  9, 63, 30, 2));
1686                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_l8_63_4",                       "",     GL_LUMINANCE,   GL_UNSIGNED_BYTE,                       64, 64,  1,  9, 63, 30, 4));
1687                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_l8_63_8",                       "",     GL_LUMINANCE,   GL_UNSIGNED_BYTE,                       64, 64,  1,  9, 63, 30, 8));
1688                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_rgba4444_51_1",         "",     GL_RGBA,                GL_UNSIGNED_SHORT_4_4_4_4,      64, 64,  7, 29, 51, 30, 1));
1689                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_rgba4444_51_2",         "",     GL_RGBA,                GL_UNSIGNED_SHORT_4_4_4_4,      64, 64,  7, 29, 51, 30, 2));
1690                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_rgba4444_51_4",         "",     GL_RGBA,                GL_UNSIGNED_SHORT_4_4_4_4,      64, 64,  7, 29, 51, 30, 4));
1691                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_rgba4444_51_8",         "",     GL_RGBA,                GL_UNSIGNED_SHORT_4_4_4_4,      64, 64,  7, 29, 51, 30, 8));
1692                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_rgb888_39_1",           "",     GL_RGB,                 GL_UNSIGNED_BYTE,                       64, 64, 11,  8, 39, 43, 1));
1693                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_rgb888_39_2",           "",     GL_RGB,                 GL_UNSIGNED_BYTE,                       64, 64, 11,  8, 39, 43, 2));
1694                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_rgb888_39_4",           "",     GL_RGB,                 GL_UNSIGNED_BYTE,                       64, 64, 11,  8, 39, 43, 4));
1695                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_rgb888_39_8",           "",     GL_RGB,                 GL_UNSIGNED_BYTE,                       64, 64, 11,  8, 39, 43, 8));
1696                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_rgba8888_47_1",         "",     GL_RGBA,                GL_UNSIGNED_BYTE,                       64, 64, 10,  1, 47, 27, 1));
1697                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_rgba8888_47_2",         "",     GL_RGBA,                GL_UNSIGNED_BYTE,                       64, 64, 10,  1, 47, 27, 2));
1698                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_rgba8888_47_4",         "",     GL_RGBA,                GL_UNSIGNED_BYTE,                       64, 64, 10,  1, 47, 27, 4));
1699                 alignGroup->addChild(new TexSubImage2DAlignCase         (m_context, "2d_rgba8888_47_8",         "",     GL_RGBA,                GL_UNSIGNED_BYTE,                       64, 64, 10,  1, 47, 27, 8));
1700
1701                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_l8_1_1",                      "",     GL_LUMINANCE,   GL_UNSIGNED_BYTE,                       64, 64, 13, 17,  1,  6, 1));
1702                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_l8_1_2",                      "",     GL_LUMINANCE,   GL_UNSIGNED_BYTE,                       64, 64, 13, 17,  1,  6, 2));
1703                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_l8_1_4",                      "",     GL_LUMINANCE,   GL_UNSIGNED_BYTE,                       64, 64, 13, 17,  1,  6, 4));
1704                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_l8_1_8",                      "",     GL_LUMINANCE,   GL_UNSIGNED_BYTE,                       64, 64, 13, 17,  1,  6, 8));
1705                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_l8_63_1",                     "",     GL_LUMINANCE,   GL_UNSIGNED_BYTE,                       64, 64,  1,  9, 63, 30, 1));
1706                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_l8_63_2",                     "",     GL_LUMINANCE,   GL_UNSIGNED_BYTE,                       64, 64,  1,  9, 63, 30, 2));
1707                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_l8_63_4",                     "",     GL_LUMINANCE,   GL_UNSIGNED_BYTE,                       64, 64,  1,  9, 63, 30, 4));
1708                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_l8_63_8",                     "",     GL_LUMINANCE,   GL_UNSIGNED_BYTE,                       64, 64,  1,  9, 63, 30, 8));
1709                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_rgba4444_51_1",       "",     GL_RGBA,                GL_UNSIGNED_SHORT_4_4_4_4,      64, 64,  7, 29, 51, 30, 1));
1710                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_rgba4444_51_2",       "",     GL_RGBA,                GL_UNSIGNED_SHORT_4_4_4_4,      64, 64,  7, 29, 51, 30, 2));
1711                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_rgba4444_51_4",       "",     GL_RGBA,                GL_UNSIGNED_SHORT_4_4_4_4,      64, 64,  7, 29, 51, 30, 4));
1712                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_rgba4444_51_8",       "",     GL_RGBA,                GL_UNSIGNED_SHORT_4_4_4_4,      64, 64,  7, 29, 51, 30, 8));
1713                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_rgb888_39_1",         "",     GL_RGB,                 GL_UNSIGNED_BYTE,                       64, 64, 11,  8, 39, 43, 1));
1714                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_rgb888_39_2",         "",     GL_RGB,                 GL_UNSIGNED_BYTE,                       64, 64, 11,  8, 39, 43, 2));
1715                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_rgb888_39_4",         "",     GL_RGB,                 GL_UNSIGNED_BYTE,                       64, 64, 11,  8, 39, 43, 4));
1716                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_rgb888_39_8",         "",     GL_RGB,                 GL_UNSIGNED_BYTE,                       64, 64, 11,  8, 39, 43, 8));
1717                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_rgba8888_47_1",       "",     GL_RGBA,                GL_UNSIGNED_BYTE,                       64, 64, 10,  1, 47, 27, 1));
1718                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_rgba8888_47_2",       "",     GL_RGBA,                GL_UNSIGNED_BYTE,                       64, 64, 10,  1, 47, 27, 2));
1719                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_rgba8888_47_4",       "",     GL_RGBA,                GL_UNSIGNED_BYTE,                       64, 64, 10,  1, 47, 27, 4));
1720                 alignGroup->addChild(new TexSubImageCubeAlignCase       (m_context, "cube_rgba8888_47_8",       "",     GL_RGBA,                GL_UNSIGNED_BYTE,                       64, 64, 10,  1, 47, 27, 8));
1721         }
1722
1723         // Basic glCopyTexImage2D() cases
1724         {
1725                 tcu::TestCaseGroup* copyTexImageGroup = new tcu::TestCaseGroup(m_testCtx, "basic_copyteximage2d", "Basic glCopyTexImage2D() usage");
1726                 addChild(copyTexImageGroup);
1727
1728                 copyTexImageGroup->addChild(new BasicCopyTexImage2DCase         (m_context, "2d_alpha",                         "",     GL_ALPHA,                       MIPMAPS,        128, 64));
1729                 copyTexImageGroup->addChild(new BasicCopyTexImage2DCase         (m_context, "2d_luminance",                     "",     GL_LUMINANCE,           MIPMAPS,        128, 64));
1730                 copyTexImageGroup->addChild(new BasicCopyTexImage2DCase         (m_context, "2d_luminance_alpha",       "",     GL_LUMINANCE_ALPHA,     MIPMAPS,        128, 64));
1731                 copyTexImageGroup->addChild(new BasicCopyTexImage2DCase         (m_context, "2d_rgb",                           "",     GL_RGB,                         MIPMAPS,        128, 64));
1732                 copyTexImageGroup->addChild(new BasicCopyTexImage2DCase         (m_context, "2d_rgba",                          "",     GL_RGBA,                        MIPMAPS,        128, 64));
1733
1734                 copyTexImageGroup->addChild(new BasicCopyTexImageCubeCase       (m_context, "cube_alpha",                       "",     GL_ALPHA,                       MIPMAPS,        64, 64));
1735                 copyTexImageGroup->addChild(new BasicCopyTexImageCubeCase       (m_context, "cube_luminance",           "",     GL_LUMINANCE,           MIPMAPS,        64, 64));
1736                 copyTexImageGroup->addChild(new BasicCopyTexImageCubeCase       (m_context, "cube_luminance_alpha",     "",     GL_LUMINANCE_ALPHA,     MIPMAPS,        64, 64));
1737                 copyTexImageGroup->addChild(new BasicCopyTexImageCubeCase       (m_context, "cube_rgb",                         "",     GL_RGB,                         MIPMAPS,        64, 64));
1738                 copyTexImageGroup->addChild(new BasicCopyTexImageCubeCase       (m_context, "cube_rgba",                        "",     GL_RGBA,                        MIPMAPS,        64, 64));
1739         }
1740
1741         // Basic glCopyTexSubImage2D() cases
1742         {
1743                 tcu::TestCaseGroup* copyTexSubImageGroup = new tcu::TestCaseGroup(m_testCtx, "basic_copytexsubimage2d", "Basic glCopyTexSubImage2D() usage");
1744                 addChild(copyTexSubImageGroup);
1745
1746                 copyTexSubImageGroup->addChild(new BasicCopyTexSubImage2DCase   (m_context, "2d_alpha",                         "",     GL_ALPHA,                       GL_UNSIGNED_BYTE, MIPMAPS, 128, 64));
1747                 copyTexSubImageGroup->addChild(new BasicCopyTexSubImage2DCase   (m_context, "2d_luminance",                     "",     GL_LUMINANCE,           GL_UNSIGNED_BYTE, MIPMAPS, 128, 64));
1748                 copyTexSubImageGroup->addChild(new BasicCopyTexSubImage2DCase   (m_context, "2d_luminance_alpha",       "",     GL_LUMINANCE_ALPHA,     GL_UNSIGNED_BYTE, MIPMAPS, 128, 64));
1749                 copyTexSubImageGroup->addChild(new BasicCopyTexSubImage2DCase   (m_context, "2d_rgb",                           "",     GL_RGB,                         GL_UNSIGNED_BYTE, MIPMAPS, 128, 64));
1750                 copyTexSubImageGroup->addChild(new BasicCopyTexSubImage2DCase   (m_context, "2d_rgba",                          "",     GL_RGBA,                        GL_UNSIGNED_BYTE, MIPMAPS, 128, 64));
1751
1752                 copyTexSubImageGroup->addChild(new BasicCopyTexSubImageCubeCase (m_context, "cube_alpha",                       "",     GL_ALPHA,                       GL_UNSIGNED_BYTE, MIPMAPS, 64, 64));
1753                 copyTexSubImageGroup->addChild(new BasicCopyTexSubImageCubeCase (m_context, "cube_luminance",           "",     GL_LUMINANCE,           GL_UNSIGNED_BYTE, MIPMAPS, 64, 64));
1754                 copyTexSubImageGroup->addChild(new BasicCopyTexSubImageCubeCase (m_context, "cube_luminance_alpha",     "",     GL_LUMINANCE_ALPHA,     GL_UNSIGNED_BYTE, MIPMAPS, 64, 64));
1755                 copyTexSubImageGroup->addChild(new BasicCopyTexSubImageCubeCase (m_context, "cube_rgb",                         "",     GL_RGB,                         GL_UNSIGNED_BYTE, MIPMAPS, 64, 64));
1756                 copyTexSubImageGroup->addChild(new BasicCopyTexSubImageCubeCase (m_context, "cube_rgba",                        "",     GL_RGBA,                        GL_UNSIGNED_BYTE, MIPMAPS, 64, 64));
1757         }
1758 }
1759
1760 } // Functional
1761 } // gles2
1762 } // deqp