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