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