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