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