1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 3.0 Module
3 * -------------------------------------------------
5 * Copyright 2014 The Android Open Source Project
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * \brief Texture specification tests.
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 *//*--------------------------------------------------------------------*/
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"
45 // \todo [2012-04-29 pyry] Should be named SglrUtil
46 #include "es31fFboTestUtil.hpp"
48 #include "glwEnums.hpp"
64 using namespace FboTestUtil;
72 static inline int maxLevelCount (int size)
74 return (int)deLog2Floor32(size)+1;
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))
80 tcu::Vector<float, Size> res;
81 for (int ndx = 0; ndx < Size; ndx++)
82 res[ndx] = rnd.getFloat(minVal[ndx], maxVal[ndx]);
86 static tcu::CubeFace getCubeFaceFromNdx (int ndx)
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;
98 return tcu::CUBEFACE_LAST;
102 class TextureSpecCase : public TestCase, public sglr::ContextWrapper
105 TextureSpecCase (Context& context, const char* name, const char* desc);
106 ~TextureSpecCase (void);
108 IterateResult iterate (void);
111 virtual bool checkExtensionSupport (void) { return true; }
113 virtual void createTexture (void) = DE_NULL;
114 virtual void verifyTexture (sglr::GLContext& gles3Context, sglr::ReferenceContext& refContext) = DE_NULL;
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);
121 TextureSpecCase (const TextureSpecCase& other);
122 TextureSpecCase& operator= (const TextureSpecCase& other);
125 TextureSpecCase::TextureSpecCase (Context& context, const char* name, const char* desc)
126 : TestCase(context, name, desc)
130 TextureSpecCase::~TextureSpecCase (void)
134 TextureSpecCase::IterateResult TextureSpecCase::iterate (void)
136 glu::RenderContext& renderCtx = TestCase::m_context.getRenderContext();
137 const tcu::RenderTarget& renderTarget = renderCtx.getRenderTarget();
138 tcu::TestLog& log = m_testCtx.getLog();
140 if (renderTarget.getWidth() < VIEWPORT_WIDTH || renderTarget.getHeight() < VIEWPORT_HEIGHT)
141 throw tcu::NotSupportedError("Too small viewport", "", __FILE__, __LINE__);
143 if (!checkExtensionSupport())
144 throw tcu::NotSupportedError("Extension not supported", "", __FILE__, __LINE__);
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);
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());
158 // Clear color buffer.
159 for (int ndx = 0; ndx < 2; ndx++)
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);
166 // Construct texture using both GLES3.1 and reference contexts.
167 for (int ndx = 0; ndx < 2; ndx++)
169 setContext(ndx ? (sglr::Context*)&refContext : (sglr::Context*)&gles31Context);
171 TCU_CHECK(glGetError() == GL_NO_ERROR);
174 // Initialize case result to pass.
175 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
178 gles31Context.enableLogging(0);
181 verifyTexture(gles31Context, refContext);
186 void TextureSpecCase::renderTex (tcu::Surface& dst, deUint32 program, int width, int height)
188 int targetW = getWidth();
189 int targetH = getHeight();
191 float w = (float)width / (float)targetW;
192 float h = (float)height / (float)targetH;
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));
197 readPixels(dst, 0, 0, width, height);
200 void TextureSpecCase::readPixels (tcu::Surface& dst, int x, int y, int width, int height)
202 dst.setSize(width, height);
203 glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, dst.getAccess().getDataPtr());
206 class TextureCubeArraySpecCase : public TextureSpecCase
209 TextureCubeArraySpecCase (Context& context, const char* name, const char* desc, const tcu::TextureFormat& format, int size, int depth, int numLevels);
210 ~TextureCubeArraySpecCase (void);
213 virtual bool checkExtensionSupport (void);
214 virtual void verifyTexture (sglr::GLContext& gles3Context, sglr::ReferenceContext& refContext);
216 tcu::TextureFormat m_texFormat;
217 tcu::TextureFormatInfo m_texFormatInfo;
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))
229 , m_numLevels (numLevels)
233 TextureCubeArraySpecCase::~TextureCubeArraySpecCase (void)
237 bool TextureCubeArraySpecCase::checkExtensionSupport (void)
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");
243 void TextureCubeArraySpecCase::verifyTexture (sglr::GLContext& gles3Context, sglr::ReferenceContext& refContext)
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);
250 shader.setTexScaleBias(m_texFormatInfo.lookupScale, m_texFormatInfo.lookupBias);
253 for (int ndx = 0; ndx < 2; ndx++)
255 sglr::Context* ctx = ndx ? static_cast<sglr::Context*>(&refContext) : static_cast<sglr::Context*>(&gles3Context);
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);
267 for (int layerFaceNdx = 0; layerFaceNdx < m_depth; layerFaceNdx++)
269 const int layerNdx = layerFaceNdx / 6;
270 const tcu::CubeFace face = getCubeFaceFromNdx(layerFaceNdx % 6);
273 shader.setLayer(layerNdx);
274 shader.setFace(face);
276 for (int levelNdx = 0; levelNdx < m_numLevels; levelNdx++)
278 int levelSize = de::max(1, m_size >> levelNdx);
279 tcu::Surface reference;
283 continue; // Fuzzy compare doesn't work for images this small.
285 for (int ndx = 0; ndx < 2; ndx++)
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;
292 shader.setUniforms(*ctx, shaderID);
293 renderTex(dst, shaderID, levelSize, levelSize);
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);
306 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
317 // Basic TexImage3D() with cube map array texture usage
318 class BasicTexImageCubeArrayCase : public TextureCubeArraySpecCase
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)
328 void createTexture (void)
331 de::Random rnd (deStringHash(getName()));
332 glu::TransferFormat transferFmt = glu::getTransferFormat(m_texFormat);
333 tcu::TextureLevel levelData (glu::mapGLTransferFormat(transferFmt.format, transferFmt.dataType));
335 glGenTextures(1, &tex);
336 glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, tex);
337 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
339 for (int ndx = 0; ndx < m_numLevels; ndx++)
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);
345 levelData.setSize(levelW, levelW, m_depth);
346 tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
348 glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, ndx, m_internalFormat, levelW, levelW, m_depth, 0, transferFmt.format, transferFmt.dataType, levelData.getAccess().getDataPtr());
352 deUint32 m_internalFormat;
355 // Basic glTexStorage3D() with cube map array texture usage
356 class BasicTexStorageCubeArrayCase : public TextureCubeArraySpecCase
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)
366 void createTexture (void)
369 de::Random rnd (deStringHash(getName()));
370 glu::TransferFormat transferFmt = glu::getTransferFormat(m_texFormat);
371 tcu::TextureLevel levelData (glu::mapGLTransferFormat(transferFmt.format, transferFmt.dataType));
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);
377 glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
379 for (int ndx = 0; ndx < m_numLevels; ndx++)
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);
385 levelData.setSize(levelW, levelW, m_depth);
386 tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
388 glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, ndx, 0, 0, 0, levelW, levelW, m_depth, transferFmt.format, transferFmt.dataType, levelData.getAccess().getDataPtr());
392 deUint32 m_internalFormat;
395 // Pixel buffer object cases.
397 // TexImage3D() cube map array from pixel buffer object.
398 class TexImageCubeArrayBufferCase : public TextureCubeArraySpecCase
401 TexImageCubeArrayBufferCase (Context& context,
404 deUint32 internalFormat,
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)
427 void createTexture (void)
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;
437 vector<deUint8> data;
439 DE_ASSERT(m_numLevels == 1);
441 // Fill data with grid.
442 data.resize(slicePitch*(m_depth+m_skipImages) + m_offset);
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;
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);
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);
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);
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);
468 deUint32 m_internalFormat;
478 // TexSubImage3D() cube map array PBO case.
479 class TexSubImageCubeArrayBufferCase : public TextureCubeArraySpecCase
482 TexSubImageCubeArrayBufferCase (Context& context,
485 deUint32 internalFormat,
501 : TextureCubeArraySpecCase (context, name, desc, glu::mapGLInternalFormat(internalFormat), size, depth, 1)
502 , m_internalFormat (internalFormat)
509 , m_imageHeight (imageHeight)
510 , m_rowLength (rowLength)
511 , m_skipImages (skipImages)
512 , m_skipRows (skipRows)
513 , m_skipPixels (skipPixels)
514 , m_alignment (alignment)
520 void createTexture (void)
522 glu::TransferFormat transferFmt = glu::getTransferFormat(m_texFormat);
523 int pixelSize = m_texFormat.getPixelSize();
526 vector<deUint8> data;
528 DE_ASSERT(m_numLevels == 1);
530 glGenTextures(1, &tex);
531 glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, tex);
533 // Fill with gradient.
535 int rowPitch = deAlign32(pixelSize*m_size, 4);
536 int slicePitch = rowPitch*m_size;
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);
542 glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, m_internalFormat, m_size, m_size, m_depth, 0, transferFmt.format, transferFmt.dataType, &data[0]);
544 // Fill data with grid.
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;
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);
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);
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);
572 deUint32 m_internalFormat;
588 // TexImage3D() depth case.
589 class TexImageCubeArrayDepthCase : public TextureCubeArraySpecCase
592 TexImageCubeArrayDepthCase (Context& context,
595 deUint32 internalFormat,
598 : TextureCubeArraySpecCase(context, name, desc, glu::mapGLInternalFormat(internalFormat), imageSize, numLayers, maxLevelCount(imageSize))
599 , m_internalFormat (internalFormat)
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);
606 void createTexture (void)
608 glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat);
610 tcu::TextureLevel levelData (glu::mapGLTransferFormat(fmt.format, fmt.dataType));
612 glGenTextures(1, &tex);
613 glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, tex);
614 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
617 for (int ndx = 0; ndx < m_numLevels; ndx++)
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);
623 levelData.setSize(levelW, levelW, m_depth);
624 tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
626 glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, ndx, m_internalFormat, levelW, levelW, m_depth, 0, fmt.format, fmt.dataType, levelData.getAccess().getDataPtr());
630 const deUint32 m_internalFormat;
633 // TexSubImage3D() depth case.
634 class TexSubImageCubeArrayDepthCase : public TextureCubeArraySpecCase
637 TexSubImageCubeArrayDepthCase (Context& context,
640 deUint32 internalFormat,
643 : TextureCubeArraySpecCase(context, name, desc, glu::mapGLInternalFormat(internalFormat), imageSize, numLayers, maxLevelCount(imageSize))
644 , m_internalFormat (internalFormat)
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);
651 void createTexture (void)
653 glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat);
654 de::Random rnd (deStringHash(getName()));
656 tcu::TextureLevel levelData (glu::mapGLTransferFormat(fmt.format, fmt.dataType));
658 glGenTextures(1, &tex);
659 glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, tex);
660 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
663 // First specify full texture.
664 for (int ndx = 0; ndx < m_numLevels; ndx++)
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);
670 levelData.setSize(levelW, levelW, m_depth);
671 tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
673 glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, ndx, m_internalFormat, levelW, levelW, m_depth, 0, fmt.format, fmt.dataType, levelData.getAccess().getDataPtr());
676 // Re-specify parts of each level.
677 for (int ndx = 0; ndx < m_numLevels; ndx++)
679 const int levelW = de::max(1, m_size >> ndx);
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);
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);
692 levelData.setSize(w, h, d);
693 tcu::fillWithGrid(levelData.getAccess(), cellSize, colorA, colorB);
695 glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, ndx, x, y, z, w, h, d, fmt.format, fmt.dataType, levelData.getAccess().getDataPtr());
699 const deUint32 m_internalFormat;
702 // TexImage3D() depth case with pbo.
703 class TexImageCubeArrayDepthBufferCase : public TextureCubeArraySpecCase
706 TexImageCubeArrayDepthBufferCase (Context& context,
709 deUint32 internalFormat,
712 : TextureCubeArraySpecCase(context, name, desc, glu::mapGLInternalFormat(internalFormat), imageSize, numLayers, 1)
713 , m_internalFormat (internalFormat)
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);
720 void createTexture (void)
722 glu::TransferFormat transferFmt = glu::getTransferFormat(m_texFormat);
723 int pixelSize = m_texFormat.getPixelSize();
724 int rowLength = m_size;
726 int rowPitch = deAlign32(rowLength*pixelSize, alignment);
727 int imageHeight = m_size;
728 int slicePitch = imageHeight*rowPitch;
731 vector<deUint8> data;
733 DE_ASSERT(m_numLevels == 1);
735 // Fill data with grid.
736 data.resize(slicePitch*m_depth);
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);
741 tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_size, m_size, m_depth, rowPitch, slicePitch, &data[0]), gMin, gMax);
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);
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);
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);
761 const deUint32 m_internalFormat;
764 TextureSpecificationTests::TextureSpecificationTests (Context& context)
765 : TestCaseGroup(context, "specification", "Texture Specification Tests")
769 TextureSpecificationTests::~TextureSpecificationTests (void)
773 void TextureSpecificationTests::init (void)
778 deUint32 internalFormat;
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, },
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, },
828 { "r8ui", GL_R8UI, },
829 { "r8_snorm", GL_R8_SNORM, }
835 deUint32 internalFormat;
836 } depthStencilFormats[] =
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 }
846 // Basic TexImage3D usage.
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++)
852 const char* fmtName = colorFormats[formatNdx].name;
853 deUint32 format = colorFormats[formatNdx].internalFormat;
854 const int texCubeArraySize = 64;
855 const int texCubeArrayLayers = 6;
857 basicTexImageGroup->addChild(new BasicTexImageCubeArrayCase (m_context, (string(fmtName) + "_cube_array").c_str(), "", format, texCubeArraySize, texCubeArrayLayers));
861 // glTexImage3D() pbo cases.
863 tcu::TestCaseGroup* pboGroup = new tcu::TestCaseGroup(m_testCtx, "teximage3d_pbo", "glTexImage3D() from PBO");
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 }
891 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++)
893 const string fmtName = colorFormats[formatNdx].name;
894 const deUint32 format = colorFormats[formatNdx].internalFormat;
895 const int texCubeArraySize = 20;
896 const int texCubeDepth = 6;
898 pboGroup->addChild(new TexImageCubeArrayBufferCase (m_context, (fmtName + "_cube_array").c_str(), "", format, texCubeArraySize, texCubeDepth, 0, 0, 0, 0, 0, 4, 0));
901 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(parameterCases); ndx++)
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));
917 // glTexImage3D() depth cases.
919 tcu::TestCaseGroup* shadow3dGroup = new tcu::TestCaseGroup(m_testCtx, "teximage3d_depth", "glTexImage3D() with depth or depth/stencil format");
920 addChild(shadow3dGroup);
922 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++)
924 const int texCubeArraySize = 64;
925 const int texCubeArrayDepth = 6;
927 shadow3dGroup->addChild(new TexImageCubeArrayDepthCase(m_context, (std::string(depthStencilFormats[ndx].name) + "_cube_array").c_str(), "", depthStencilFormats[ndx].internalFormat, texCubeArraySize, texCubeArrayDepth));
931 // glTexImage3D() depth cases with pbo.
933 tcu::TestCaseGroup* shadow3dGroup = new tcu::TestCaseGroup(m_testCtx, "teximage3d_depth_pbo", "glTexImage3D() with depth or depth/stencil format with pbo");
934 addChild(shadow3dGroup);
936 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++)
938 const int texCubeArraySize = 64;
939 const int texCubeArrayDepth = 6;
941 shadow3dGroup->addChild(new TexImageCubeArrayDepthBufferCase(m_context, (std::string(depthStencilFormats[ndx].name) + "_cube_array").c_str(), "", depthStencilFormats[ndx].internalFormat, texCubeArraySize, texCubeArrayDepth));
945 // glTexSubImage3D() PBO cases.
947 tcu::TestCaseGroup* pboGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage3d_pbo", "glTexSubImage3D() pixel buffer object tests");
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 }
979 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(colorFormats); ndx++)
981 pboGroup->addChild(new TexSubImageCubeArrayBufferCase(m_context, (std::string(colorFormats[ndx].name) + "_cube_array").c_str(), "",
982 colorFormats[ndx].internalFormat,
1000 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(paramCases); ndx++)
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));
1022 // glTexSubImage3D() depth cases.
1024 tcu::TestCaseGroup* shadow3dGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage3d_depth", "glTexSubImage3D() with depth or depth/stencil format");
1025 addChild(shadow3dGroup);
1027 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++)
1029 const int texCubeArraySize = 57;
1030 const int texCubeArrayLayers = 6;
1032 shadow3dGroup->addChild(new TexSubImageCubeArrayDepthCase(m_context, (std::string(depthStencilFormats[ndx].name) + "_cube_array").c_str(), "", depthStencilFormats[ndx].internalFormat, texCubeArraySize, texCubeArrayLayers));
1036 // glTexStorage3D() cases.
1038 tcu::TestCaseGroup* texStorageGroup = new tcu::TestCaseGroup(m_testCtx, "texstorage3d", "Basic glTexStorage3D() usage");
1039 addChild(texStorageGroup);
1042 tcu::TestCaseGroup* formatGroup = new tcu::TestCaseGroup(m_testCtx, "format", "glTexStorage3D() with all formats");
1043 texStorageGroup->addChild(formatGroup);
1046 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++)
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);
1054 formatGroup->addChild(new BasicTexStorageCubeArrayCase (m_context, (string(fmtName) + "_cube_array").c_str(), "", internalFormat, texCubeArraySize, texCubeArrayLayers, texCubeArrayLevels));
1057 // Depth/stencil formats (only 2D texture array is supported).
1058 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(depthStencilFormats); formatNdx++)
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);
1066 formatGroup->addChild(new BasicTexStorageCubeArrayCase (m_context, (string(fmtName) + "_cube_array").c_str(), "", internalFormat, texCubeArraySize, texCubeArrayLayers, texCubeArrayLevels));
1075 } texCubeArraySizes[] =
1087 tcu::TestCaseGroup* sizeGroup = new tcu::TestCaseGroup(m_testCtx, "size", "glTexStorage3D() with various sizes");
1088 texStorageGroup->addChild(sizeGroup);
1090 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(texCubeArraySizes); ndx++)
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";
1098 sizeGroup->addChild(new BasicTexStorageCubeArrayCase(m_context, name.c_str(), "", format, size, layers, levels));