| /*------------------------------------------------------------------------- |
| * drawElements Quality Program OpenGL ES 3.0 Module |
| * ------------------------------------------------- |
| * |
| * Copyright 2014 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| *//*! |
| * \file |
| * \brief Texture specification tests. |
| * |
| * \todo [pyry] Following tests are missing: |
| * - Specify mipmap incomplete texture, use without mipmaps, re-specify |
| * as complete and render. |
| * - Randomly re-specify levels to eventually reach mipmap-complete texture. |
| *//*--------------------------------------------------------------------*/ |
| |
| #include "es31fTextureSpecificationTests.hpp" |
| #include "tcuTestLog.hpp" |
| #include "tcuImageCompare.hpp" |
| #include "tcuTextureUtil.hpp" |
| #include "tcuVectorUtil.hpp" |
| #include "gluStrUtil.hpp" |
| #include "gluTexture.hpp" |
| #include "gluTextureUtil.hpp" |
| #include "sglrContextUtil.hpp" |
| #include "sglrContextWrapper.hpp" |
| #include "sglrGLContext.hpp" |
| #include "sglrReferenceContext.hpp" |
| #include "glsTextureTestUtil.hpp" |
| #include "deRandom.hpp" |
| #include "deStringUtil.hpp" |
| |
| // \todo [2012-04-29 pyry] Should be named SglrUtil |
| #include "es31fFboTestUtil.hpp" |
| |
| #include "glwEnums.hpp" |
| |
| namespace deqp |
| { |
| namespace gles31 |
| { |
| namespace Functional |
| { |
| |
| using std::pair; |
| using std::string; |
| using std::vector; |
| using tcu::IVec4; |
| using tcu::TestLog; |
| using tcu::UVec4; |
| using tcu::Vec4; |
| using namespace FboTestUtil; |
| |
| enum |
| { |
| VIEWPORT_WIDTH = 256, |
| VIEWPORT_HEIGHT = 256 |
| }; |
| |
| static inline int maxLevelCount(int size) |
| { |
| return (int)deLog2Floor32(size) + 1; |
| } |
| |
| template <int Size> |
| 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)) |
| { |
| tcu::Vector<float, Size> res; |
| for (int ndx = 0; ndx < Size; ndx++) |
| res[ndx] = rnd.getFloat(minVal[ndx], maxVal[ndx]); |
| return res; |
| } |
| |
| static tcu::CubeFace getCubeFaceFromNdx(int ndx) |
| { |
| switch (ndx) |
| { |
| case 0: |
| return tcu::CUBEFACE_POSITIVE_X; |
| case 1: |
| return tcu::CUBEFACE_NEGATIVE_X; |
| case 2: |
| return tcu::CUBEFACE_POSITIVE_Y; |
| case 3: |
| return tcu::CUBEFACE_NEGATIVE_Y; |
| case 4: |
| return tcu::CUBEFACE_POSITIVE_Z; |
| case 5: |
| return tcu::CUBEFACE_NEGATIVE_Z; |
| default: |
| DE_ASSERT(false); |
| return tcu::CUBEFACE_LAST; |
| } |
| } |
| |
| class TextureSpecCase : public TestCase, public sglr::ContextWrapper |
| { |
| public: |
| TextureSpecCase(Context &context, const char *name, const char *desc); |
| ~TextureSpecCase(void); |
| |
| IterateResult iterate(void); |
| |
| protected: |
| virtual bool checkExtensionSupport(void) |
| { |
| return true; |
| } |
| |
| virtual void createTexture(void) = DE_NULL; |
| virtual void verifyTexture(sglr::GLContext &gles3Context, sglr::ReferenceContext &refContext) = DE_NULL; |
| |
| // Utilities. |
| void renderTex(tcu::Surface &dst, uint32_t program, int width, int height); |
| void readPixels(tcu::Surface &dst, int x, int y, int width, int height); |
| |
| private: |
| TextureSpecCase(const TextureSpecCase &other); |
| TextureSpecCase &operator=(const TextureSpecCase &other); |
| }; |
| |
| TextureSpecCase::TextureSpecCase(Context &context, const char *name, const char *desc) : TestCase(context, name, desc) |
| { |
| } |
| |
| TextureSpecCase::~TextureSpecCase(void) |
| { |
| } |
| |
| TextureSpecCase::IterateResult TextureSpecCase::iterate(void) |
| { |
| glu::RenderContext &renderCtx = TestCase::m_context.getRenderContext(); |
| const tcu::RenderTarget &renderTarget = renderCtx.getRenderTarget(); |
| tcu::TestLog &log = m_testCtx.getLog(); |
| |
| if (renderTarget.getWidth() < VIEWPORT_WIDTH || renderTarget.getHeight() < VIEWPORT_HEIGHT) |
| throw tcu::NotSupportedError("Too small viewport", "", __FILE__, __LINE__); |
| |
| if (!checkExtensionSupport()) |
| throw tcu::NotSupportedError("Extension not supported", "", __FILE__, __LINE__); |
| |
| // Context size, and viewport for GLES3.1 |
| de::Random rnd(deStringHash(getName())); |
| int width = deMin32(renderTarget.getWidth(), VIEWPORT_WIDTH); |
| int height = deMin32(renderTarget.getHeight(), VIEWPORT_HEIGHT); |
| int x = rnd.getInt(0, renderTarget.getWidth() - width); |
| int y = rnd.getInt(0, renderTarget.getHeight() - height); |
| |
| // Contexts. |
| sglr::GLContext gles31Context(renderCtx, log, sglr::GLCONTEXT_LOG_CALLS, tcu::IVec4(x, y, width, height)); |
| sglr::ReferenceContextBuffers refBuffers(tcu::PixelFormat(8, 8, 8, renderTarget.getPixelFormat().alphaBits ? 8 : 0), |
| 0 /* depth */, 0 /* stencil */, width, height); |
| sglr::ReferenceContext refContext(sglr::ReferenceContextLimits(renderCtx), refBuffers.getColorbuffer(), |
| refBuffers.getDepthbuffer(), refBuffers.getStencilbuffer()); |
| |
| // Clear color buffer. |
| for (int ndx = 0; ndx < 2; ndx++) |
| { |
| setContext(ndx ? (sglr::Context *)&refContext : (sglr::Context *)&gles31Context); |
| glClearColor(0.125f, 0.25f, 0.5f, 1.0f); |
| glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); |
| } |
| |
| // Construct texture using both GLES3.1 and reference contexts. |
| for (int ndx = 0; ndx < 2; ndx++) |
| { |
| setContext(ndx ? (sglr::Context *)&refContext : (sglr::Context *)&gles31Context); |
| createTexture(); |
| TCU_CHECK(glGetError() == GL_NO_ERROR); |
| } |
| |
| // Initialize case result to pass. |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| |
| // Disable logging. |
| gles31Context.enableLogging(0); |
| |
| // Verify results. |
| verifyTexture(gles31Context, refContext); |
| |
| return STOP; |
| } |
| |
| void TextureSpecCase::renderTex(tcu::Surface &dst, uint32_t program, int width, int height) |
| { |
| int targetW = getWidth(); |
| int targetH = getHeight(); |
| |
| float w = (float)width / (float)targetW; |
| float h = (float)height / (float)targetH; |
| |
| 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)); |
| |
| // Read pixels back. |
| readPixels(dst, 0, 0, width, height); |
| } |
| |
| void TextureSpecCase::readPixels(tcu::Surface &dst, int x, int y, int width, int height) |
| { |
| dst.setSize(width, height); |
| glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, dst.getAccess().getDataPtr()); |
| } |
| |
| class TextureCubeArraySpecCase : public TextureSpecCase |
| { |
| public: |
| TextureCubeArraySpecCase(Context &context, const char *name, const char *desc, const tcu::TextureFormat &format, |
| int size, int depth, int numLevels); |
| ~TextureCubeArraySpecCase(void); |
| |
| protected: |
| virtual bool checkExtensionSupport(void); |
| virtual void verifyTexture(sglr::GLContext &gles3Context, sglr::ReferenceContext &refContext); |
| |
| tcu::TextureFormat m_texFormat; |
| tcu::TextureFormatInfo m_texFormatInfo; |
| int m_size; |
| int m_depth; |
| int m_numLevels; |
| }; |
| |
| TextureCubeArraySpecCase::TextureCubeArraySpecCase(Context &context, const char *name, const char *desc, |
| const tcu::TextureFormat &format, int size, int depth, int numLevels) |
| : TextureSpecCase(context, name, desc) |
| , m_texFormat(format) |
| , m_texFormatInfo(tcu::getTextureFormatInfo(format)) |
| , m_size(size) |
| , m_depth(depth) |
| , m_numLevels(numLevels) |
| { |
| } |
| |
| TextureCubeArraySpecCase::~TextureCubeArraySpecCase(void) |
| { |
| } |
| |
| bool TextureCubeArraySpecCase::checkExtensionSupport(void) |
| { |
| glu::ContextType contextType = m_context.getRenderContext().getType(); |
| const bool supportsES32orGL45 = glu::contextSupports(contextType, glu::ApiType::es(3, 2)) || |
| glu::contextSupports(contextType, glu::ApiType::core(4, 5)); |
| return supportsES32orGL45 || m_context.getContextInfo().isExtensionSupported("GL_EXT_texture_cube_map_array"); |
| } |
| |
| void TextureCubeArraySpecCase::verifyTexture(sglr::GLContext &gles3Context, sglr::ReferenceContext &refContext) |
| { |
| const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType()); |
| TextureCubeArrayShader shader(glu::getSamplerCubeArrayType(m_texFormat), glu::TYPE_FLOAT_VEC4, glslVersion); |
| uint32_t shaderIDgles = gles3Context.createProgram(&shader); |
| uint32_t shaderIDRef = refContext.createProgram(&shader); |
| |
| shader.setTexScaleBias(m_texFormatInfo.lookupScale, m_texFormatInfo.lookupBias); |
| |
| // Set state. |
| for (int ndx = 0; ndx < 2; ndx++) |
| { |
| sglr::Context *ctx = |
| ndx ? static_cast<sglr::Context *>(&refContext) : static_cast<sglr::Context *>(&gles3Context); |
| |
| setContext(ctx); |
| |
| glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); |
| glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); |
| glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAX_LEVEL, m_numLevels - 1); |
| } |
| |
| for (int layerFaceNdx = 0; layerFaceNdx < m_depth; layerFaceNdx++) |
| { |
| const int layerNdx = layerFaceNdx / 6; |
| const tcu::CubeFace face = getCubeFaceFromNdx(layerFaceNdx % 6); |
| bool layerOk = true; |
| |
| shader.setLayer(layerNdx); |
| shader.setFace(face); |
| |
| for (int levelNdx = 0; levelNdx < m_numLevels; levelNdx++) |
| { |
| int levelSize = de::max(1, m_size >> levelNdx); |
| tcu::Surface reference; |
| tcu::Surface result; |
| |
| if (levelSize <= 2) |
| continue; // Fuzzy compare doesn't work for images this small. |
| |
| for (int ndx = 0; ndx < 2; ndx++) |
| { |
| tcu::Surface &dst = ndx ? reference : result; |
| sglr::Context *ctx = |
| ndx ? static_cast<sglr::Context *>(&refContext) : static_cast<sglr::Context *>(&gles3Context); |
| uint32_t shaderID = ndx ? shaderIDRef : shaderIDgles; |
| |
| setContext(ctx); |
| shader.setUniforms(*ctx, shaderID); |
| renderTex(dst, shaderID, levelSize, levelSize); |
| } |
| |
| const float threshold = 0.02f; |
| string levelStr = de::toString(levelNdx); |
| string layerFaceStr = de::toString(layerFaceNdx); |
| string name = string("LayerFace") + layerFaceStr + "Level" + levelStr; |
| string desc = string("Layer-face ") + layerFaceStr + ", Level " + levelStr; |
| bool isFaceOk = tcu::fuzzyCompare( |
| m_testCtx.getLog(), name.c_str(), desc.c_str(), reference, result, threshold, |
| (levelNdx == 0 && layerFaceNdx == 0) == 0 ? tcu::COMPARE_LOG_RESULT : tcu::COMPARE_LOG_ON_ERROR); |
| |
| if (!isFaceOk) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed"); |
| layerOk = false; |
| break; |
| } |
| } |
| |
| if (!layerOk) |
| break; |
| } |
| } |
| |
| // Basic TexImage3D() with cube map array texture usage |
| class BasicTexImageCubeArrayCase : public TextureCubeArraySpecCase |
| { |
| public: |
| BasicTexImageCubeArrayCase(Context &context, const char *name, const char *desc, uint32_t internalFormat, int size, |
| int numLayers) |
| : TextureCubeArraySpecCase(context, name, desc, glu::mapGLInternalFormat(internalFormat), size, numLayers, |
| maxLevelCount(size)) |
| , m_internalFormat(internalFormat) |
| { |
| } |
| |
| protected: |
| void createTexture(void) |
| { |
| uint32_t tex = 0; |
| de::Random rnd(deStringHash(getName())); |
| glu::TransferFormat transferFmt = glu::getTransferFormat(m_texFormat); |
| tcu::TextureLevel levelData(glu::mapGLTransferFormat(transferFmt.format, transferFmt.dataType)); |
| |
| glGenTextures(1, &tex); |
| glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, tex); |
| glPixelStorei(GL_UNPACK_ALIGNMENT, 1); |
| |
| for (int ndx = 0; ndx < m_numLevels; ndx++) |
| { |
| int levelW = de::max(1, m_size >> ndx); |
| Vec4 gMin = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax); |
| Vec4 gMax = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax); |
| |
| levelData.setSize(levelW, levelW, m_depth); |
| tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax); |
| |
| glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, ndx, m_internalFormat, levelW, levelW, m_depth, 0, |
| transferFmt.format, transferFmt.dataType, levelData.getAccess().getDataPtr()); |
| } |
| } |
| |
| uint32_t m_internalFormat; |
| }; |
| |
| // Basic glTexStorage3D() with cube map array texture usage |
| class BasicTexStorageCubeArrayCase : public TextureCubeArraySpecCase |
| { |
| public: |
| BasicTexStorageCubeArrayCase(Context &context, const char *name, const char *desc, uint32_t internalFormat, |
| int size, int numLayers, int numLevels) |
| : TextureCubeArraySpecCase(context, name, desc, glu::mapGLInternalFormat(internalFormat), size, numLayers, |
| numLevels) |
| , m_internalFormat(internalFormat) |
| { |
| } |
| |
| protected: |
| void createTexture(void) |
| { |
| uint32_t tex = 0; |
| de::Random rnd(deStringHash(getName())); |
| glu::TransferFormat transferFmt = glu::getTransferFormat(m_texFormat); |
| tcu::TextureLevel levelData(glu::mapGLTransferFormat(transferFmt.format, transferFmt.dataType)); |
| |
| glGenTextures(1, &tex); |
| glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, tex); |
| glTexStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, m_numLevels, m_internalFormat, m_size, m_size, m_depth); |
| |
| glPixelStorei(GL_UNPACK_ALIGNMENT, 1); |
| |
| for (int ndx = 0; ndx < m_numLevels; ndx++) |
| { |
| int levelW = de::max(1, m_size >> ndx); |
| Vec4 gMin = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax); |
| Vec4 gMax = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax); |
| |
| levelData.setSize(levelW, levelW, m_depth); |
| tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax); |
| |
| glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, ndx, 0, 0, 0, levelW, levelW, m_depth, transferFmt.format, |
| transferFmt.dataType, levelData.getAccess().getDataPtr()); |
| } |
| } |
| |
| uint32_t m_internalFormat; |
| }; |
| |
| // Pixel buffer object cases. |
| |
| // TexImage3D() cube map array from pixel buffer object. |
| class TexImageCubeArrayBufferCase : public TextureCubeArraySpecCase |
| { |
| public: |
| TexImageCubeArrayBufferCase(Context &context, const char *name, const char *desc, uint32_t internalFormat, int size, |
| int depth, int imageHeight, int rowLength, int skipImages, int skipRows, int skipPixels, |
| int alignment, int offset) |
| : TextureCubeArraySpecCase(context, name, desc, glu::mapGLInternalFormat(internalFormat), size, depth, 1) |
| , m_internalFormat(internalFormat) |
| , m_imageHeight(imageHeight) |
| , m_rowLength(rowLength) |
| , m_skipImages(skipImages) |
| , m_skipRows(skipRows) |
| , m_skipPixels(skipPixels) |
| , m_alignment(alignment) |
| , m_offset(offset) |
| { |
| } |
| |
| protected: |
| void createTexture(void) |
| { |
| glu::TransferFormat transferFmt = glu::getTransferFormat(m_texFormat); |
| int pixelSize = m_texFormat.getPixelSize(); |
| int rowLength = m_rowLength > 0 ? m_rowLength : m_size; |
| int rowPitch = deAlign32(rowLength * pixelSize, m_alignment); |
| int imageHeight = m_imageHeight > 0 ? m_imageHeight : m_size; |
| int slicePitch = imageHeight * rowPitch; |
| uint32_t tex = 0; |
| uint32_t buf = 0; |
| vector<uint8_t> data; |
| |
| DE_ASSERT(m_numLevels == 1); |
| |
| // Fill data with grid. |
| data.resize(slicePitch * (m_depth + m_skipImages) + m_offset); |
| { |
| Vec4 cScale = m_texFormatInfo.valueMax - m_texFormatInfo.valueMin; |
| Vec4 cBias = m_texFormatInfo.valueMin; |
| Vec4 colorA = Vec4(1.0f, 0.0f, 0.0f, 1.0f) * cScale + cBias; |
| Vec4 colorB = Vec4(0.0f, 1.0f, 0.0f, 1.0f) * cScale + cBias; |
| |
| 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); |
| } |
| |
| glGenBuffers(1, &buf); |
| glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf); |
| glBufferData(GL_PIXEL_UNPACK_BUFFER, (int)data.size(), &data[0], GL_STATIC_DRAW); |
| |
| glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, m_imageHeight); |
| glPixelStorei(GL_UNPACK_ROW_LENGTH, m_rowLength); |
| glPixelStorei(GL_UNPACK_SKIP_IMAGES, m_skipImages); |
| glPixelStorei(GL_UNPACK_SKIP_ROWS, m_skipRows); |
| glPixelStorei(GL_UNPACK_SKIP_PIXELS, m_skipPixels); |
| glPixelStorei(GL_UNPACK_ALIGNMENT, m_alignment); |
| |
| glGenTextures(1, &tex); |
| glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, tex); |
| glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, m_internalFormat, m_size, m_size, m_depth, 0, transferFmt.format, |
| transferFmt.dataType, (const void *)(uintptr_t)m_offset); |
| } |
| |
| uint32_t m_internalFormat; |
| int m_imageHeight; |
| int m_rowLength; |
| int m_skipImages; |
| int m_skipRows; |
| int m_skipPixels; |
| int m_alignment; |
| int m_offset; |
| }; |
| |
| // TexSubImage3D() cube map array PBO case. |
| class TexSubImageCubeArrayBufferCase : public TextureCubeArraySpecCase |
| { |
| public: |
| TexSubImageCubeArrayBufferCase(Context &context, const char *name, const char *desc, uint32_t internalFormat, |
| int size, int depth, int subX, int subY, int subZ, int subW, int subH, int subD, |
| int imageHeight, int rowLength, int skipImages, int skipRows, int skipPixels, |
| int alignment, int offset) |
| : TextureCubeArraySpecCase(context, name, desc, glu::mapGLInternalFormat(internalFormat), size, depth, 1) |
| , m_internalFormat(internalFormat) |
| , m_subX(subX) |
| , m_subY(subY) |
| , m_subZ(subZ) |
| , m_subW(subW) |
| , m_subH(subH) |
| , m_subD(subD) |
| , m_imageHeight(imageHeight) |
| , m_rowLength(rowLength) |
| , m_skipImages(skipImages) |
| , m_skipRows(skipRows) |
| , m_skipPixels(skipPixels) |
| , m_alignment(alignment) |
| , m_offset(offset) |
| { |
| } |
| |
| protected: |
| void createTexture(void) |
| { |
| glu::TransferFormat transferFmt = glu::getTransferFormat(m_texFormat); |
| int pixelSize = m_texFormat.getPixelSize(); |
| uint32_t tex = 0; |
| uint32_t buf = 0; |
| vector<uint8_t> data; |
| |
| DE_ASSERT(m_numLevels == 1); |
| |
| glGenTextures(1, &tex); |
| glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, tex); |
| |
| // Fill with gradient. |
| { |
| int rowPitch = deAlign32(pixelSize * m_size, 4); |
| int slicePitch = rowPitch * m_size; |
| |
| data.resize(slicePitch * m_depth); |
| tcu::fillWithComponentGradients( |
| tcu::PixelBufferAccess(m_texFormat, m_size, m_size, m_depth, rowPitch, slicePitch, &data[0]), |
| m_texFormatInfo.valueMin, m_texFormatInfo.valueMax); |
| } |
| |
| glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, m_internalFormat, m_size, m_size, m_depth, 0, transferFmt.format, |
| transferFmt.dataType, &data[0]); |
| |
| // Fill data with grid. |
| { |
| int rowLength = m_rowLength > 0 ? m_rowLength : m_subW; |
| int rowPitch = deAlign32(rowLength * pixelSize, m_alignment); |
| int imageHeight = m_imageHeight > 0 ? m_imageHeight : m_subH; |
| int slicePitch = imageHeight * rowPitch; |
| Vec4 cScale = m_texFormatInfo.valueMax - m_texFormatInfo.valueMin; |
| Vec4 cBias = m_texFormatInfo.valueMin; |
| Vec4 colorA = Vec4(1.0f, 0.0f, 0.0f, 1.0f) * cScale + cBias; |
| Vec4 colorB = Vec4(0.0f, 1.0f, 0.0f, 1.0f) * cScale + cBias; |
| |
| data.resize(slicePitch * (m_depth + m_skipImages) + m_offset); |
| 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); |
| } |
| |
| glGenBuffers(1, &buf); |
| glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf); |
| glBufferData(GL_PIXEL_UNPACK_BUFFER, (int)data.size(), &data[0], GL_STATIC_DRAW); |
| |
| glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, m_imageHeight); |
| glPixelStorei(GL_UNPACK_ROW_LENGTH, m_rowLength); |
| glPixelStorei(GL_UNPACK_SKIP_IMAGES, m_skipImages); |
| glPixelStorei(GL_UNPACK_SKIP_ROWS, m_skipRows); |
| glPixelStorei(GL_UNPACK_SKIP_PIXELS, m_skipPixels); |
| glPixelStorei(GL_UNPACK_ALIGNMENT, m_alignment); |
| 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 *)(intptr_t)m_offset); |
| } |
| |
| uint32_t m_internalFormat; |
| int m_subX; |
| int m_subY; |
| int m_subZ; |
| int m_subW; |
| int m_subH; |
| int m_subD; |
| int m_imageHeight; |
| int m_rowLength; |
| int m_skipImages; |
| int m_skipRows; |
| int m_skipPixels; |
| int m_alignment; |
| int m_offset; |
| }; |
| |
| // TexImage3D() depth case. |
| class TexImageCubeArrayDepthCase : public TextureCubeArraySpecCase |
| { |
| public: |
| TexImageCubeArrayDepthCase(Context &context, const char *name, const char *desc, uint32_t internalFormat, |
| int imageSize, int numLayers) |
| : TextureCubeArraySpecCase(context, name, desc, glu::mapGLInternalFormat(internalFormat), imageSize, numLayers, |
| maxLevelCount(imageSize)) |
| , m_internalFormat(internalFormat) |
| { |
| // we are interested in the behavior near [-2, 2], map it to visible range [0, 1] |
| m_texFormatInfo.lookupBias = Vec4(0.25f, 0.0f, 0.0f, 1.0f); |
| m_texFormatInfo.lookupScale = Vec4(0.5f, 1.0f, 1.0f, 0.0f); |
| } |
| |
| void createTexture(void) |
| { |
| glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat); |
| uint32_t tex = 0; |
| tcu::TextureLevel levelData(glu::mapGLTransferFormat(fmt.format, fmt.dataType)); |
| |
| glGenTextures(1, &tex); |
| glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, tex); |
| glPixelStorei(GL_UNPACK_ALIGNMENT, 1); |
| GLU_CHECK(); |
| |
| for (int ndx = 0; ndx < m_numLevels; ndx++) |
| { |
| const int levelW = de::max(1, m_size >> ndx); |
| const Vec4 gMin = Vec4(-1.5f, -2.0f, 1.7f, -1.5f); |
| const Vec4 gMax = Vec4(2.0f, 1.5f, -1.0f, 2.0f); |
| |
| levelData.setSize(levelW, levelW, m_depth); |
| tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax); |
| |
| glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, ndx, m_internalFormat, levelW, levelW, m_depth, 0, fmt.format, |
| fmt.dataType, levelData.getAccess().getDataPtr()); |
| } |
| } |
| |
| const uint32_t m_internalFormat; |
| }; |
| |
| // TexSubImage3D() depth case. |
| class TexSubImageCubeArrayDepthCase : public TextureCubeArraySpecCase |
| { |
| public: |
| TexSubImageCubeArrayDepthCase(Context &context, const char *name, const char *desc, uint32_t internalFormat, |
| int imageSize, int numLayers) |
| : TextureCubeArraySpecCase(context, name, desc, glu::mapGLInternalFormat(internalFormat), imageSize, numLayers, |
| maxLevelCount(imageSize)) |
| , m_internalFormat(internalFormat) |
| { |
| // we are interested in the behavior near [-2, 2], map it to visible range [0, 1] |
| m_texFormatInfo.lookupBias = Vec4(0.25f, 0.0f, 0.0f, 1.0f); |
| m_texFormatInfo.lookupScale = Vec4(0.5f, 1.0f, 1.0f, 0.0f); |
| } |
| |
| void createTexture(void) |
| { |
| glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat); |
| de::Random rnd(deStringHash(getName())); |
| uint32_t tex = 0; |
| tcu::TextureLevel levelData(glu::mapGLTransferFormat(fmt.format, fmt.dataType)); |
| |
| glGenTextures(1, &tex); |
| glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, tex); |
| glPixelStorei(GL_UNPACK_ALIGNMENT, 1); |
| GLU_CHECK(); |
| |
| // First specify full texture. |
| for (int ndx = 0; ndx < m_numLevels; ndx++) |
| { |
| const int levelW = de::max(1, m_size >> ndx); |
| const Vec4 gMin = Vec4(-1.5f, -2.0f, 1.7f, -1.5f); |
| const Vec4 gMax = Vec4(2.0f, 1.5f, -1.0f, 2.0f); |
| |
| levelData.setSize(levelW, levelW, m_depth); |
| tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax); |
| |
| glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, ndx, m_internalFormat, levelW, levelW, m_depth, 0, fmt.format, |
| fmt.dataType, levelData.getAccess().getDataPtr()); |
| } |
| |
| // Re-specify parts of each level. |
| for (int ndx = 0; ndx < m_numLevels; ndx++) |
| { |
| const int levelW = de::max(1, m_size >> ndx); |
| |
| const int w = rnd.getInt(1, levelW); |
| const int h = rnd.getInt(1, levelW); |
| const int d = rnd.getInt(1, m_depth); |
| const int x = rnd.getInt(0, levelW - w); |
| const int y = rnd.getInt(0, levelW - h); |
| const int z = rnd.getInt(0, m_depth - d); |
| |
| const Vec4 colorA = Vec4(2.0f, 1.5f, -1.0f, 2.0f); |
| const Vec4 colorB = Vec4(-1.5f, -2.0f, 1.7f, -1.5f); |
| const int cellSize = rnd.getInt(2, 16); |
| |
| levelData.setSize(w, h, d); |
| tcu::fillWithGrid(levelData.getAccess(), cellSize, colorA, colorB); |
| |
| glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, ndx, x, y, z, w, h, d, fmt.format, fmt.dataType, |
| levelData.getAccess().getDataPtr()); |
| } |
| } |
| |
| const uint32_t m_internalFormat; |
| }; |
| |
| // TexImage3D() depth case with pbo. |
| class TexImageCubeArrayDepthBufferCase : public TextureCubeArraySpecCase |
| { |
| public: |
| TexImageCubeArrayDepthBufferCase(Context &context, const char *name, const char *desc, uint32_t internalFormat, |
| int imageSize, int numLayers) |
| : TextureCubeArraySpecCase(context, name, desc, glu::mapGLInternalFormat(internalFormat), imageSize, numLayers, |
| 1) |
| , m_internalFormat(internalFormat) |
| { |
| // we are interested in the behavior near [-2, 2], map it to visible range [0, 1] |
| m_texFormatInfo.lookupBias = Vec4(0.25f, 0.0f, 0.0f, 1.0f); |
| m_texFormatInfo.lookupScale = Vec4(0.5f, 1.0f, 1.0f, 0.0f); |
| } |
| |
| void createTexture(void) |
| { |
| glu::TransferFormat transferFmt = glu::getTransferFormat(m_texFormat); |
| int pixelSize = m_texFormat.getPixelSize(); |
| int rowLength = m_size; |
| int alignment = 4; |
| int rowPitch = deAlign32(rowLength * pixelSize, alignment); |
| int imageHeight = m_size; |
| int slicePitch = imageHeight * rowPitch; |
| uint32_t tex = 0; |
| uint32_t buf = 0; |
| vector<uint8_t> data; |
| |
| DE_ASSERT(m_numLevels == 1); |
| |
| // Fill data with grid. |
| data.resize(slicePitch * m_depth); |
| { |
| const Vec4 gMin = Vec4(-1.5f, -2.0f, 1.7f, -1.5f); |
| const Vec4 gMax = Vec4(2.0f, 1.5f, -1.0f, 2.0f); |
| |
| tcu::fillWithComponentGradients( |
| tcu::PixelBufferAccess(m_texFormat, m_size, m_size, m_depth, rowPitch, slicePitch, &data[0]), gMin, |
| gMax); |
| } |
| |
| glGenBuffers(1, &buf); |
| glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf); |
| glBufferData(GL_PIXEL_UNPACK_BUFFER, (int)data.size(), &data[0], GL_STATIC_DRAW); |
| |
| glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, imageHeight); |
| glPixelStorei(GL_UNPACK_ROW_LENGTH, rowLength); |
| glPixelStorei(GL_UNPACK_SKIP_IMAGES, 0); |
| glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); |
| glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); |
| glPixelStorei(GL_UNPACK_ALIGNMENT, alignment); |
| |
| glGenTextures(1, &tex); |
| glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, tex); |
| glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, m_internalFormat, m_size, m_size, m_depth, 0, transferFmt.format, |
| transferFmt.dataType, DE_NULL); |
| glDeleteBuffers(1, &buf); |
| } |
| |
| const uint32_t m_internalFormat; |
| }; |
| |
| TextureSpecificationTests::TextureSpecificationTests(Context &context) |
| : TestCaseGroup(context, "specification", "Texture Specification Tests") |
| { |
| } |
| |
| TextureSpecificationTests::~TextureSpecificationTests(void) |
| { |
| } |
| |
| void TextureSpecificationTests::init(void) |
| { |
| struct |
| { |
| const char *name; |
| uint32_t internalFormat; |
| } colorFormats[] = {{ |
| "rgba32f", |
| GL_RGBA32F, |
| }, |
| { |
| "rgba32i", |
| GL_RGBA32I, |
| }, |
| { |
| "rgba32ui", |
| GL_RGBA32UI, |
| }, |
| { |
| "rgba16f", |
| GL_RGBA16F, |
| }, |
| { |
| "rgba16i", |
| GL_RGBA16I, |
| }, |
| { |
| "rgba16ui", |
| GL_RGBA16UI, |
| }, |
| { |
| "rgba8", |
| GL_RGBA8, |
| }, |
| { |
| "rgba8i", |
| GL_RGBA8I, |
| }, |
| { |
| "rgba8ui", |
| GL_RGBA8UI, |
| }, |
| { |
| "srgb8_alpha8", |
| GL_SRGB8_ALPHA8, |
| }, |
| { |
| "rgb10_a2", |
| GL_RGB10_A2, |
| }, |
| { |
| "rgb10_a2ui", |
| GL_RGB10_A2UI, |
| }, |
| { |
| "rgba4", |
| GL_RGBA4, |
| }, |
| { |
| "rgb5_a1", |
| GL_RGB5_A1, |
| }, |
| { |
| "rgba8_snorm", |
| GL_RGBA8_SNORM, |
| }, |
| { |
| "rgb8", |
| GL_RGB8, |
| }, |
| { |
| "rgb565", |
| GL_RGB565, |
| }, |
| { |
| "r11f_g11f_b10f", |
| GL_R11F_G11F_B10F, |
| }, |
| { |
| "rgb32f", |
| GL_RGB32F, |
| }, |
| { |
| "rgb32i", |
| GL_RGB32I, |
| }, |
| { |
| "rgb32ui", |
| GL_RGB32UI, |
| }, |
| { |
| "rgb16f", |
| GL_RGB16F, |
| }, |
| { |
| "rgb16i", |
| GL_RGB16I, |
| }, |
| { |
| "rgb16ui", |
| GL_RGB16UI, |
| }, |
| { |
| "rgb8_snorm", |
| GL_RGB8_SNORM, |
| }, |
| { |
| "rgb8i", |
| GL_RGB8I, |
| }, |
| { |
| "rgb8ui", |
| GL_RGB8UI, |
| }, |
| { |
| "srgb8", |
| GL_SRGB8, |
| }, |
| { |
| "rgb9_e5", |
| GL_RGB9_E5, |
| }, |
| { |
| "rg32f", |
| GL_RG32F, |
| }, |
| { |
| "rg32i", |
| GL_RG32I, |
| }, |
| { |
| "rg32ui", |
| GL_RG32UI, |
| }, |
| { |
| "rg16f", |
| GL_RG16F, |
| }, |
| { |
| "rg16i", |
| GL_RG16I, |
| }, |
| { |
| "rg16ui", |
| GL_RG16UI, |
| }, |
| { |
| "rg8", |
| GL_RG8, |
| }, |
| { |
| "rg8i", |
| GL_RG8I, |
| }, |
| { |
| "rg8ui", |
| GL_RG8UI, |
| }, |
| { |
| "rg8_snorm", |
| GL_RG8_SNORM, |
| }, |
| { |
| "r32f", |
| GL_R32F, |
| }, |
| { |
| "r32i", |
| GL_R32I, |
| }, |
| { |
| "r32ui", |
| GL_R32UI, |
| }, |
| { |
| "r16f", |
| GL_R16F, |
| }, |
| { |
| "r16i", |
| GL_R16I, |
| }, |
| { |
| "r16ui", |
| GL_R16UI, |
| }, |
| { |
| "r8", |
| GL_R8, |
| }, |
| { |
| "r8i", |
| GL_R8I, |
| }, |
| { |
| "r8ui", |
| GL_R8UI, |
| }, |
| { |
| "r8_snorm", |
| GL_R8_SNORM, |
| }}; |
| |
| static const struct |
| { |
| const char *name; |
| uint32_t internalFormat; |
| } depthStencilFormats[] = {// Depth and stencil formats |
| {"depth_component32f", GL_DEPTH_COMPONENT32F}, |
| {"depth_component24", GL_DEPTH_COMPONENT24}, |
| {"depth_component16", GL_DEPTH_COMPONENT16}, |
| {"depth32f_stencil8", GL_DEPTH32F_STENCIL8}, |
| {"depth24_stencil8", GL_DEPTH24_STENCIL8}}; |
| |
| // Basic TexImage3D usage. |
| { |
| tcu::TestCaseGroup *basicTexImageGroup = |
| new tcu::TestCaseGroup(m_testCtx, "basic_teximage3d", "Basic glTexImage3D() usage"); |
| addChild(basicTexImageGroup); |
| for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++) |
| { |
| const char *fmtName = colorFormats[formatNdx].name; |
| uint32_t format = colorFormats[formatNdx].internalFormat; |
| const int texCubeArraySize = 64; |
| const int texCubeArrayLayers = 6; |
| |
| basicTexImageGroup->addChild(new BasicTexImageCubeArrayCase(m_context, |
| (string(fmtName) + "_cube_array").c_str(), "", |
| format, texCubeArraySize, texCubeArrayLayers)); |
| } |
| } |
| |
| // glTexImage3D() pbo cases. |
| { |
| tcu::TestCaseGroup *pboGroup = new tcu::TestCaseGroup(m_testCtx, "teximage3d_pbo", "glTexImage3D() from PBO"); |
| addChild(pboGroup); |
| |
| // Parameter cases |
| static const struct |
| { |
| const char *name; |
| uint32_t format; |
| int size; |
| int depth; |
| int imageHeight; |
| int rowLength; |
| int skipImages; |
| int skipRows; |
| int skipPixels; |
| int alignment; |
| int offset; |
| } parameterCases[] = {{"rgb8_offset", GL_RGB8, 23, 6, 0, 0, 0, 0, 0, 1, 67}, |
| {"rgb8_alignment", GL_RGB8, 23, 6, 0, 0, 0, 0, 0, 2, 0}, |
| {"rgb8_image_height", GL_RGB8, 23, 6, 26, 0, 0, 0, 0, 4, 0}, |
| {"rgb8_row_length", GL_RGB8, 23, 6, 0, 27, 0, 0, 0, 4, 0}, |
| {"rgb8_skip_images", GL_RGB8, 23, 6, 0, 0, 3, 0, 0, 4, 0}, |
| {"rgb8_skip_rows", GL_RGB8, 23, 6, 26, 0, 0, 3, 0, 4, 0}, |
| {"rgb8_skip_pixels", GL_RGB8, 23, 6, 0, 25, 0, 0, 2, 4, 0}}; |
| |
| for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++) |
| { |
| const string fmtName = colorFormats[formatNdx].name; |
| const uint32_t format = colorFormats[formatNdx].internalFormat; |
| const int texCubeArraySize = 20; |
| const int texCubeDepth = 6; |
| |
| pboGroup->addChild(new TexImageCubeArrayBufferCase(m_context, (fmtName + "_cube_array").c_str(), "", format, |
| texCubeArraySize, texCubeDepth, 0, 0, 0, 0, 0, 4, 0)); |
| } |
| |
| for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(parameterCases); ndx++) |
| { |
| pboGroup->addChild(new TexImageCubeArrayBufferCase( |
| m_context, (string(parameterCases[ndx].name) + "_cube_array").c_str(), "", parameterCases[ndx].format, |
| parameterCases[ndx].size, parameterCases[ndx].depth, parameterCases[ndx].imageHeight, |
| parameterCases[ndx].rowLength, parameterCases[ndx].skipImages, parameterCases[ndx].skipRows, |
| parameterCases[ndx].skipPixels, parameterCases[ndx].alignment, parameterCases[ndx].offset)); |
| } |
| } |
| |
| // glTexImage3D() depth cases. |
| { |
| tcu::TestCaseGroup *shadow3dGroup = |
| new tcu::TestCaseGroup(m_testCtx, "teximage3d_depth", "glTexImage3D() with depth or depth/stencil format"); |
| addChild(shadow3dGroup); |
| |
| for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++) |
| { |
| const int texCubeArraySize = 64; |
| const int texCubeArrayDepth = 6; |
| |
| shadow3dGroup->addChild(new TexImageCubeArrayDepthCase( |
| m_context, (std::string(depthStencilFormats[ndx].name) + "_cube_array").c_str(), "", |
| depthStencilFormats[ndx].internalFormat, texCubeArraySize, texCubeArrayDepth)); |
| } |
| } |
| |
| // glTexImage3D() depth cases with pbo. |
| { |
| tcu::TestCaseGroup *shadow3dGroup = new tcu::TestCaseGroup( |
| m_testCtx, "teximage3d_depth_pbo", "glTexImage3D() with depth or depth/stencil format with pbo"); |
| addChild(shadow3dGroup); |
| |
| for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++) |
| { |
| const int texCubeArraySize = 64; |
| const int texCubeArrayDepth = 6; |
| |
| shadow3dGroup->addChild(new TexImageCubeArrayDepthBufferCase( |
| m_context, (std::string(depthStencilFormats[ndx].name) + "_cube_array").c_str(), "", |
| depthStencilFormats[ndx].internalFormat, texCubeArraySize, texCubeArrayDepth)); |
| } |
| } |
| |
| // glTexSubImage3D() PBO cases. |
| { |
| tcu::TestCaseGroup *pboGroup = |
| new tcu::TestCaseGroup(m_testCtx, "texsubimage3d_pbo", "glTexSubImage3D() pixel buffer object tests"); |
| addChild(pboGroup); |
| |
| static const struct |
| { |
| const char *name; |
| uint32_t format; |
| 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; |
| } paramCases[] = {{"rgb8_offset", GL_RGB8, 26, 12, 1, 2, 1, 23, 19, 8, 0, 0, 0, 0, 0, 4, 67}, |
| {"rgb8_image_height", GL_RGB8, 26, 12, 1, 2, 1, 23, 19, 8, 26, 0, 0, 0, 0, 4, 0}, |
| {"rgb8_row_length", GL_RGB8, 26, 12, 1, 2, 1, 23, 19, 8, 0, 27, 0, 0, 0, 4, 0}, |
| {"rgb8_skip_images", GL_RGB8, 26, 12, 1, 2, 1, 23, 19, 8, 0, 0, 3, 0, 0, 4, 0}, |
| {"rgb8_skip_rows", GL_RGB8, 26, 12, 1, 2, 1, 23, 19, 8, 22, 0, 0, 3, 0, 4, 0}, |
| {"rgb8_skip_pixels", GL_RGB8, 26, 12, 1, 2, 1, 23, 19, 8, 0, 25, 0, 0, 2, 4, 0}}; |
| |
| for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(colorFormats); ndx++) |
| { |
| pboGroup->addChild(new TexSubImageCubeArrayBufferCase( |
| m_context, (std::string(colorFormats[ndx].name) + "_cube_array").c_str(), "", |
| colorFormats[ndx].internalFormat, |
| 26, // Size |
| 12, // Depth |
| 1, // Sub X |
| 2, // Sub Y |
| 0, // Sub Z |
| 23, // Sub W |
| 19, // Sub H |
| 8, // Sub D |
| 0, // Image height |
| 0, // Row length |
| 0, // Skip images |
| 0, // Skip rows |
| 0, // Skip pixels |
| 4, // Alignment |
| 0 /* offset */)); |
| } |
| |
| for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(paramCases); ndx++) |
| { |
| pboGroup->addChild(new TexSubImageCubeArrayBufferCase( |
| m_context, (std::string(paramCases[ndx].name) + "_cube_array").c_str(), "", paramCases[ndx].format, |
| paramCases[ndx].size, paramCases[ndx].depth, paramCases[ndx].subX, paramCases[ndx].subY, |
| paramCases[ndx].subZ, paramCases[ndx].subW, paramCases[ndx].subH, paramCases[ndx].subD, |
| paramCases[ndx].imageHeight, paramCases[ndx].rowLength, paramCases[ndx].skipImages, |
| paramCases[ndx].skipRows, paramCases[ndx].skipPixels, paramCases[ndx].alignment, |
| paramCases[ndx].offset)); |
| } |
| } |
| |
| // glTexSubImage3D() depth cases. |
| { |
| tcu::TestCaseGroup *shadow3dGroup = new tcu::TestCaseGroup( |
| m_testCtx, "texsubimage3d_depth", "glTexSubImage3D() with depth or depth/stencil format"); |
| addChild(shadow3dGroup); |
| |
| for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++) |
| { |
| const int texCubeArraySize = 57; |
| const int texCubeArrayLayers = 6; |
| |
| shadow3dGroup->addChild(new TexSubImageCubeArrayDepthCase( |
| m_context, (std::string(depthStencilFormats[ndx].name) + "_cube_array").c_str(), "", |
| depthStencilFormats[ndx].internalFormat, texCubeArraySize, texCubeArrayLayers)); |
| } |
| } |
| |
| // glTexStorage3D() cases. |
| { |
| tcu::TestCaseGroup *texStorageGroup = |
| new tcu::TestCaseGroup(m_testCtx, "texstorage3d", "Basic glTexStorage3D() usage"); |
| addChild(texStorageGroup); |
| |
| // All formats. |
| tcu::TestCaseGroup *formatGroup = |
| new tcu::TestCaseGroup(m_testCtx, "format", "glTexStorage3D() with all formats"); |
| texStorageGroup->addChild(formatGroup); |
| |
| // Color formats. |
| for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++) |
| { |
| const char *fmtName = colorFormats[formatNdx].name; |
| uint32_t internalFormat = colorFormats[formatNdx].internalFormat; |
| const int texCubeArraySize = 57; |
| const int texCubeArrayLayers = 6; |
| int texCubeArrayLevels = maxLevelCount(texCubeArraySize); |
| |
| formatGroup->addChild(new BasicTexStorageCubeArrayCase(m_context, (string(fmtName) + "_cube_array").c_str(), |
| "", internalFormat, texCubeArraySize, |
| texCubeArrayLayers, texCubeArrayLevels)); |
| } |
| |
| // Depth/stencil formats (only 2D texture array is supported). |
| for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(depthStencilFormats); formatNdx++) |
| { |
| const char *fmtName = depthStencilFormats[formatNdx].name; |
| uint32_t internalFormat = depthStencilFormats[formatNdx].internalFormat; |
| const int texCubeArraySize = 57; |
| const int texCubeArrayLayers = 6; |
| int texCubeArrayLevels = maxLevelCount(texCubeArraySize); |
| |
| formatGroup->addChild(new BasicTexStorageCubeArrayCase(m_context, (string(fmtName) + "_cube_array").c_str(), |
| "", internalFormat, texCubeArraySize, |
| texCubeArrayLayers, texCubeArrayLevels)); |
| } |
| |
| // Sizes. |
| static const struct |
| { |
| int size; |
| int layers; |
| int levels; |
| } texCubeArraySizes[] = {// Sz La Le |
| {1, 6, 1}, {2, 6, 2}, {32, 6, 3}, {64, 6, 4}, {57, 12, 1}, {57, 12, 2}, {57, 12, 6}}; |
| |
| tcu::TestCaseGroup *sizeGroup = |
| new tcu::TestCaseGroup(m_testCtx, "size", "glTexStorage3D() with various sizes"); |
| texStorageGroup->addChild(sizeGroup); |
| |
| for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(texCubeArraySizes); ndx++) |
| { |
| const uint32_t format = GL_RGBA8; |
| int size = texCubeArraySizes[ndx].size; |
| int layers = texCubeArraySizes[ndx].layers; |
| int levels = texCubeArraySizes[ndx].levels; |
| string name = string("cube_array_") + de::toString(size) + "x" + de::toString(size) + "x" + |
| de::toString(layers) + "_" + de::toString(levels) + "_levels"; |
| |
| sizeGroup->addChild( |
| new BasicTexStorageCubeArrayCase(m_context, name.c_str(), "", format, size, layers, levels)); |
| } |
| } |
| } |
| |
| } // namespace Functional |
| } // namespace gles31 |
| } // namespace deqp |