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