/*------------------------------------------------------------------------- * 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 "es3fTextureSpecificationTests.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 "es3fFboTestUtil.hpp" #include "glwEnums.hpp" namespace deqp { namespace gles3 { namespace Functional { using std::string; using std::vector; using std::pair; using tcu::TestLog; using tcu::Vec4; using tcu::IVec4; using tcu::UVec4; using namespace FboTestUtil; tcu::TextureFormat mapGLUnsizedInternalFormat (deUint32 internalFormat) { using tcu::TextureFormat; switch (internalFormat) { case GL_ALPHA: return TextureFormat(TextureFormat::A, TextureFormat::UNORM_INT8); case GL_LUMINANCE: return TextureFormat(TextureFormat::L, TextureFormat::UNORM_INT8); case GL_LUMINANCE_ALPHA: return TextureFormat(TextureFormat::LA, TextureFormat::UNORM_INT8); case GL_RGB: return TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8); case GL_RGBA: return TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8); default: throw tcu::InternalError(string("Can't map GL unsized internal format (") + tcu::toHex(internalFormat).toString() + ") to texture format"); } } enum { VIEWPORT_WIDTH = 256, VIEWPORT_HEIGHT = 256 }; static inline int maxLevelCount (int width, int height) { return (int)deLog2Floor32(de::max(width, height))+1; } static inline int maxLevelCount (int width, int height, int depth) { return (int)deLog2Floor32(de::max(width, de::max(height, depth)))+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 const deUint32 s_cubeMapFaces[] = { GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, }; static tcu::IVec4 getPixelFormatCompareDepth (const tcu::PixelFormat& pixelFormat, tcu::TextureFormat textureFormat) { switch (textureFormat.order) { case tcu::TextureFormat::L: case tcu::TextureFormat::LA: return tcu::IVec4(pixelFormat.redBits, pixelFormat.redBits, pixelFormat.redBits, pixelFormat.alphaBits); default: return tcu::IVec4(pixelFormat.redBits, pixelFormat.greenBits, pixelFormat.blueBits, pixelFormat.alphaBits); } } static IVec4 getEffectiveTextureFormatBitDepth (tcu::TextureFormat textureFormat) { if (textureFormat.order == tcu::TextureFormat::DS) { // When sampling depth-stencil texture, we actually sample just // the depth component. return tcu::getTextureFormatBitDepth(tcu::getEffectiveDepthStencilTextureFormat(textureFormat, tcu::Sampler::MODE_DEPTH)); } else return tcu::getTextureFormatBitDepth(textureFormat); } static tcu::UVec4 computeCompareThreshold (const tcu::PixelFormat& pixelFormat, tcu::TextureFormat textureFormat) { const IVec4 texFormatBits = getEffectiveTextureFormatBitDepth(textureFormat); const IVec4 pixelFormatBits = getPixelFormatCompareDepth(pixelFormat, textureFormat); const IVec4 accurateFmtBits = min(pixelFormatBits, texFormatBits); const IVec4 compareBits = select(accurateFmtBits, IVec4(8), greaterThan(accurateFmtBits, IVec4(0))) - 1; return (IVec4(1) << (8-compareBits)).asUint(); } class TextureSpecCase : public TestCase, public sglr::ContextWrapper { public: TextureSpecCase (Context& context, const char* name, const char* desc); ~TextureSpecCase (void); IterateResult iterate (void); protected: virtual void createTexture (void) = DE_NULL; virtual void verifyTexture (sglr::GLContext& gles3Context, sglr::ReferenceContext& refContext) = DE_NULL; // Utilities. void renderTex (tcu::Surface& dst, deUint32 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__); // Context size, and viewport for GLES3 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 gles3Context (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*)&gles3Context); 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 and reference contexts. for (int ndx = 0; ndx < 2; ndx++) { setContext(ndx ? (sglr::Context*)&refContext : (sglr::Context*)&gles3Context); createTexture(); TCU_CHECK(glGetError() == GL_NO_ERROR); } // Initialize case result to pass. m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); // Disable logging. gles3Context.enableLogging(0); // Verify results. verifyTexture(gles3Context, refContext); return STOP; } void TextureSpecCase::renderTex (tcu::Surface& dst, deUint32 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 Texture2DSpecCase : public TextureSpecCase { public: Texture2DSpecCase (Context& context, const char* name, const char* desc, const tcu::TextureFormat& format, int width, int height, int numLevels); ~Texture2DSpecCase (void); protected: virtual void verifyTexture (sglr::GLContext& gles3Context, sglr::ReferenceContext& refContext); tcu::TextureFormat m_texFormat; tcu::TextureFormatInfo m_texFormatInfo; int m_width; int m_height; int m_numLevels; }; Texture2DSpecCase::Texture2DSpecCase (Context& context, const char* name, const char* desc, const tcu::TextureFormat& format, int width, int height, int numLevels) : TextureSpecCase (context, name, desc) , m_texFormat (format) , m_texFormatInfo (tcu::getTextureFormatInfo(format)) , m_width (width) , m_height (height) , m_numLevels (numLevels) { } Texture2DSpecCase::~Texture2DSpecCase (void) { } void Texture2DSpecCase::verifyTexture (sglr::GLContext& gles3Context, sglr::ReferenceContext& refContext) { Texture2DShader shader (DataTypes() << glu::getSampler2DType(m_texFormat), glu::TYPE_FLOAT_VEC4); deUint32 shaderIDgles = gles3Context.createProgram(&shader); deUint32 shaderIDRef = refContext.createProgram(&shader); shader.setTexScaleBias(0, 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_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, m_numLevels-1); } for (int levelNdx = 0; levelNdx < m_numLevels; levelNdx++) { int levelW = de::max(1, m_width >> levelNdx); int levelH = de::max(1, m_height >> levelNdx); tcu::Surface reference; tcu::Surface result; 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); deUint32 shaderID = ndx ? shaderIDRef : shaderIDgles; setContext(ctx); shader.setUniforms(*ctx, shaderID); renderTex(dst, shaderID, levelW, levelH); } UVec4 threshold = computeCompareThreshold(m_context.getRenderTarget().getPixelFormat(), m_texFormat); string levelStr = de::toString(levelNdx); string name = string("Level") + levelStr; string desc = string("Level ") + levelStr; bool isOk = tcu::intThresholdCompare(m_testCtx.getLog(), name.c_str(), desc.c_str(), reference.getAccess(), result.getAccess(), threshold, levelNdx == 0 ? tcu::COMPARE_LOG_RESULT : tcu::COMPARE_LOG_ON_ERROR); if (!isOk) { m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed"); break; } } } class TextureCubeSpecCase : public TextureSpecCase { public: TextureCubeSpecCase (Context& context, const char* name, const char* desc, const tcu::TextureFormat& format, int size, int numLevels); ~TextureCubeSpecCase (void); protected: virtual void verifyTexture (sglr::GLContext& gles3Context, sglr::ReferenceContext& refContext); tcu::TextureFormat m_texFormat; tcu::TextureFormatInfo m_texFormatInfo; int m_size; int m_numLevels; }; TextureCubeSpecCase::TextureCubeSpecCase (Context& context, const char* name, const char* desc, const tcu::TextureFormat& format, int size, int numLevels) : TextureSpecCase (context, name, desc) , m_texFormat (format) , m_texFormatInfo (tcu::getTextureFormatInfo(format)) , m_size (size) , m_numLevels (numLevels) { } TextureCubeSpecCase::~TextureCubeSpecCase (void) { } void TextureCubeSpecCase::verifyTexture (sglr::GLContext& gles3Context, sglr::ReferenceContext& refContext) { TextureCubeShader shader (glu::getSamplerCubeType(m_texFormat), glu::TYPE_FLOAT_VEC4); deUint32 shaderIDgles = gles3Context.createProgram(&shader); deUint32 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, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, m_numLevels-1); } for (int levelNdx = 0; levelNdx < m_numLevels; levelNdx++) { int levelSize = de::max(1, m_size >> levelNdx); bool isOk = true; for (int face = 0; face < tcu::CUBEFACE_LAST; face++) { tcu::Surface reference; tcu::Surface result; if (levelSize <= 2) continue; // Fuzzy compare doesn't work for images this small. shader.setFace((tcu::CubeFace)face); 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); deUint32 shaderID = ndx ? shaderIDRef : shaderIDgles; setContext(ctx); shader.setUniforms(*ctx, shaderID); renderTex(dst, shaderID, levelSize, levelSize); } const float threshold = 0.02f; string faceStr = de::toString((tcu::CubeFace)face); string levelStr = de::toString(levelNdx); string name = string("Level") + levelStr; string desc = string("Level ") + levelStr + ", face " + faceStr; bool isFaceOk = tcu::fuzzyCompare(m_testCtx.getLog(), name.c_str(), desc.c_str(), reference, result, threshold, levelNdx == 0 ? tcu::COMPARE_LOG_RESULT : tcu::COMPARE_LOG_ON_ERROR); if (!isFaceOk) { m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed"); isOk = false; break; } } if (!isOk) break; } } class Texture2DArraySpecCase : public TextureSpecCase { public: Texture2DArraySpecCase (Context& context, const char* name, const char* desc, const tcu::TextureFormat& format, int width, int height, int numLayers, int numLevels); ~Texture2DArraySpecCase (void); protected: virtual void verifyTexture (sglr::GLContext& gles3Context, sglr::ReferenceContext& refContext); tcu::TextureFormat m_texFormat; tcu::TextureFormatInfo m_texFormatInfo; int m_width; int m_height; int m_numLayers; int m_numLevels; }; Texture2DArraySpecCase::Texture2DArraySpecCase (Context& context, const char* name, const char* desc, const tcu::TextureFormat& format, int width, int height, int numLayers, int numLevels) : TextureSpecCase (context, name, desc) , m_texFormat (format) , m_texFormatInfo (tcu::getTextureFormatInfo(format)) , m_width (width) , m_height (height) , m_numLayers (numLayers) , m_numLevels (numLevels) { } Texture2DArraySpecCase::~Texture2DArraySpecCase (void) { } void Texture2DArraySpecCase::verifyTexture (sglr::GLContext& gles3Context, sglr::ReferenceContext& refContext) { Texture2DArrayShader shader (glu::getSampler2DArrayType(m_texFormat), glu::TYPE_FLOAT_VEC4); deUint32 shaderIDgles = gles3Context.createProgram(&shader); deUint32 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_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, m_numLevels-1); } for (int layerNdx = 0; layerNdx < m_numLayers; layerNdx++) { bool layerOk = true; shader.setLayer(layerNdx); for (int levelNdx = 0; levelNdx < m_numLevels; levelNdx++) { int levelW = de::max(1, m_width >> levelNdx); int levelH = de::max(1, m_height >> levelNdx); tcu::Surface reference; tcu::Surface result; 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); deUint32 shaderID = ndx ? shaderIDRef : shaderIDgles; setContext(ctx); shader.setUniforms(*ctx, shaderID); renderTex(dst, shaderID, levelW, levelH); } UVec4 threshold = computeCompareThreshold(m_context.getRenderTarget().getPixelFormat(), m_texFormat); string levelStr = de::toString(levelNdx); string layerStr = de::toString(layerNdx); string name = string("Layer") + layerStr + "Level" + levelStr; string desc = string("Layer ") + layerStr + ", Level " + levelStr; bool depthOk = tcu::intThresholdCompare(m_testCtx.getLog(), name.c_str(), desc.c_str(), reference.getAccess(), result.getAccess(), threshold, (levelNdx == 0 && layerNdx == 0) ? tcu::COMPARE_LOG_RESULT : tcu::COMPARE_LOG_ON_ERROR); if (!depthOk) { m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed"); layerOk = false; break; } } if (!layerOk) break; } } class Texture3DSpecCase : public TextureSpecCase { public: Texture3DSpecCase (Context& context, const char* name, const char* desc, const tcu::TextureFormat& format, int width, int height, int depth, int numLevels); ~Texture3DSpecCase (void); protected: virtual void verifyTexture (sglr::GLContext& gles3Context, sglr::ReferenceContext& refContext); tcu::TextureFormat m_texFormat; tcu::TextureFormatInfo m_texFormatInfo; int m_width; int m_height; int m_depth; int m_numLevels; }; Texture3DSpecCase::Texture3DSpecCase (Context& context, const char* name, const char* desc, const tcu::TextureFormat& format, int width, int height, int depth, int numLevels) : TextureSpecCase (context, name, desc) , m_texFormat (format) , m_texFormatInfo (tcu::getTextureFormatInfo(format)) , m_width (width) , m_height (height) , m_depth (depth) , m_numLevels (numLevels) { } Texture3DSpecCase::~Texture3DSpecCase (void) { } void Texture3DSpecCase::verifyTexture (sglr::GLContext& gles3Context, sglr::ReferenceContext& refContext) { Texture3DShader shader (glu::getSampler3DType(m_texFormat), glu::TYPE_FLOAT_VEC4); deUint32 shaderIDgles = gles3Context.createProgram(&shader); deUint32 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_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, m_numLevels-1); } for (int levelNdx = 0; levelNdx < m_numLevels; levelNdx++) { int levelW = de::max(1, m_width >> levelNdx); int levelH = de::max(1, m_height >> levelNdx); int levelD = de::max(1, m_depth >> levelNdx); bool levelOk = true; for (int depth = 0; depth < levelD; depth++) { tcu::Surface reference; tcu::Surface result; shader.setDepth(((float)depth + 0.5f) / (float)levelD); 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); deUint32 shaderID = ndx ? shaderIDRef : shaderIDgles; setContext(ctx); shader.setUniforms(*ctx, shaderID); renderTex(dst, shaderID, levelW, levelH); } UVec4 threshold = computeCompareThreshold(m_context.getRenderTarget().getPixelFormat(), m_texFormat); string levelStr = de::toString(levelNdx); string sliceStr = de::toString(depth); string name = string("Level") + levelStr + "Slice" + sliceStr; string desc = string("Level ") + levelStr + ", Slice " + sliceStr; bool depthOk = tcu::intThresholdCompare(m_testCtx.getLog(), name.c_str(), desc.c_str(), reference.getAccess(), result.getAccess(), threshold, (levelNdx == 0 && depth == 0) ? tcu::COMPARE_LOG_RESULT : tcu::COMPARE_LOG_ON_ERROR); if (!depthOk) { m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed"); levelOk = false; break; } } if (!levelOk) break; } } // Basic TexImage2D() with 2D texture usage class BasicTexImage2DCase : public Texture2DSpecCase { public: // Unsized internal format. BasicTexImage2DCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int width, int height) : Texture2DSpecCase (context, name, desc, glu::mapGLTransferFormat(format, dataType), width, height, maxLevelCount(width, height)) , m_internalFormat (format) , m_format (format) , m_dataType (dataType) { } // Sized internal format. BasicTexImage2DCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height) : Texture2DSpecCase (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, maxLevelCount(width, height)) , m_internalFormat (internalFormat) , m_format (GL_NONE) , m_dataType (GL_NONE) { glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat); m_format = fmt.format; m_dataType = fmt.dataType; } protected: void createTexture (void) { deUint32 tex = 0; tcu::TextureLevel levelData (m_texFormat); de::Random rnd (deStringHash(getName())); glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); for (int ndx = 0; ndx < m_numLevels; ndx++) { int levelW = de::max(1, m_width >> ndx); int levelH = de::max(1, m_height >> 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, levelH); tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax); glTexImage2D(GL_TEXTURE_2D, ndx, m_internalFormat, levelW, levelH, 0, m_format, m_dataType, levelData.getAccess().getDataPtr()); } } deUint32 m_internalFormat; deUint32 m_format; deUint32 m_dataType; }; // Basic TexImage2D() with cubemap usage class BasicTexImageCubeCase : public TextureCubeSpecCase { public: // Unsized formats. BasicTexImageCubeCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int size) : TextureCubeSpecCase (context, name, desc, glu::mapGLTransferFormat(format, dataType), size, deLog2Floor32(size)+1) , m_internalFormat (format) , m_format (format) , m_dataType (dataType) { } // Sized internal formats. BasicTexImageCubeCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int size) : TextureCubeSpecCase (context, name, desc, glu::mapGLInternalFormat(internalFormat), size, deLog2Floor32(size)+1) , m_internalFormat (internalFormat) , m_format (GL_NONE) , m_dataType (GL_NONE) { glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat); m_format = fmt.format; m_dataType = fmt.dataType; } protected: void createTexture (void) { deUint32 tex = 0; tcu::TextureLevel levelData (m_texFormat); de::Random rnd (deStringHash(getName())); glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_CUBE_MAP, tex); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); for (int ndx = 0; ndx < m_numLevels; ndx++) { int levelSize = de::max(1, m_size >> ndx); levelData.setSize(levelSize, levelSize); for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++) { Vec4 gMin = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax); Vec4 gMax = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax); tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax); glTexImage2D(s_cubeMapFaces[face], ndx, m_internalFormat, levelSize, levelSize, 0, m_format, m_dataType, levelData.getAccess().getDataPtr()); } } } deUint32 m_internalFormat; deUint32 m_format; deUint32 m_dataType; }; // Basic TexImage3D() with 2D array texture usage class BasicTexImage2DArrayCase : public Texture2DArraySpecCase { public: BasicTexImage2DArrayCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height, int numLayers) : Texture2DArraySpecCase (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, numLayers, maxLevelCount(width, height)) , m_internalFormat (internalFormat) { } protected: void createTexture (void) { deUint32 tex = 0; tcu::TextureLevel levelData (m_texFormat); de::Random rnd (deStringHash(getName())); glu::TransferFormat transferFmt = glu::getTransferFormat(m_texFormat); glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D_ARRAY, tex); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); for (int ndx = 0; ndx < m_numLevels; ndx++) { int levelW = de::max(1, m_width >> ndx); int levelH = de::max(1, m_height >> 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, levelH, m_numLayers); tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax); glTexImage3D(GL_TEXTURE_2D_ARRAY, ndx, m_internalFormat, levelW, levelH, m_numLayers, 0, transferFmt.format, transferFmt.dataType, levelData.getAccess().getDataPtr()); } } deUint32 m_internalFormat; }; // Basic TexImage3D() with 3D texture usage class BasicTexImage3DCase : public Texture3DSpecCase { public: BasicTexImage3DCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height, int depth) : Texture3DSpecCase (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, depth, maxLevelCount(width, height, depth)) , m_internalFormat (internalFormat) { } protected: void createTexture (void) { deUint32 tex = 0; tcu::TextureLevel levelData (m_texFormat); de::Random rnd (deStringHash(getName())); glu::TransferFormat transferFmt = glu::getTransferFormat(m_texFormat); glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_3D, tex); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); for (int ndx = 0; ndx < m_numLevels; ndx++) { int levelW = de::max(1, m_width >> ndx); int levelH = de::max(1, m_height >> ndx); int levelD = de::max(1, m_depth >> 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, levelH, levelD); tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax); glTexImage3D(GL_TEXTURE_3D, ndx, m_internalFormat, levelW, levelH, levelD, 0, transferFmt.format, transferFmt.dataType, levelData.getAccess().getDataPtr()); } } deUint32 m_internalFormat; }; // Randomized 2D texture specification using TexImage2D class RandomOrderTexImage2DCase : public Texture2DSpecCase { public: RandomOrderTexImage2DCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int width, int height) : Texture2DSpecCase (context, name, desc, glu::mapGLTransferFormat(format, dataType), width, height, maxLevelCount(width, height)) , m_internalFormat (format) , m_format (format) , m_dataType (dataType) { } RandomOrderTexImage2DCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height) : Texture2DSpecCase (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, maxLevelCount(width, height)) , m_internalFormat (internalFormat) , m_format (GL_NONE) , m_dataType (GL_NONE) { glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat); m_format = fmt.format; m_dataType = fmt.dataType; } protected: void createTexture (void) { deUint32 tex = 0; tcu::TextureLevel levelData (m_texFormat); de::Random rnd (deStringHash(getName())); glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); vector<int> levels (m_numLevels); for (int i = 0; i < m_numLevels; i++) levels[i] = i; rnd.shuffle(levels.begin(), levels.end()); for (int ndx = 0; ndx < m_numLevels; ndx++) { int levelNdx = levels[ndx]; int levelW = de::max(1, m_width >> levelNdx); int levelH = de::max(1, m_height >> levelNdx); 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, levelH); tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax); glTexImage2D(GL_TEXTURE_2D, levelNdx, m_internalFormat, levelW, levelH, 0, m_format, m_dataType, levelData.getAccess().getDataPtr()); } } deUint32 m_internalFormat; deUint32 m_format; deUint32 m_dataType; }; // Randomized cubemap texture specification using TexImage2D class RandomOrderTexImageCubeCase : public TextureCubeSpecCase { public: RandomOrderTexImageCubeCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int size) : TextureCubeSpecCase (context, name, desc, glu::mapGLTransferFormat(format, dataType), size, deLog2Floor32(size)+1) , m_internalFormat (GL_NONE) , m_format (format) , m_dataType (dataType) { } RandomOrderTexImageCubeCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int size) : TextureCubeSpecCase (context, name, desc, glu::mapGLInternalFormat(internalFormat), size, deLog2Floor32(size)+1) , m_internalFormat (internalFormat) , m_format (GL_NONE) , m_dataType (GL_NONE) { glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat); m_format = fmt.format; m_dataType = fmt.dataType; } protected: void createTexture (void) { deUint32 tex = 0; tcu::TextureLevel levelData (m_texFormat); de::Random rnd (deStringHash(getName())); glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_CUBE_MAP, tex); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // Level-face pairs. vector<pair<int, tcu::CubeFace> > images (m_numLevels*6); for (int ndx = 0; ndx < m_numLevels; ndx++) for (int face = 0; face < tcu::CUBEFACE_LAST; face++) images[ndx*6 + face] = std::make_pair(ndx, (tcu::CubeFace)face); rnd.shuffle(images.begin(), images.end()); for (int ndx = 0; ndx < (int)images.size(); ndx++) { int levelNdx = images[ndx].first; tcu::CubeFace face = images[ndx].second; int levelSize = de::max(1, m_size >> levelNdx); Vec4 gMin = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax); Vec4 gMax = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax); levelData.setSize(levelSize, levelSize); tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax); glTexImage2D(s_cubeMapFaces[face], levelNdx, m_internalFormat, levelSize, levelSize, 0, m_format, m_dataType, levelData.getAccess().getDataPtr()); } } deUint32 m_internalFormat; deUint32 m_format; deUint32 m_dataType; }; // TexImage2D() unpack alignment case. class TexImage2DAlignCase : public Texture2DSpecCase { public: TexImage2DAlignCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int width, int height, int numLevels, int alignment) : Texture2DSpecCase (context, name, desc, glu::mapGLTransferFormat(format, dataType), width, height, numLevels) , m_internalFormat (format) , m_format (format) , m_dataType (dataType) , m_alignment (alignment) { } TexImage2DAlignCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height, int numLevels, int alignment) : Texture2DSpecCase (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, numLevels) , m_internalFormat (internalFormat) , m_format (GL_NONE) , m_dataType (GL_NONE) , m_alignment (alignment) { glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat); m_format = fmt.format; m_dataType = fmt.dataType; } protected: void createTexture (void) { deUint32 tex = 0; vector<deUint8> data; glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); glPixelStorei(GL_UNPACK_ALIGNMENT, m_alignment); for (int ndx = 0; ndx < m_numLevels; ndx++) { int levelW = de::max(1, m_width >> ndx); int levelH = de::max(1, m_height >> ndx); Vec4 colorA = Vec4(1.0f, 0.0f, 0.0f, 1.0f)*(m_texFormatInfo.valueMax-m_texFormatInfo.valueMin) + m_texFormatInfo.valueMin; Vec4 colorB = Vec4(0.0f, 1.0f, 0.0f, 1.0f)*(m_texFormatInfo.valueMax-m_texFormatInfo.valueMin) + m_texFormatInfo.valueMin; int rowPitch = deAlign32(levelW*m_texFormat.getPixelSize(), m_alignment); int cellSize = de::max(1, de::min(levelW >> 2, levelH >> 2)); data.resize(rowPitch*levelH); tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, levelW, levelH, 1, rowPitch, 0, &data[0]), cellSize, colorA, colorB); glTexImage2D(GL_TEXTURE_2D, ndx, m_internalFormat, levelW, levelH, 0, m_format, m_dataType, &data[0]); } } deUint32 m_internalFormat; deUint32 m_format; deUint32 m_dataType; int m_alignment; }; // TexImage2D() unpack alignment case. class TexImageCubeAlignCase : public TextureCubeSpecCase { public: TexImageCubeAlignCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int size, int numLevels, int alignment) : TextureCubeSpecCase (context, name, desc, glu::mapGLTransferFormat(format, dataType), size, numLevels) , m_internalFormat (format) , m_format (format) , m_dataType (dataType) , m_alignment (alignment) { } TexImageCubeAlignCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int size, int numLevels, int alignment) : TextureCubeSpecCase (context, name, desc, glu::mapGLInternalFormat(internalFormat), size, numLevels) , m_internalFormat (internalFormat) , m_format (GL_NONE) , m_dataType (GL_NONE) , m_alignment (alignment) { glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat); m_format = fmt.format; m_dataType = fmt.dataType; } protected: void createTexture (void) { deUint32 tex = 0; vector<deUint8> data; glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_CUBE_MAP, tex); glPixelStorei(GL_UNPACK_ALIGNMENT, m_alignment); for (int ndx = 0; ndx < m_numLevels; ndx++) { int levelSize = de::max(1, m_size >> ndx); int rowPitch = deAlign32(m_texFormat.getPixelSize()*levelSize, m_alignment); Vec4 colorA = Vec4(1.0f, 0.0f, 0.0f, 1.0f)*(m_texFormatInfo.valueMax-m_texFormatInfo.valueMin) + m_texFormatInfo.valueMin; Vec4 colorB = Vec4(0.0f, 1.0f, 0.0f, 1.0f)*(m_texFormatInfo.valueMax-m_texFormatInfo.valueMin) + m_texFormatInfo.valueMin; int cellSize = de::max(1, levelSize >> 2); data.resize(rowPitch*levelSize); tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, levelSize, levelSize, 1, rowPitch, 0, &data[0]), cellSize, colorA, colorB); for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++) glTexImage2D(s_cubeMapFaces[face], ndx, m_internalFormat, levelSize, levelSize, 0, m_format, m_dataType, &data[0]); } } deUint32 m_internalFormat; deUint32 m_format; deUint32 m_dataType; int m_alignment; }; // TexImage2D() unpack parameters case. class TexImage2DParamsCase : public Texture2DSpecCase { public: TexImage2DParamsCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height, int rowLength, int skipRows, int skipPixels, int alignment) : Texture2DSpecCase (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, 1) , m_internalFormat (internalFormat) , m_rowLength (rowLength) , m_skipRows (skipRows) , m_skipPixels (skipPixels) , m_alignment (alignment) { } protected: void createTexture (void) { glu::TransferFormat transferFmt = glu::getTransferFormat(m_texFormat); int pixelSize = m_texFormat.getPixelSize(); int rowLength = m_rowLength > 0 ? m_rowLength : m_width; int rowPitch = deAlign32(rowLength*pixelSize, m_alignment); int height = m_height + m_skipRows; deUint32 tex = 0; vector<deUint8> data; DE_ASSERT(m_numLevels == 1); // Fill data with grid. data.resize(rowPitch*height); { 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_width, m_height, 1, rowPitch, 0, &data[0] + m_skipRows*rowPitch + m_skipPixels*pixelSize), 4, colorA, colorB); } glPixelStorei(GL_UNPACK_ROW_LENGTH, m_rowLength); 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_2D, tex); glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_width, m_height, 0, transferFmt.format, transferFmt.dataType, &data[0]); } deUint32 m_internalFormat; int m_rowLength; int m_skipRows; int m_skipPixels; int m_alignment; }; // TexImage3D() unpack parameters case. class TexImage3DParamsCase : public Texture3DSpecCase { public: TexImage3DParamsCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height, int depth, int imageHeight, int rowLength, int skipImages, int skipRows, int skipPixels, int alignment) : Texture3DSpecCase (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, depth, 1) , m_internalFormat (internalFormat) , m_imageHeight (imageHeight) , m_rowLength (rowLength) , m_skipImages (skipImages) , m_skipRows (skipRows) , m_skipPixels (skipPixels) , m_alignment (alignment) { } protected: void createTexture (void) { glu::TransferFormat transferFmt = glu::getTransferFormat(m_texFormat); int pixelSize = m_texFormat.getPixelSize(); int rowLength = m_rowLength > 0 ? m_rowLength : m_width; int rowPitch = deAlign32(rowLength*pixelSize, m_alignment); int imageHeight = m_imageHeight > 0 ? m_imageHeight : m_height; int slicePitch = imageHeight*rowPitch; deUint32 tex = 0; vector<deUint8> data; DE_ASSERT(m_numLevels == 1); // Fill data with grid. data.resize(slicePitch*(m_depth+m_skipImages)); { 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_width, m_height, m_depth, rowPitch, slicePitch, &data[0] + m_skipImages*slicePitch + m_skipRows*rowPitch + m_skipPixels*pixelSize), 4, colorA, colorB); } 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_3D, tex); glTexImage3D(GL_TEXTURE_3D, 0, m_internalFormat, m_width, m_height, m_depth, 0, transferFmt.format, transferFmt.dataType, &data[0]); } deUint32 m_internalFormat; int m_imageHeight; int m_rowLength; int m_skipImages; int m_skipRows; int m_skipPixels; int m_alignment; }; // Basic TexSubImage2D() with 2D texture usage class BasicTexSubImage2DCase : public Texture2DSpecCase { public: BasicTexSubImage2DCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int width, int height) : Texture2DSpecCase (context, name, desc, glu::mapGLTransferFormat(format, dataType), width, height, maxLevelCount(width, height)) , m_internalFormat (format) , m_format (format) , m_dataType (dataType) { } BasicTexSubImage2DCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height) : Texture2DSpecCase (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, maxLevelCount(width, height)) , m_internalFormat (internalFormat) , m_format (GL_NONE) , m_dataType (GL_NONE) { glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat); m_format = fmt.format; m_dataType = fmt.dataType; } protected: void createTexture (void) { deUint32 tex = 0; tcu::TextureLevel data (m_texFormat); de::Random rnd (deStringHash(getName())); glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // First specify full texture. for (int ndx = 0; ndx < m_numLevels; ndx++) { int levelW = de::max(1, m_width >> ndx); int levelH = de::max(1, m_height >> ndx); Vec4 gMin = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax); Vec4 gMax = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax); data.setSize(levelW, levelH); tcu::fillWithComponentGradients(data.getAccess(), gMin, gMax); glTexImage2D(GL_TEXTURE_2D, ndx, m_internalFormat, levelW, levelH, 0, m_format, m_dataType, data.getAccess().getDataPtr()); } // Re-specify parts of each level. for (int ndx = 0; ndx < m_numLevels; ndx++) { int levelW = de::max(1, m_width >> ndx); int levelH = de::max(1, m_height >> ndx); int w = rnd.getInt(1, levelW); int h = rnd.getInt(1, levelH); int x = rnd.getInt(0, levelW-w); int y = rnd.getInt(0, levelH-h); Vec4 colorA = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax); Vec4 colorB = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax); int cellSize = rnd.getInt(2, 16); data.setSize(w, h); tcu::fillWithGrid(data.getAccess(), cellSize, colorA, colorB); glTexSubImage2D(GL_TEXTURE_2D, ndx, x, y, w, h, m_format, m_dataType, data.getAccess().getDataPtr()); } } deUint32 m_internalFormat; deUint32 m_format; deUint32 m_dataType; }; // Basic TexSubImage2D() with cubemap usage class BasicTexSubImageCubeCase : public TextureCubeSpecCase { public: BasicTexSubImageCubeCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int size) : TextureCubeSpecCase (context, name, desc, glu::mapGLTransferFormat(format, dataType), size, deLog2Floor32(size)+1) , m_internalFormat (format) , m_format (format) , m_dataType (dataType) { } BasicTexSubImageCubeCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int size) : TextureCubeSpecCase (context, name, desc, glu::mapGLInternalFormat(internalFormat), size, deLog2Floor32(size)+1) , m_internalFormat (internalFormat) , m_format (GL_NONE) , m_dataType (GL_NONE) { glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat); m_format = fmt.format; m_dataType = fmt.dataType; } protected: void createTexture (void) { deUint32 tex = 0; tcu::TextureLevel data (m_texFormat); de::Random rnd (deStringHash(getName())); glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_CUBE_MAP, tex); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); for (int ndx = 0; ndx < m_numLevels; ndx++) { int levelSize = de::max(1, m_size >> ndx); data.setSize(levelSize, levelSize); for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++) { Vec4 gMin = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax); Vec4 gMax = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax); tcu::fillWithComponentGradients(data.getAccess(), gMin, gMax); glTexImage2D(s_cubeMapFaces[face], ndx, m_internalFormat, levelSize, levelSize, 0, m_format, m_dataType, data.getAccess().getDataPtr()); } } // Re-specify parts of each face and level. for (int ndx = 0; ndx < m_numLevels; ndx++) { int levelSize = de::max(1, m_size >> ndx); for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++) { int w = rnd.getInt(1, levelSize); int h = rnd.getInt(1, levelSize); int x = rnd.getInt(0, levelSize-w); int y = rnd.getInt(0, levelSize-h); Vec4 colorA = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax); Vec4 colorB = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax); int cellSize = rnd.getInt(2, 16); data.setSize(w, h); tcu::fillWithGrid(data.getAccess(), cellSize, colorA, colorB); glTexSubImage2D(s_cubeMapFaces[face], ndx, x, y, w, h, m_format, m_dataType, data.getAccess().getDataPtr()); } } } deUint32 m_internalFormat; deUint32 m_format; deUint32 m_dataType; }; // TexSubImage2D() unpack parameters case. class TexSubImage2DParamsCase : public Texture2DSpecCase { public: TexSubImage2DParamsCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height, int subX, int subY, int subW, int subH, int rowLength, int skipRows, int skipPixels, int alignment) : Texture2DSpecCase (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, 1) , m_internalFormat (internalFormat) , m_subX (subX) , m_subY (subY) , m_subW (subW) , m_subH (subH) , m_rowLength (rowLength) , m_skipRows (skipRows) , m_skipPixels (skipPixels) , m_alignment (alignment) { } protected: void createTexture (void) { glu::TransferFormat transferFmt = glu::getTransferFormat(m_texFormat); int pixelSize = m_texFormat.getPixelSize(); deUint32 tex = 0; vector<deUint8> data; DE_ASSERT(m_numLevels == 1); glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); // First fill texture with gradient. data.resize(deAlign32(m_width*pixelSize, 4)*m_height); tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, 1, deAlign32(m_width*pixelSize, 4), 0, &data[0]), m_texFormatInfo.valueMin, m_texFormatInfo.valueMax); glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_width, m_height, 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 height = m_subH + m_skipRows; 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(rowPitch*height); tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, m_subW, m_subH, 1, rowPitch, 0, &data[0] + m_skipRows*rowPitch + m_skipPixels*pixelSize), 4, colorA, colorB); } glPixelStorei(GL_UNPACK_ROW_LENGTH, m_rowLength); glPixelStorei(GL_UNPACK_SKIP_ROWS, m_skipRows); glPixelStorei(GL_UNPACK_SKIP_PIXELS, m_skipPixels); glPixelStorei(GL_UNPACK_ALIGNMENT, m_alignment); glTexSubImage2D(GL_TEXTURE_2D, 0, m_subX, m_subY, m_subW, m_subH, transferFmt.format, transferFmt.dataType, &data[0]); } deUint32 m_internalFormat; int m_subX; int m_subY; int m_subW; int m_subH; int m_rowLength; int m_skipRows; int m_skipPixels; int m_alignment; }; // Basic TexSubImage3D() with 3D texture usage class BasicTexSubImage3DCase : public Texture3DSpecCase { public: BasicTexSubImage3DCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height, int depth) : Texture3DSpecCase (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, depth, maxLevelCount(width, height, depth)) , m_internalFormat (internalFormat) { } protected: void createTexture (void) { deUint32 tex = 0; tcu::TextureLevel data (m_texFormat); de::Random rnd (deStringHash(getName())); glu::TransferFormat transferFmt = glu::getTransferFormat(m_texFormat); glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_3D, tex); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // First specify full texture. for (int ndx = 0; ndx < m_numLevels; ndx++) { int levelW = de::max(1, m_width >> ndx); int levelH = de::max(1, m_height >> ndx); int levelD = de::max(1, m_depth >> ndx); Vec4 gMin = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax); Vec4 gMax = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax); data.setSize(levelW, levelH, levelD); tcu::fillWithComponentGradients(data.getAccess(), gMin, gMax); glTexImage3D(GL_TEXTURE_3D, ndx, m_internalFormat, levelW, levelH, levelD, 0, transferFmt.format, transferFmt.dataType, data.getAccess().getDataPtr()); } // Re-specify parts of each level. for (int ndx = 0; ndx < m_numLevels; ndx++) { int levelW = de::max(1, m_width >> ndx); int levelH = de::max(1, m_height >> ndx); int levelD = de::max(1, m_depth >> ndx); int w = rnd.getInt(1, levelW); int h = rnd.getInt(1, levelH); int d = rnd.getInt(1, levelD); int x = rnd.getInt(0, levelW-w); int y = rnd.getInt(0, levelH-h); int z = rnd.getInt(0, levelD-d); Vec4 colorA = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax); Vec4 colorB = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax); int cellSize = rnd.getInt(2, 16); data.setSize(w, h, d); tcu::fillWithGrid(data.getAccess(), cellSize, colorA, colorB); glTexSubImage3D(GL_TEXTURE_3D, ndx, x, y, z, w, h, d, transferFmt.format, transferFmt.dataType, data.getAccess().getDataPtr()); } } deUint32 m_internalFormat; }; // TexSubImage2D() to texture initialized with empty data class TexSubImage2DEmptyTexCase : public Texture2DSpecCase { public: TexSubImage2DEmptyTexCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int width, int height) : Texture2DSpecCase (context, name, desc, glu::mapGLTransferFormat(format, dataType), width, height, maxLevelCount(width, height)) , m_internalFormat (format) , m_format (format) , m_dataType (dataType) { } TexSubImage2DEmptyTexCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height) : Texture2DSpecCase (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, maxLevelCount(width, height)) , m_internalFormat (internalFormat) , m_format (GL_NONE) , m_dataType (GL_NONE) { glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat); m_format = fmt.format; m_dataType = fmt.dataType; } protected: void createTexture (void) { deUint32 tex = 0; tcu::TextureLevel data (m_texFormat); de::Random rnd (deStringHash(getName())); glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // First allocate storage for each level. for (int ndx = 0; ndx < m_numLevels; ndx++) { int levelW = de::max(1, m_width >> ndx); int levelH = de::max(1, m_height >> ndx); glTexImage2D(GL_TEXTURE_2D, ndx, m_internalFormat, levelW, levelH, 0, m_format, m_dataType, DE_NULL); } // Specify pixel data to all levels using glTexSubImage2D() for (int ndx = 0; ndx < m_numLevels; ndx++) { int levelW = de::max(1, m_width >> ndx); int levelH = de::max(1, m_height >> ndx); Vec4 gMin = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax); Vec4 gMax = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax); data.setSize(levelW, levelH); tcu::fillWithComponentGradients(data.getAccess(), gMin, gMax); glTexSubImage2D(GL_TEXTURE_2D, ndx, 0, 0, levelW, levelH, m_format, m_dataType, data.getAccess().getDataPtr()); } } deUint32 m_internalFormat; deUint32 m_format; deUint32 m_dataType; }; // TexSubImage2D() to empty cubemap texture class TexSubImageCubeEmptyTexCase : public TextureCubeSpecCase { public: TexSubImageCubeEmptyTexCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int size) : TextureCubeSpecCase (context, name, desc, glu::mapGLTransferFormat(format, dataType), size, deLog2Floor32(size)+1) , m_internalFormat (format) , m_format (format) , m_dataType (dataType) { } TexSubImageCubeEmptyTexCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int size) : TextureCubeSpecCase (context, name, desc, glu::mapGLInternalFormat(internalFormat), size, deLog2Floor32(size)+1) , m_internalFormat (internalFormat) , m_format (GL_NONE) , m_dataType (GL_NONE) { glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat); m_format = fmt.format; m_dataType = fmt.dataType; } protected: void createTexture (void) { deUint32 tex = 0; tcu::TextureLevel data (m_texFormat); de::Random rnd (deStringHash(getName())); glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_CUBE_MAP, tex); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // Specify storage for each level. for (int ndx = 0; ndx < m_numLevels; ndx++) { int levelSize = de::max(1, m_size >> ndx); for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++) glTexImage2D(s_cubeMapFaces[face], ndx, m_internalFormat, levelSize, levelSize, 0, m_format, m_dataType, DE_NULL); } // Specify data using glTexSubImage2D() for (int ndx = 0; ndx < m_numLevels; ndx++) { int levelSize = de::max(1, m_size >> ndx); data.setSize(levelSize, levelSize); for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++) { Vec4 gMin = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax); Vec4 gMax = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax); tcu::fillWithComponentGradients(data.getAccess(), gMin, gMax); glTexSubImage2D(s_cubeMapFaces[face], ndx, 0, 0, levelSize, levelSize, m_format, m_dataType, data.getAccess().getDataPtr()); } } } deUint32 m_internalFormat; deUint32 m_format; deUint32 m_dataType; }; // TexSubImage2D() unpack alignment with 2D texture class TexSubImage2DAlignCase : public Texture2DSpecCase { public: TexSubImage2DAlignCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int width, int height, int subX, int subY, int subW, int subH, int alignment) : Texture2DSpecCase (context, name, desc, glu::mapGLTransferFormat(format, dataType), width, height, 1) , m_internalFormat (format) , m_format (format) , m_dataType (dataType) , m_subX (subX) , m_subY (subY) , m_subW (subW) , m_subH (subH) , m_alignment (alignment) { } TexSubImage2DAlignCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height, int subX, int subY, int subW, int subH, int alignment) : Texture2DSpecCase (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, 1) , m_internalFormat (internalFormat) , m_format (GL_NONE) , m_dataType (GL_NONE) , m_subX (subX) , m_subY (subY) , m_subW (subW) , m_subH (subH) , m_alignment (alignment) { glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat); m_format = fmt.format; m_dataType = fmt.dataType; } protected: void createTexture (void) { deUint32 tex = 0; vector<deUint8> data; glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); // Specify base level. data.resize(m_texFormat.getPixelSize()*m_width*m_height); tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, 1, &data[0]), Vec4(0.0f), Vec4(1.0f)); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_width, m_height, 0, m_format, m_dataType, &data[0]); // Re-specify subrectangle. int rowPitch = deAlign32(m_texFormat.getPixelSize()*m_subW, m_alignment); data.resize(rowPitch*m_subH); tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, m_subW, m_subH, 1, rowPitch, 0, &data[0]), 4, Vec4(1.0f, 0.0f, 0.0f, 1.0f), Vec4(0.0f, 1.0f, 0.0f, 1.0f)); glPixelStorei(GL_UNPACK_ALIGNMENT, m_alignment); glTexSubImage2D(GL_TEXTURE_2D, 0, m_subX, m_subY, m_subW, m_subH, m_format, m_dataType, &data[0]); } deUint32 m_internalFormat; deUint32 m_format; deUint32 m_dataType; int m_subX; int m_subY; int m_subW; int m_subH; int m_alignment; }; // TexSubImage2D() unpack alignment with cubemap texture class TexSubImageCubeAlignCase : public TextureCubeSpecCase { public: TexSubImageCubeAlignCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int size, int subX, int subY, int subW, int subH, int alignment) : TextureCubeSpecCase (context, name, desc, glu::mapGLTransferFormat(format, dataType), size, 1) , m_internalFormat (format) , m_format (format) , m_dataType (dataType) , m_subX (subX) , m_subY (subY) , m_subW (subW) , m_subH (subH) , m_alignment (alignment) { } TexSubImageCubeAlignCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int size, int subX, int subY, int subW, int subH, int alignment) : TextureCubeSpecCase (context, name, desc, glu::mapGLInternalFormat(internalFormat), size, 1) , m_internalFormat (internalFormat) , m_format (GL_NONE) , m_dataType (GL_NONE) , m_subX (subX) , m_subY (subY) , m_subW (subW) , m_subH (subH) , m_alignment (alignment) { glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat); m_format = fmt.format; m_dataType = fmt.dataType; } protected: void createTexture (void) { deUint32 tex = 0; vector<deUint8> data; glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_CUBE_MAP, tex); // Specify base level. data.resize(m_texFormat.getPixelSize()*m_size*m_size); tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_size, m_size, 1, &data[0]), Vec4(0.0f), Vec4(1.0f)); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); for (int face = 0; face < tcu::CUBEFACE_LAST; face++) glTexImage2D(s_cubeMapFaces[face], 0, m_internalFormat, m_size, m_size, 0, m_format, m_dataType, &data[0]); // Re-specify subrectangle. int rowPitch = deAlign32(m_texFormat.getPixelSize()*m_subW, m_alignment); data.resize(rowPitch*m_subH); tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, m_subW, m_subH, 1, rowPitch, 0, &data[0]), 4, Vec4(1.0f, 0.0f, 0.0f, 1.0f), Vec4(0.0f, 1.0f, 0.0f, 1.0f)); glPixelStorei(GL_UNPACK_ALIGNMENT, m_alignment); for (int face = 0; face < tcu::CUBEFACE_LAST; face++) glTexSubImage2D(s_cubeMapFaces[face], 0, m_subX, m_subY, m_subW, m_subH, m_format, m_dataType, &data[0]); } deUint32 m_internalFormat; deUint32 m_format; deUint32 m_dataType; int m_subX; int m_subY; int m_subW; int m_subH; int m_alignment; }; // TexSubImage3D() unpack parameters case. class TexSubImage3DParamsCase : public Texture3DSpecCase { public: TexSubImage3DParamsCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height, 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) : Texture3DSpecCase (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, 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) { } protected: void createTexture (void) { glu::TransferFormat transferFmt = glu::getTransferFormat(m_texFormat); int pixelSize = m_texFormat.getPixelSize(); deUint32 tex = 0; vector<deUint8> data; DE_ASSERT(m_numLevels == 1); glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_3D, tex); // Fill with gradient. { int rowPitch = deAlign32(pixelSize*m_width, 4); int slicePitch = rowPitch*m_height; data.resize(slicePitch*m_depth); tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, m_depth, rowPitch, slicePitch, &data[0]), m_texFormatInfo.valueMin, m_texFormatInfo.valueMax); } glTexImage3D(GL_TEXTURE_3D, 0, m_internalFormat, m_width, m_height, 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)); 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), 4, colorA, colorB); } 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_3D, 0, m_subX, m_subY, m_subZ, m_subW, m_subH, m_subD, transferFmt.format, transferFmt.dataType, &data[0]); } deUint32 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; }; // Basic CopyTexImage2D() with 2D texture usage class BasicCopyTexImage2DCase : public Texture2DSpecCase { public: BasicCopyTexImage2DCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height) : Texture2DSpecCase (context, name, desc, glu::mapGLTransferFormat(internalFormat, GL_UNSIGNED_BYTE), width, height, maxLevelCount(width, height)) , m_internalFormat (internalFormat) { } protected: void createTexture (void) { const tcu::RenderTarget& renderTarget = TestCase::m_context.getRenderContext().getRenderTarget(); bool targetHasRGB = renderTarget.getPixelFormat().redBits > 0 && renderTarget.getPixelFormat().greenBits > 0 && renderTarget.getPixelFormat().blueBits > 0; bool targetHasAlpha = renderTarget.getPixelFormat().alphaBits > 0; tcu::TextureFormat fmt = mapGLUnsizedInternalFormat(m_internalFormat); bool texHasRGB = fmt.order != tcu::TextureFormat::A; bool texHasAlpha = fmt.order == tcu::TextureFormat::RGBA || fmt.order == tcu::TextureFormat::LA || fmt.order == tcu::TextureFormat::A; deUint32 tex = 0; de::Random rnd (deStringHash(getName())); GradientShader shader (glu::TYPE_FLOAT_VEC4); deUint32 shaderID = getCurrentContext()->createProgram(&shader); if ((texHasRGB && !targetHasRGB) || (texHasAlpha && !targetHasAlpha)) throw tcu::NotSupportedError("Copying from current framebuffer is not supported", "", __FILE__, __LINE__); // Fill render target with gradient. shader.setGradient(*getCurrentContext(), shaderID, Vec4(0.0f), Vec4(1.0f)); sglr::drawQuad(*getCurrentContext(), shaderID, tcu::Vec3(-1.0f, -1.0f, 0.0f), tcu::Vec3(1.0f, 1.0f, 0.0f)); glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); for (int ndx = 0; ndx < m_numLevels; ndx++) { int levelW = de::max(1, m_width >> ndx); int levelH = de::max(1, m_height >> ndx); int x = rnd.getInt(0, getWidth() - levelW); int y = rnd.getInt(0, getHeight() - levelH); glCopyTexImage2D(GL_TEXTURE_2D, ndx, m_internalFormat, x, y, levelW, levelH, 0); } } deUint32 m_internalFormat; }; // Basic CopyTexImage2D() with cubemap usage class BasicCopyTexImageCubeCase : public TextureCubeSpecCase { public: BasicCopyTexImageCubeCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int size) : TextureCubeSpecCase (context, name, desc, glu::mapGLTransferFormat(internalFormat, GL_UNSIGNED_BYTE), size, deLog2Floor32(size)+1) , m_internalFormat (internalFormat) { } protected: void createTexture (void) { const tcu::RenderTarget& renderTarget = TestCase::m_context.getRenderContext().getRenderTarget(); bool targetHasRGB = renderTarget.getPixelFormat().redBits > 0 && renderTarget.getPixelFormat().greenBits > 0 && renderTarget.getPixelFormat().blueBits > 0; bool targetHasAlpha = renderTarget.getPixelFormat().alphaBits > 0; tcu::TextureFormat fmt = mapGLUnsizedInternalFormat(m_internalFormat); bool texHasRGB = fmt.order != tcu::TextureFormat::A; bool texHasAlpha = fmt.order == tcu::TextureFormat::RGBA || fmt.order == tcu::TextureFormat::LA || fmt.order == tcu::TextureFormat::A; deUint32 tex = 0; de::Random rnd (deStringHash(getName())); GradientShader shader (glu::TYPE_FLOAT_VEC4); deUint32 shaderID = getCurrentContext()->createProgram(&shader); if ((texHasRGB && !targetHasRGB) || (texHasAlpha && !targetHasAlpha)) throw tcu::NotSupportedError("Copying from current framebuffer is not supported", "", __FILE__, __LINE__); // Fill render target with gradient. shader.setGradient(*getCurrentContext(), shaderID, Vec4(0.0f), Vec4(1.0f)); sglr::drawQuad(*getCurrentContext(), shaderID, tcu::Vec3(-1.0f, -1.0f, 0.0f), tcu::Vec3(1.0f, 1.0f, 0.0f)); glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_CUBE_MAP, tex); for (int ndx = 0; ndx < m_numLevels; ndx++) { int levelSize = de::max(1, m_size >> ndx); for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++) { int x = rnd.getInt(0, getWidth() - levelSize); int y = rnd.getInt(0, getHeight() - levelSize); glCopyTexImage2D(s_cubeMapFaces[face], ndx, m_internalFormat, x, y, levelSize, levelSize, 0); } } } deUint32 m_internalFormat; }; // Basic CopyTexSubImage2D() with 2D texture usage class BasicCopyTexSubImage2DCase : public Texture2DSpecCase { public: BasicCopyTexSubImage2DCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int width, int height) : Texture2DSpecCase (context, name, desc, glu::mapGLTransferFormat(format, dataType), width, height, maxLevelCount(width, height)) , m_format (format) , m_dataType (dataType) { } protected: void createTexture (void) { const tcu::RenderTarget& renderTarget = TestCase::m_context.getRenderContext().getRenderTarget(); bool targetHasRGB = renderTarget.getPixelFormat().redBits > 0 && renderTarget.getPixelFormat().greenBits > 0 && renderTarget.getPixelFormat().blueBits > 0; bool targetHasAlpha = renderTarget.getPixelFormat().alphaBits > 0; tcu::TextureFormat fmt = glu::mapGLTransferFormat(m_format, m_dataType); bool texHasRGB = fmt.order != tcu::TextureFormat::A; bool texHasAlpha = fmt.order == tcu::TextureFormat::RGBA || fmt.order == tcu::TextureFormat::LA || fmt.order == tcu::TextureFormat::A; deUint32 tex = 0; tcu::TextureLevel data (fmt); de::Random rnd (deStringHash(getName())); GradientShader shader (glu::TYPE_FLOAT_VEC4); deUint32 shaderID = getCurrentContext()->createProgram(&shader); if ((texHasRGB && !targetHasRGB) || (texHasAlpha && !targetHasAlpha)) throw tcu::NotSupportedError("Copying from current framebuffer is not supported", "", __FILE__, __LINE__); glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // First specify full texture. for (int ndx = 0; ndx < m_numLevels; ndx++) { int levelW = de::max(1, m_width >> ndx); int levelH = de::max(1, m_height >> ndx); Vec4 colorA = randomVector<4>(rnd); Vec4 colorB = randomVector<4>(rnd); int cellSize = rnd.getInt(2, 16); data.setSize(levelW, levelH); tcu::fillWithGrid(data.getAccess(), cellSize, colorA, colorB); glTexImage2D(GL_TEXTURE_2D, ndx, m_format, levelW, levelH, 0, m_format, m_dataType, data.getAccess().getDataPtr()); } // Fill render target with gradient. shader.setGradient(*getCurrentContext(), shaderID, Vec4(0.0f), Vec4(1.0f)); sglr::drawQuad(*getCurrentContext(), shaderID, tcu::Vec3(-1.0f, -1.0f, 0.0f), tcu::Vec3(1.0f, 1.0f, 0.0f)); // Re-specify parts of each level. for (int ndx = 0; ndx < m_numLevels; ndx++) { int levelW = de::max(1, m_width >> ndx); int levelH = de::max(1, m_height >> ndx); int w = rnd.getInt(1, levelW); int h = rnd.getInt(1, levelH); int xo = rnd.getInt(0, levelW-w); int yo = rnd.getInt(0, levelH-h); int x = rnd.getInt(0, getWidth() - w); int y = rnd.getInt(0, getHeight() - h); glCopyTexSubImage2D(GL_TEXTURE_2D, ndx, xo, yo, x, y, w, h); } } deUint32 m_format; deUint32 m_dataType; }; // Basic CopyTexSubImage2D() with cubemap usage class BasicCopyTexSubImageCubeCase : public TextureCubeSpecCase { public: BasicCopyTexSubImageCubeCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int size) : TextureCubeSpecCase (context, name, desc, glu::mapGLTransferFormat(format, dataType), size, deLog2Floor32(size)+1) , m_format (format) , m_dataType (dataType) { } protected: void createTexture (void) { const tcu::RenderTarget& renderTarget = TestCase::m_context.getRenderContext().getRenderTarget(); bool targetHasRGB = renderTarget.getPixelFormat().redBits > 0 && renderTarget.getPixelFormat().greenBits > 0 && renderTarget.getPixelFormat().blueBits > 0; bool targetHasAlpha = renderTarget.getPixelFormat().alphaBits > 0; tcu::TextureFormat fmt = glu::mapGLTransferFormat(m_format, m_dataType); bool texHasRGB = fmt.order != tcu::TextureFormat::A; bool texHasAlpha = fmt.order == tcu::TextureFormat::RGBA || fmt.order == tcu::TextureFormat::LA || fmt.order == tcu::TextureFormat::A; deUint32 tex = 0; tcu::TextureLevel data (fmt); de::Random rnd (deStringHash(getName())); GradientShader shader (glu::TYPE_FLOAT_VEC4); deUint32 shaderID = getCurrentContext()->createProgram(&shader); if ((texHasRGB && !targetHasRGB) || (texHasAlpha && !targetHasAlpha)) throw tcu::NotSupportedError("Copying from current framebuffer is not supported", "", __FILE__, __LINE__); glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_CUBE_MAP, tex); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); for (int ndx = 0; ndx < m_numLevels; ndx++) { int levelSize = de::max(1, m_size >> ndx); data.setSize(levelSize, levelSize); for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++) { Vec4 colorA = randomVector<4>(rnd); Vec4 colorB = randomVector<4>(rnd); int cellSize = rnd.getInt(2, 16); tcu::fillWithGrid(data.getAccess(), cellSize, colorA, colorB); glTexImage2D(s_cubeMapFaces[face], ndx, m_format, levelSize, levelSize, 0, m_format, m_dataType, data.getAccess().getDataPtr()); } } // Fill render target with gradient. shader.setGradient(*getCurrentContext(), shaderID, Vec4(0.0f), Vec4(1.0f)); sglr::drawQuad(*getCurrentContext(), shaderID, tcu::Vec3(-1.0f, -1.0f, 0.0f), tcu::Vec3(1.0f, 1.0f, 0.0f)); // Re-specify parts of each face and level. for (int ndx = 0; ndx < m_numLevels; ndx++) { int levelSize = de::max(1, m_size >> ndx); for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++) { int w = rnd.getInt(1, levelSize); int h = rnd.getInt(1, levelSize); int xo = rnd.getInt(0, levelSize-w); int yo = rnd.getInt(0, levelSize-h); int x = rnd.getInt(0, getWidth() - w); int y = rnd.getInt(0, getHeight() - h); glCopyTexSubImage2D(s_cubeMapFaces[face], ndx, xo, yo, x, y, w, h); } } } deUint32 m_format; deUint32 m_dataType; }; // Basic glTexStorage2D() with 2D texture usage class BasicTexStorage2DCase : public Texture2DSpecCase { public: BasicTexStorage2DCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height, int numLevels) : Texture2DSpecCase (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, numLevels) , m_internalFormat (internalFormat) { } protected: void createTexture (void) { tcu::TextureFormat fmt = glu::mapGLInternalFormat(m_internalFormat); glu::TransferFormat transferFmt = glu::getTransferFormat(fmt); deUint32 tex = 0; tcu::TextureLevel levelData (fmt); de::Random rnd (deStringHash(getName())); glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); glTexStorage2D(GL_TEXTURE_2D, m_numLevels, m_internalFormat, m_width, m_height); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); for (int ndx = 0; ndx < m_numLevels; ndx++) { int levelW = de::max(1, m_width >> ndx); int levelH = de::max(1, m_height >> 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, levelH); tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax); glTexSubImage2D(GL_TEXTURE_2D, ndx, 0, 0, levelW, levelH, transferFmt.format, transferFmt.dataType, levelData.getAccess().getDataPtr()); } } deUint32 m_internalFormat; }; // Basic glTexStorage2D() with cubemap usage class BasicTexStorageCubeCase : public TextureCubeSpecCase { public: BasicTexStorageCubeCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int size, int numLevels) : TextureCubeSpecCase (context, name, desc, glu::mapGLInternalFormat(internalFormat), size, numLevels) , m_internalFormat (internalFormat) { } protected: void createTexture (void) { tcu::TextureFormat fmt = glu::mapGLInternalFormat(m_internalFormat); glu::TransferFormat transferFmt = glu::getTransferFormat(fmt); deUint32 tex = 0; tcu::TextureLevel levelData (fmt); de::Random rnd (deStringHash(getName())); glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_CUBE_MAP, tex); glTexStorage2D(GL_TEXTURE_CUBE_MAP, m_numLevels, m_internalFormat, m_size, m_size); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); for (int ndx = 0; ndx < m_numLevels; ndx++) { int levelSize = de::max(1, m_size >> ndx); levelData.setSize(levelSize, levelSize); for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++) { Vec4 gMin = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax); Vec4 gMax = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax); tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax); glTexSubImage2D(s_cubeMapFaces[face], ndx, 0, 0, levelSize, levelSize, transferFmt.format, transferFmt.dataType, levelData.getAccess().getDataPtr()); } } } deUint32 m_internalFormat; }; // Basic glTexStorage3D() with 2D array texture usage class BasicTexStorage2DArrayCase : public Texture2DArraySpecCase { public: BasicTexStorage2DArrayCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height, int numLayers, int numLevels) : Texture2DArraySpecCase (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, numLayers, numLevels) , m_internalFormat (internalFormat) { } protected: void createTexture (void) { deUint32 tex = 0; tcu::TextureLevel levelData (m_texFormat); de::Random rnd (deStringHash(getName())); glu::TransferFormat transferFmt = glu::getTransferFormat(m_texFormat); glGenTextures (1, &tex); glBindTexture (GL_TEXTURE_2D_ARRAY, tex); glTexStorage3D (GL_TEXTURE_2D_ARRAY, m_numLevels, m_internalFormat, m_width, m_height, m_numLayers); glPixelStorei (GL_UNPACK_ALIGNMENT, 1); for (int ndx = 0; ndx < m_numLevels; ndx++) { int levelW = de::max(1, m_width >> ndx); int levelH = de::max(1, m_height >> 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, levelH, m_numLayers); tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax); glTexSubImage3D(GL_TEXTURE_2D_ARRAY, ndx, 0, 0, 0, levelW, levelH, m_numLayers, transferFmt.format, transferFmt.dataType, levelData.getAccess().getDataPtr()); } } deUint32 m_internalFormat; }; // Basic TexStorage3D() with 3D texture usage class BasicTexStorage3DCase : public Texture3DSpecCase { public: BasicTexStorage3DCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height, int depth, int numLevels) : Texture3DSpecCase (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, depth, numLevels) , m_internalFormat (internalFormat) { } protected: void createTexture (void) { deUint32 tex = 0; tcu::TextureLevel levelData (m_texFormat); de::Random rnd (deStringHash(getName())); glu::TransferFormat transferFmt = glu::getTransferFormat(m_texFormat); glGenTextures (1, &tex); glBindTexture (GL_TEXTURE_3D, tex); glTexStorage3D (GL_TEXTURE_3D, m_numLevels, m_internalFormat, m_width, m_height, m_depth); glPixelStorei (GL_UNPACK_ALIGNMENT, 1); for (int ndx = 0; ndx < m_numLevels; ndx++) { int levelW = de::max(1, m_width >> ndx); int levelH = de::max(1, m_height >> ndx); int levelD = de::max(1, m_depth >> 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, levelH, levelD); tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax); glTexSubImage3D(GL_TEXTURE_3D, ndx, 0, 0, 0, levelW, levelH, levelD, transferFmt.format, transferFmt.dataType, levelData.getAccess().getDataPtr()); } } deUint32 m_internalFormat; }; // Pixel buffer object cases. // TexImage2D() from pixel buffer object. class TexImage2DBufferCase : public Texture2DSpecCase { public: TexImage2DBufferCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height, int rowLength, int skipRows, int skipPixels, int alignment, int offset) : Texture2DSpecCase (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, 1) , m_internalFormat (internalFormat) , m_rowLength (rowLength) , 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_width + m_skipPixels; int rowPitch = deAlign32(rowLength*pixelSize, m_alignment); int height = m_height + m_skipRows; deUint32 buf = 0; deUint32 tex = 0; vector<deUint8> data; DE_ASSERT(m_numLevels == 1); // Fill data with grid. data.resize(rowPitch*height + 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_width, m_height, 1, rowPitch, 0, &data[0] + m_skipRows*rowPitch + m_skipPixels*pixelSize + m_offset), 4, colorA, colorB); } // Create buffer and upload. 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_ROW_LENGTH, m_rowLength); 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_2D, tex); glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_width, m_height, 0, transferFmt.format, transferFmt.dataType, (const void*)(deUintptr)m_offset); } deUint32 m_internalFormat; int m_rowLength; int m_skipRows; int m_skipPixels; int m_alignment; int m_offset; }; // TexImage2D() cubemap from pixel buffer object case class TexImageCubeBufferCase : public TextureCubeSpecCase { public: TexImageCubeBufferCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int size, int rowLength, int skipRows, int skipPixels, int alignment, int offset) : TextureCubeSpecCase (context, name, desc, glu::mapGLInternalFormat(internalFormat), size, 1) , m_internalFormat (internalFormat) , m_rowLength (rowLength) , m_skipRows (skipRows) , m_skipPixels (skipPixels) , m_alignment (alignment) , m_offset (offset) { } protected: void createTexture (void) { de::Random rnd (deStringHash(getName())); deUint32 tex = 0; glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat); const int pixelSize = m_texFormat.getPixelSize(); const int rowLength = m_rowLength > 0 ? m_rowLength : m_size + m_skipPixels; const int rowPitch = deAlign32(rowLength*pixelSize, m_alignment); const int height = m_size + m_skipRows; vector<vector<deUint8> > data (DE_LENGTH_OF_ARRAY(s_cubeMapFaces)); DE_ASSERT(m_numLevels == 1); glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_CUBE_MAP, tex); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++) { deUint32 buf = 0; { const Vec4 gMin = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax); const Vec4 gMax = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax); data[face].resize(rowPitch*height + m_offset); tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_size, m_size, 1, rowPitch, 0, &data[face][0] + m_skipRows*rowPitch + m_skipPixels*pixelSize + m_offset), gMin, gMax); } // Create buffer and upload. glGenBuffers(1, &buf); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf); glBufferData(GL_PIXEL_UNPACK_BUFFER, (int)data[face].size(), &data[face][0], GL_STATIC_DRAW); glPixelStorei(GL_UNPACK_ROW_LENGTH, m_rowLength); glPixelStorei(GL_UNPACK_SKIP_ROWS, m_skipRows); glPixelStorei(GL_UNPACK_SKIP_PIXELS, m_skipPixels); glPixelStorei(GL_UNPACK_ALIGNMENT, m_alignment); glTexImage2D(s_cubeMapFaces[face], 0, m_internalFormat, m_size, m_size, 0, fmt.format, fmt.dataType, (const void*)(deUintptr)m_offset); } } deUint32 m_internalFormat; int m_rowLength; int m_skipRows; int m_skipPixels; int m_alignment; int m_offset; }; // TexImage3D() 2D array from pixel buffer object. class TexImage2DArrayBufferCase : public Texture2DArraySpecCase { public: TexImage2DArrayBufferCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height, int depth, int imageHeight, int rowLength, int skipImages, int skipRows, int skipPixels, int alignment, int offset) : Texture2DArraySpecCase (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, 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_width; int rowPitch = deAlign32(rowLength*pixelSize, m_alignment); int imageHeight = m_imageHeight > 0 ? m_imageHeight : m_height; int slicePitch = imageHeight*rowPitch; deUint32 tex = 0; deUint32 buf = 0; vector<deUint8> data; DE_ASSERT(m_numLevels == 1); // Fill data with grid. data.resize(slicePitch*(m_numLayers+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_width, m_height, m_numLayers, 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_2D_ARRAY, tex); glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, m_internalFormat, m_width, m_height, m_numLayers, 0, transferFmt.format, transferFmt.dataType, (const void*)(deUintptr)m_offset); } deUint32 m_internalFormat; int m_imageHeight; int m_rowLength; int m_skipImages; int m_skipRows; int m_skipPixels; int m_alignment; int m_offset; }; // TexImage3D() from pixel buffer object. class TexImage3DBufferCase : public Texture3DSpecCase { public: TexImage3DBufferCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height, int depth, int imageHeight, int rowLength, int skipImages, int skipRows, int skipPixels, int alignment, int offset) : Texture3DSpecCase (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, 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_width; int rowPitch = deAlign32(rowLength*pixelSize, m_alignment); int imageHeight = m_imageHeight > 0 ? m_imageHeight : m_height; int slicePitch = imageHeight*rowPitch; deUint32 tex = 0; deUint32 buf = 0; vector<deUint8> 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_width, m_height, 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_3D, tex); glTexImage3D(GL_TEXTURE_3D, 0, m_internalFormat, m_width, m_height, m_depth, 0, transferFmt.format, transferFmt.dataType, (const void*)(deUintptr)m_offset); } deUint32 m_internalFormat; int m_imageHeight; int m_rowLength; int m_skipImages; int m_skipRows; int m_skipPixels; int m_alignment; int m_offset; }; // TexSubImage2D() PBO case. class TexSubImage2DBufferCase : public Texture2DSpecCase { public: TexSubImage2DBufferCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height, int subX, int subY, int subW, int subH, int rowLength, int skipRows, int skipPixels, int alignment, int offset) : Texture2DSpecCase (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, 1) , m_internalFormat (internalFormat) , m_subX (subX) , m_subY (subY) , m_subW (subW) , m_subH (subH) , m_rowLength (rowLength) , 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(); deUint32 tex = 0; deUint32 buf = 0; vector<deUint8> data; DE_ASSERT(m_numLevels == 1); glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); // First fill texture with gradient. data.resize(deAlign32(m_width*pixelSize, 4)*m_height); tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, 1, deAlign32(m_width*pixelSize, 4), 0, &data[0]), m_texFormatInfo.valueMin, m_texFormatInfo.valueMax); glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_width, m_height, 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 height = m_subH + m_skipRows; 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(rowPitch*height + m_offset); tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, m_subW, m_subH, 1, rowPitch, 0, &data[0] + 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_ROW_LENGTH, m_rowLength); glPixelStorei(GL_UNPACK_SKIP_ROWS, m_skipRows); glPixelStorei(GL_UNPACK_SKIP_PIXELS, m_skipPixels); glPixelStorei(GL_UNPACK_ALIGNMENT, m_alignment); glTexSubImage2D(GL_TEXTURE_2D, 0, m_subX, m_subY, m_subW, m_subH, transferFmt.format, transferFmt.dataType, (const void*)(deUintptr)m_offset); } deUint32 m_internalFormat; int m_subX; int m_subY; int m_subW; int m_subH; int m_rowLength; int m_skipRows; int m_skipPixels; int m_alignment; int m_offset; }; // TexSubImage2D() cubemap PBO case. class TexSubImageCubeBufferCase : public TextureCubeSpecCase { public: TexSubImageCubeBufferCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int size, int subX, int subY, int subW, int subH, int rowLength, int skipRows, int skipPixels, int alignment, int offset) : TextureCubeSpecCase (context, name, desc, glu::mapGLInternalFormat(internalFormat), size, 1) , m_internalFormat (internalFormat) , m_subX (subX) , m_subY (subY) , m_subW (subW) , m_subH (subH) , m_rowLength (rowLength) , m_skipRows (skipRows) , m_skipPixels (skipPixels) , m_alignment (alignment) , m_offset (offset) { } protected: void createTexture (void) { de::Random rnd (deStringHash(getName())); glu::TransferFormat transferFmt = glu::getTransferFormat(m_texFormat); int pixelSize = m_texFormat.getPixelSize(); deUint32 tex = 0; deUint32 buf = 0; vector<deUint8> data; DE_ASSERT(m_numLevels == 1); glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_CUBE_MAP, tex); // Fill faces with different gradients. data.resize(deAlign32(m_size*pixelSize, 4)*m_size); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++) { const Vec4 gMin = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax); const Vec4 gMax = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax); tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_size, m_size, 1, deAlign32(m_size*pixelSize, 4), 0, &data[0]), gMin, gMax); glTexImage2D(s_cubeMapFaces[face], 0, m_internalFormat, m_size, m_size, 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 height = m_subH + m_skipRows; 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(rowPitch*height + m_offset); tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, m_subW, m_subH, 1, rowPitch, 0, &data[0] + 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_ROW_LENGTH, m_rowLength); glPixelStorei(GL_UNPACK_SKIP_ROWS, m_skipRows); glPixelStorei(GL_UNPACK_SKIP_PIXELS, m_skipPixels); glPixelStorei(GL_UNPACK_ALIGNMENT, m_alignment); for (int face = 0; face < tcu::CUBEFACE_LAST; face++) glTexSubImage2D(s_cubeMapFaces[face], 0, m_subX, m_subY, m_subW, m_subH, transferFmt.format, transferFmt.dataType, (const void*)(deUintptr)m_offset); } deUint32 m_internalFormat; int m_subX; int m_subY; int m_subW; int m_subH; int m_rowLength; int m_skipRows; int m_skipPixels; int m_alignment; int m_offset; }; // TexSubImage3D() 2D array PBO case. class TexSubImage2DArrayBufferCase : public Texture2DArraySpecCase { public: TexSubImage2DArrayBufferCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height, 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) : Texture2DArraySpecCase (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, 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(); deUint32 tex = 0; deUint32 buf = 0; vector<deUint8> data; DE_ASSERT(m_numLevels == 1); glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D_ARRAY, tex); // Fill with gradient. { int rowPitch = deAlign32(pixelSize*m_width, 4); int slicePitch = rowPitch*m_height; data.resize(slicePitch*m_numLayers); tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, m_numLayers, rowPitch, slicePitch, &data[0]), m_texFormatInfo.valueMin, m_texFormatInfo.valueMax); } glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, m_internalFormat, m_width, m_height, m_numLayers, 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_numLayers+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_2D_ARRAY, 0, m_subX, m_subY, m_subZ, m_subW, m_subH, m_subD, transferFmt.format, transferFmt.dataType, (const void*)(deIntptr)m_offset); } deUint32 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; }; // TexSubImage3D() PBO case. class TexSubImage3DBufferCase : public Texture3DSpecCase { public: TexSubImage3DBufferCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height, 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) : Texture3DSpecCase (context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, 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(); deUint32 tex = 0; deUint32 buf = 0; vector<deUint8> data; DE_ASSERT(m_numLevels == 1); glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_3D, tex); // Fill with gradient. { int rowPitch = deAlign32(pixelSize*m_width, 4); int slicePitch = rowPitch*m_height; data.resize(slicePitch*m_depth); tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, m_depth, rowPitch, slicePitch, &data[0]), m_texFormatInfo.valueMin, m_texFormatInfo.valueMax); } glTexImage3D(GL_TEXTURE_3D, 0, m_internalFormat, m_width, m_height, 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_3D, 0, m_subX, m_subY, m_subZ, m_subW, m_subH, m_subD, transferFmt.format, transferFmt.dataType, (const void*)(deIntptr)m_offset); } deUint32 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; }; // TexImage2D() depth case. class TexImage2DDepthCase : public Texture2DSpecCase { public: TexImage2DDepthCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int imageWidth, int imageHeight) : Texture2DSpecCase (context, name, desc, glu::mapGLInternalFormat(internalFormat), imageWidth, imageHeight, maxLevelCount(imageWidth, imageHeight)) , 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); deUint32 tex = 0; tcu::TextureLevel levelData (m_texFormat); glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); GLU_CHECK(); for (int ndx = 0; ndx < m_numLevels; ndx++) { const int levelW = de::max(1, m_width >> ndx); const int levelH = de::max(1, m_height >> 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, levelH); tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax); glTexImage2D(GL_TEXTURE_2D, ndx, m_internalFormat, levelW, levelH, 0, fmt.format, fmt.dataType, levelData.getAccess().getDataPtr()); } } const deUint32 m_internalFormat; }; // TexImage3D() depth case. class TexImage2DArrayDepthCase : public Texture2DArraySpecCase { public: TexImage2DArrayDepthCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int imageWidth, int imageHeight, int numLayers) : Texture2DArraySpecCase(context, name, desc, glu::mapGLInternalFormat(internalFormat), imageWidth, imageHeight, numLayers, maxLevelCount(imageWidth, imageHeight)) , 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); deUint32 tex = 0; tcu::TextureLevel levelData (m_texFormat); glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D_ARRAY, tex); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); GLU_CHECK(); for (int ndx = 0; ndx < m_numLevels; ndx++) { const int levelW = de::max(1, m_width >> ndx); const int levelH = de::max(1, m_height >> 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, levelH, m_numLayers); tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax); glTexImage3D(GL_TEXTURE_2D_ARRAY, ndx, m_internalFormat, levelW, levelH, m_numLayers, 0, fmt.format, fmt.dataType, levelData.getAccess().getDataPtr()); } } const deUint32 m_internalFormat; }; // TexSubImage2D() depth case. class TexSubImage2DDepthCase : public Texture2DSpecCase { public: TexSubImage2DDepthCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int imageWidth, int imageHeight) : Texture2DSpecCase (context, name, desc, glu::mapGLInternalFormat(internalFormat), imageWidth, imageHeight, maxLevelCount(imageWidth, imageHeight)) , 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())); deUint32 tex = 0; tcu::TextureLevel levelData (m_texFormat); glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, 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_width >> ndx); const int levelH = de::max(1, m_height >> 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, levelH); tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax); glTexImage2D(GL_TEXTURE_2D, ndx, m_internalFormat, levelW, levelH, 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_width >> ndx); const int levelH = de::max(1, m_height >> ndx); const int w = rnd.getInt(1, levelW); const int h = rnd.getInt(1, levelH); const int x = rnd.getInt(0, levelW-w); const int y = rnd.getInt(0, levelH-h); 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); tcu::fillWithGrid(levelData.getAccess(), cellSize, colorA, colorB); glTexSubImage2D(GL_TEXTURE_2D, ndx, x, y, w, h, fmt.format, fmt.dataType, levelData.getAccess().getDataPtr()); } } const deUint32 m_internalFormat; }; // TexSubImage3D() depth case. class TexSubImage2DArrayDepthCase : public Texture2DArraySpecCase { public: TexSubImage2DArrayDepthCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int imageWidth, int imageHeight, int numLayers) : Texture2DArraySpecCase(context, name, desc, glu::mapGLInternalFormat(internalFormat), imageWidth, imageHeight, numLayers, maxLevelCount(imageWidth, imageHeight)) , 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())); deUint32 tex = 0; tcu::TextureLevel levelData (m_texFormat); glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D_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_width >> ndx); const int levelH = de::max(1, m_height >> 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, levelH, m_numLayers); tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax); glTexImage3D(GL_TEXTURE_2D_ARRAY, ndx, m_internalFormat, levelW, levelH, m_numLayers, 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_width >> ndx); const int levelH = de::max(1, m_height >> ndx); const int w = rnd.getInt(1, levelW); const int h = rnd.getInt(1, levelH); const int d = rnd.getInt(1, m_numLayers); const int x = rnd.getInt(0, levelW-w); const int y = rnd.getInt(0, levelH-h); const int z = rnd.getInt(0, m_numLayers-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_2D_ARRAY, ndx, x, y, z, w, h, d, fmt.format, fmt.dataType, levelData.getAccess().getDataPtr()); } } const deUint32 m_internalFormat; }; // TexImage2D() depth case with pbo. class TexImage2DDepthBufferCase : public Texture2DSpecCase { public: TexImage2DDepthBufferCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int imageWidth, int imageHeight) : Texture2DSpecCase (context, name, desc, glu::mapGLInternalFormat(internalFormat), imageWidth, imageHeight, 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_width; int alignment = 4; int rowPitch = deAlign32(rowLength*pixelSize, alignment); int height = m_height; deUint32 buf = 0; deUint32 tex = 0; vector<deUint8> data; DE_ASSERT(m_numLevels == 1); // Fill data with gradient data.resize(rowPitch*height); { 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_width, m_height, 1, rowPitch, 0, &data[0]), gMin, gMax); } // Create buffer and upload. 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_ROW_LENGTH, rowLength); glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); glPixelStorei(GL_UNPACK_ALIGNMENT, alignment); glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_width, m_height, 0, transferFmt.format, transferFmt.dataType, DE_NULL); glDeleteBuffers(1, &buf); } const deUint32 m_internalFormat; }; // TexImage3D() depth case with pbo. class TexImage2DArrayDepthBufferCase : public Texture2DArraySpecCase { public: TexImage2DArrayDepthBufferCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int imageWidth, int imageHeight, int numLayers) : Texture2DArraySpecCase(context, name, desc, glu::mapGLInternalFormat(internalFormat), imageWidth, imageHeight, 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_width; int alignment = 4; int rowPitch = deAlign32(rowLength*pixelSize, alignment); int imageHeight = m_height; int slicePitch = imageHeight*rowPitch; deUint32 tex = 0; deUint32 buf = 0; vector<deUint8> data; DE_ASSERT(m_numLevels == 1); // Fill data with grid. data.resize(slicePitch*m_numLayers); { 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_width, m_height, m_numLayers, 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_2D_ARRAY, tex); glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, m_internalFormat, m_width, m_height, m_numLayers, 0, transferFmt.format, transferFmt.dataType, DE_NULL); glDeleteBuffers(1, &buf); } const deUint32 m_internalFormat; }; TextureSpecificationTests::TextureSpecificationTests (Context& context) : TestCaseGroup(context, "specification", "Texture Specification Tests") { } TextureSpecificationTests::~TextureSpecificationTests (void) { } void TextureSpecificationTests::init (void) { struct { const char* name; deUint32 format; deUint32 dataType; } unsizedFormats[] = { { "alpha_unsigned_byte", GL_ALPHA, GL_UNSIGNED_BYTE }, { "luminance_unsigned_byte", GL_LUMINANCE, GL_UNSIGNED_BYTE }, { "luminance_alpha_unsigned_byte", GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE }, { "rgb_unsigned_short_5_6_5", GL_RGB, GL_UNSIGNED_SHORT_5_6_5 }, { "rgb_unsigned_byte", GL_RGB, GL_UNSIGNED_BYTE }, { "rgba_unsigned_short_4_4_4_4", GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4 }, { "rgba_unsigned_short_5_5_5_1", GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1 }, { "rgba_unsigned_byte", GL_RGBA, GL_UNSIGNED_BYTE } }; struct { const char* name; deUint32 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; deUint32 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 TexImage2D usage. { tcu::TestCaseGroup* basicTexImageGroup = new tcu::TestCaseGroup(m_testCtx, "basic_teximage2d", "Basic glTexImage2D() usage"); addChild(basicTexImageGroup); for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++) { const char* fmtName = colorFormats[formatNdx].name; deUint32 format = colorFormats[formatNdx].internalFormat; const int tex2DWidth = 64; const int tex2DHeight = 128; const int texCubeSize = 64; basicTexImageGroup->addChild(new BasicTexImage2DCase (m_context, (string(fmtName) + "_2d").c_str(), "", format, tex2DWidth, tex2DHeight)); basicTexImageGroup->addChild(new BasicTexImageCubeCase (m_context, (string(fmtName) + "_cube").c_str(), "", format, texCubeSize)); } } // Randomized TexImage2D order. { tcu::TestCaseGroup* randomTexImageGroup = new tcu::TestCaseGroup(m_testCtx, "random_teximage2d", "Randomized glTexImage2D() usage"); addChild(randomTexImageGroup); de::Random rnd(9); // 2D cases. for (int ndx = 0; ndx < 10; ndx++) { int formatNdx = rnd.getInt(0, DE_LENGTH_OF_ARRAY(colorFormats)-1); int width = 1 << rnd.getInt(2, 8); int height = 1 << rnd.getInt(2, 8); randomTexImageGroup->addChild(new RandomOrderTexImage2DCase(m_context, (string("2d_") + de::toString(ndx)).c_str(), "", colorFormats[formatNdx].internalFormat, width, height)); } // Cubemap cases. for (int ndx = 0; ndx < 10; ndx++) { int formatNdx = rnd.getInt(0, DE_LENGTH_OF_ARRAY(colorFormats)-1); int size = 1 << rnd.getInt(2, 8); randomTexImageGroup->addChild(new RandomOrderTexImageCubeCase(m_context, (string("cube_") + de::toString(ndx)).c_str(), "", colorFormats[formatNdx].internalFormat, size)); } } // TexImage2D unpack alignment. { tcu::TestCaseGroup* alignGroup = new tcu::TestCaseGroup(m_testCtx, "teximage2d_align", "glTexImage2D() unpack alignment tests"); addChild(alignGroup); alignGroup->addChild(new TexImage2DAlignCase (m_context, "2d_r8_4_8", "", GL_R8, 4, 8, 4, 8)); alignGroup->addChild(new TexImage2DAlignCase (m_context, "2d_r8_63_1", "", GL_R8, 63, 30, 1, 1)); alignGroup->addChild(new TexImage2DAlignCase (m_context, "2d_r8_63_2", "", GL_R8, 63, 30, 1, 2)); alignGroup->addChild(new TexImage2DAlignCase (m_context, "2d_r8_63_4", "", GL_R8, 63, 30, 1, 4)); alignGroup->addChild(new TexImage2DAlignCase (m_context, "2d_r8_63_8", "", GL_R8, 63, 30, 1, 8)); alignGroup->addChild(new TexImage2DAlignCase (m_context, "2d_rgba4_51_1", "", GL_RGBA4, 51, 30, 1, 1)); alignGroup->addChild(new TexImage2DAlignCase (m_context, "2d_rgba4_51_2", "", GL_RGBA4, 51, 30, 1, 2)); alignGroup->addChild(new TexImage2DAlignCase (m_context, "2d_rgba4_51_4", "", GL_RGBA4, 51, 30, 1, 4)); alignGroup->addChild(new TexImage2DAlignCase (m_context, "2d_rgba4_51_8", "", GL_RGBA4, 51, 30, 1, 8)); alignGroup->addChild(new TexImage2DAlignCase (m_context, "2d_rgb8_39_1", "", GL_RGB8, 39, 43, 1, 1)); alignGroup->addChild(new TexImage2DAlignCase (m_context, "2d_rgb8_39_2", "", GL_RGB8, 39, 43, 1, 2)); alignGroup->addChild(new TexImage2DAlignCase (m_context, "2d_rgb8_39_4", "", GL_RGB8, 39, 43, 1, 4)); alignGroup->addChild(new TexImage2DAlignCase (m_context, "2d_rgb8_39_8", "", GL_RGB8, 39, 43, 1, 8)); alignGroup->addChild(new TexImage2DAlignCase (m_context, "2d_rgba8_47_1", "", GL_RGBA8, 47, 27, 1, 1)); alignGroup->addChild(new TexImage2DAlignCase (m_context, "2d_rgba8_47_2", "", GL_RGBA8, 47, 27, 1, 2)); alignGroup->addChild(new TexImage2DAlignCase (m_context, "2d_rgba8_47_4", "", GL_RGBA8, 47, 27, 1, 4)); alignGroup->addChild(new TexImage2DAlignCase (m_context, "2d_rgba8_47_8", "", GL_RGBA8, 47, 27, 1, 8)); alignGroup->addChild(new TexImageCubeAlignCase (m_context, "cube_r8_4_8", "", GL_R8, 4, 3, 8)); alignGroup->addChild(new TexImageCubeAlignCase (m_context, "cube_r8_63_1", "", GL_R8, 63, 1, 1)); alignGroup->addChild(new TexImageCubeAlignCase (m_context, "cube_r8_63_2", "", GL_R8, 63, 1, 2)); alignGroup->addChild(new TexImageCubeAlignCase (m_context, "cube_r8_63_4", "", GL_R8, 63, 1, 4)); alignGroup->addChild(new TexImageCubeAlignCase (m_context, "cube_r8_63_8", "", GL_R8, 63, 1, 8)); alignGroup->addChild(new TexImageCubeAlignCase (m_context, "cube_rgba4_51_1", "", GL_RGBA4, 51, 1, 1)); alignGroup->addChild(new TexImageCubeAlignCase (m_context, "cube_rgba4_51_2", "", GL_RGBA4, 51, 1, 2)); alignGroup->addChild(new TexImageCubeAlignCase (m_context, "cube_rgba4_51_4", "", GL_RGBA4, 51, 1, 4)); alignGroup->addChild(new TexImageCubeAlignCase (m_context, "cube_rgba4_51_8", "", GL_RGBA4, 51, 1, 8)); alignGroup->addChild(new TexImageCubeAlignCase (m_context, "cube_rgb8_39_1", "", GL_RGB8, 39, 1, 1)); alignGroup->addChild(new TexImageCubeAlignCase (m_context, "cube_rgb8_39_2", "", GL_RGB8, 39, 1, 2)); alignGroup->addChild(new TexImageCubeAlignCase (m_context, "cube_rgb8_39_4", "", GL_RGB8, 39, 1, 4)); alignGroup->addChild(new TexImageCubeAlignCase (m_context, "cube_rgb8_39_8", "", GL_RGB8, 39, 1, 8)); alignGroup->addChild(new TexImageCubeAlignCase (m_context, "cube_rgba8_47_1", "", GL_RGBA8, 47, 1, 1)); alignGroup->addChild(new TexImageCubeAlignCase (m_context, "cube_rgba8_47_2", "", GL_RGBA8, 47, 1, 2)); alignGroup->addChild(new TexImageCubeAlignCase (m_context, "cube_rgba8_47_4", "", GL_RGBA8, 47, 1, 4)); alignGroup->addChild(new TexImageCubeAlignCase (m_context, "cube_rgba8_47_8", "", GL_RGBA8, 47, 1, 8)); } // glTexImage2D() unpack parameter cases. { tcu::TestCaseGroup* paramGroup = new tcu::TestCaseGroup(m_testCtx, "teximage2d_unpack_params", "glTexImage2D() pixel transfer mode cases"); addChild(paramGroup); static const struct { const char* name; deUint32 format; int width; int height; int rowLength; int skipRows; int skipPixels; int alignment; } cases[] = { { "rgb8_alignment", GL_RGB8, 31, 30, 0, 0, 0, 2 }, { "rgb8_row_length", GL_RGB8, 31, 30, 50, 0, 0, 4 }, { "rgb8_skip_rows", GL_RGB8, 31, 30, 0, 3, 0, 4 }, { "rgb8_skip_pixels", GL_RGB8, 31, 30, 36, 0, 5, 4 }, { "r8_complex1", GL_R8, 31, 30, 64, 1, 3, 1 }, { "r8_complex2", GL_R8, 31, 30, 64, 1, 3, 2 }, { "r8_complex3", GL_R8, 31, 30, 64, 1, 3, 4 }, { "r8_complex4", GL_R8, 31, 30, 64, 1, 3, 8 }, { "rgba8_complex1", GL_RGBA8, 56, 61, 69, 0, 0, 8 }, { "rgba8_complex2", GL_RGBA8, 56, 61, 69, 0, 7, 8 }, { "rgba8_complex3", GL_RGBA8, 56, 61, 69, 3, 0, 8 }, { "rgba8_complex4", GL_RGBA8, 56, 61, 69, 3, 7, 8 }, { "rgba32f_complex", GL_RGBA32F, 19, 10, 27, 1, 7, 8 } }; for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cases); ndx++) paramGroup->addChild(new TexImage2DParamsCase(m_context, cases[ndx].name, "", cases[ndx].format, cases[ndx].width, cases[ndx].height, cases[ndx].rowLength, cases[ndx].skipRows, cases[ndx].skipPixels, cases[ndx].alignment)); } // glTexImage2D() pbo cases. { tcu::TestCaseGroup* pboGroup = new tcu::TestCaseGroup(m_testCtx, "teximage2d_pbo", "glTexImage2D() from PBO"); addChild(pboGroup); // Parameter cases static const struct { const char* name; deUint32 format; int width; int height; int rowLength; int skipRows; int skipPixels; int alignment; int offset; } parameterCases[] = { { "rgb8_offset", GL_RGB8, 31, 30, 0, 0, 0, 4, 67 }, { "rgb8_alignment", GL_RGB8, 31, 30, 0, 0, 0, 2, 0 }, { "rgb8_row_length", GL_RGB8, 31, 30, 50, 0, 0, 4, 0 }, { "rgb8_skip_rows", GL_RGB8, 31, 30, 0, 3, 0, 4, 0 }, { "rgb8_skip_pixels", GL_RGB8, 31, 30, 36, 0, 5, 4, 0 } }; for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++) { const string fmtName = colorFormats[formatNdx].name; const deUint32 format = colorFormats[formatNdx].internalFormat; const int tex2DWidth = 65; const int tex2DHeight = 37; const int texCubeSize = 64; pboGroup->addChild(new TexImage2DBufferCase (m_context, (fmtName + "_2d").c_str(), "", format, tex2DWidth, tex2DHeight, 0, 0, 0, 4, 0)); pboGroup->addChild(new TexImageCubeBufferCase (m_context, (fmtName + "_cube").c_str(), "", format, texCubeSize, 0, 0, 0, 4, 0)); } for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(parameterCases); ndx++) { pboGroup->addChild(new TexImage2DBufferCase(m_context, (string(parameterCases[ndx].name) + "_2d").c_str(), "", parameterCases[ndx].format, parameterCases[ndx].width, parameterCases[ndx].height, parameterCases[ndx].rowLength, parameterCases[ndx].skipRows, parameterCases[ndx].skipPixels, parameterCases[ndx].alignment, parameterCases[ndx].offset)); pboGroup->addChild(new TexImageCubeBufferCase(m_context, (string(parameterCases[ndx].name) + "_cube").c_str(), "", parameterCases[ndx].format, parameterCases[ndx].width, parameterCases[ndx].rowLength, parameterCases[ndx].skipRows, parameterCases[ndx].skipPixels, parameterCases[ndx].alignment, parameterCases[ndx].offset)); } } // glTexImage2D() depth cases. { tcu::TestCaseGroup* shadow2dGroup = new tcu::TestCaseGroup(m_testCtx, "teximage2d_depth", "glTexImage2D() with depth or depth/stencil format"); addChild(shadow2dGroup); for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++) { const int tex2DWidth = 64; const int tex2DHeight = 128; shadow2dGroup->addChild(new TexImage2DDepthCase(m_context, depthStencilFormats[ndx].name, "", depthStencilFormats[ndx].internalFormat, tex2DWidth, tex2DHeight)); } } // glTexImage2D() depth cases with pbo. { tcu::TestCaseGroup* shadow2dGroup = new tcu::TestCaseGroup(m_testCtx, "teximage2d_depth_pbo", "glTexImage2D() with depth or depth/stencil format with pbo"); addChild(shadow2dGroup); for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++) { const int tex2DWidth = 64; const int tex2DHeight = 128; shadow2dGroup->addChild(new TexImage2DDepthBufferCase(m_context, depthStencilFormats[ndx].name, "", depthStencilFormats[ndx].internalFormat, tex2DWidth, tex2DHeight)); } } // Basic TexSubImage2D usage. { tcu::TestCaseGroup* basicTexSubImageGroup = new tcu::TestCaseGroup(m_testCtx, "basic_texsubimage2d", "Basic glTexSubImage2D() usage"); addChild(basicTexSubImageGroup); for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++) { const char* fmtName = colorFormats[formatNdx].name; deUint32 format = colorFormats[formatNdx].internalFormat; const int tex2DWidth = 64; const int tex2DHeight = 128; const int texCubeSize = 64; basicTexSubImageGroup->addChild(new BasicTexSubImage2DCase (m_context, (string(fmtName) + "_2d").c_str(), "", format, tex2DWidth, tex2DHeight)); basicTexSubImageGroup->addChild(new BasicTexSubImageCubeCase (m_context, (string(fmtName) + "_cube").c_str(), "", format, texCubeSize)); } } // TexSubImage2D to empty texture. { tcu::TestCaseGroup* texSubImageEmptyTexGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage2d_empty_tex", "glTexSubImage2D() to texture that has storage but no data"); addChild(texSubImageEmptyTexGroup); for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(unsizedFormats); formatNdx++) { const char* fmtName = unsizedFormats[formatNdx].name; deUint32 format = unsizedFormats[formatNdx].format; deUint32 dataType = unsizedFormats[formatNdx].dataType; const int tex2DWidth = 64; const int tex2DHeight = 32; const int texCubeSize = 32; texSubImageEmptyTexGroup->addChild(new TexSubImage2DEmptyTexCase (m_context, (string(fmtName) + "_2d").c_str(), "", format, dataType, tex2DWidth, tex2DHeight)); texSubImageEmptyTexGroup->addChild(new TexSubImageCubeEmptyTexCase (m_context, (string(fmtName) + "_cube").c_str(), "", format, dataType, texCubeSize)); } } // TexSubImage2D alignment cases. { tcu::TestCaseGroup* alignGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage2d_align", "glTexSubImage2D() unpack alignment tests"); addChild(alignGroup); alignGroup->addChild(new TexSubImage2DAlignCase (m_context, "2d_r8_1_1", "", GL_R8, 64, 64, 13, 17, 1, 6, 1)); alignGroup->addChild(new TexSubImage2DAlignCase (m_context, "2d_r8_1_2", "", GL_R8, 64, 64, 13, 17, 1, 6, 2)); alignGroup->addChild(new TexSubImage2DAlignCase (m_context, "2d_r8_1_4", "", GL_R8, 64, 64, 13, 17, 1, 6, 4)); alignGroup->addChild(new TexSubImage2DAlignCase (m_context, "2d_r8_1_8", "", GL_R8, 64, 64, 13, 17, 1, 6, 8)); alignGroup->addChild(new TexSubImage2DAlignCase (m_context, "2d_r8_63_1", "", GL_R8, 64, 64, 1, 9, 63, 30, 1)); alignGroup->addChild(new TexSubImage2DAlignCase (m_context, "2d_r8_63_2", "", GL_R8, 64, 64, 1, 9, 63, 30, 2)); alignGroup->addChild(new TexSubImage2DAlignCase (m_context, "2d_r8_63_4", "", GL_R8, 64, 64, 1, 9, 63, 30, 4)); alignGroup->addChild(new TexSubImage2DAlignCase (m_context, "2d_r8_63_8", "", GL_R8, 64, 64, 1, 9, 63, 30, 8)); alignGroup->addChild(new TexSubImage2DAlignCase (m_context, "2d_rgba4_51_1", "", GL_RGBA4, 64, 64, 7, 29, 51, 30, 1)); alignGroup->addChild(new TexSubImage2DAlignCase (m_context, "2d_rgba4_51_2", "", GL_RGBA4, 64, 64, 7, 29, 51, 30, 2)); alignGroup->addChild(new TexSubImage2DAlignCase (m_context, "2d_rgba4_51_4", "", GL_RGBA4, 64, 64, 7, 29, 51, 30, 4)); alignGroup->addChild(new TexSubImage2DAlignCase (m_context, "2d_rgba4_51_8", "", GL_RGBA4, 64, 64, 7, 29, 51, 30, 8)); alignGroup->addChild(new TexSubImage2DAlignCase (m_context, "2d_rgb8_39_1", "", GL_RGB8, 64, 64, 11, 8, 39, 43, 1)); alignGroup->addChild(new TexSubImage2DAlignCase (m_context, "2d_rgb8_39_2", "", GL_RGB8, 64, 64, 11, 8, 39, 43, 2)); alignGroup->addChild(new TexSubImage2DAlignCase (m_context, "2d_rgb8_39_4", "", GL_RGB8, 64, 64, 11, 8, 39, 43, 4)); alignGroup->addChild(new TexSubImage2DAlignCase (m_context, "2d_rgb8_39_8", "", GL_RGB8, 64, 64, 11, 8, 39, 43, 8)); alignGroup->addChild(new TexSubImage2DAlignCase (m_context, "2d_rgba8_47_1", "", GL_RGBA8, 64, 64, 10, 1, 47, 27, 1)); alignGroup->addChild(new TexSubImage2DAlignCase (m_context, "2d_rgba8_47_2", "", GL_RGBA8, 64, 64, 10, 1, 47, 27, 2)); alignGroup->addChild(new TexSubImage2DAlignCase (m_context, "2d_rgba8_47_4", "", GL_RGBA8, 64, 64, 10, 1, 47, 27, 4)); alignGroup->addChild(new TexSubImage2DAlignCase (m_context, "2d_rgba8_47_8", "", GL_RGBA8, 64, 64, 10, 1, 47, 27, 8)); alignGroup->addChild(new TexSubImageCubeAlignCase (m_context, "cube_r8_1_1", "", GL_R8, 64, 13, 17, 1, 6, 1)); alignGroup->addChild(new TexSubImageCubeAlignCase (m_context, "cube_r8_1_2", "", GL_R8, 64, 13, 17, 1, 6, 2)); alignGroup->addChild(new TexSubImageCubeAlignCase (m_context, "cube_r8_1_4", "", GL_R8, 64, 13, 17, 1, 6, 4)); alignGroup->addChild(new TexSubImageCubeAlignCase (m_context, "cube_r8_1_8", "", GL_R8, 64, 13, 17, 1, 6, 8)); alignGroup->addChild(new TexSubImageCubeAlignCase (m_context, "cube_r8_63_1", "", GL_R8, 64, 1, 9, 63, 30, 1)); alignGroup->addChild(new TexSubImageCubeAlignCase (m_context, "cube_r8_63_2", "", GL_R8, 64, 1, 9, 63, 30, 2)); alignGroup->addChild(new TexSubImageCubeAlignCase (m_context, "cube_r8_63_4", "", GL_R8, 64, 1, 9, 63, 30, 4)); alignGroup->addChild(new TexSubImageCubeAlignCase (m_context, "cube_r8_63_8", "", GL_R8, 64, 1, 9, 63, 30, 8)); alignGroup->addChild(new TexSubImageCubeAlignCase (m_context, "cube_rgba4_51_1", "", GL_RGBA4, 64, 7, 29, 51, 30, 1)); alignGroup->addChild(new TexSubImageCubeAlignCase (m_context, "cube_rgba4_51_2", "", GL_RGBA4, 64, 7, 29, 51, 30, 2)); alignGroup->addChild(new TexSubImageCubeAlignCase (m_context, "cube_rgba4_51_4", "", GL_RGBA4, 64, 7, 29, 51, 30, 4)); alignGroup->addChild(new TexSubImageCubeAlignCase (m_context, "cube_rgba4_51_8", "", GL_RGBA4, 64, 7, 29, 51, 30, 8)); alignGroup->addChild(new TexSubImageCubeAlignCase (m_context, "cube_rgb8_39_1", "", GL_RGB8, 64, 11, 8, 39, 43, 1)); alignGroup->addChild(new TexSubImageCubeAlignCase (m_context, "cube_rgb8_39_2", "", GL_RGB8, 64, 11, 8, 39, 43, 2)); alignGroup->addChild(new TexSubImageCubeAlignCase (m_context, "cube_rgb8_39_4", "", GL_RGB8, 64, 11, 8, 39, 43, 4)); alignGroup->addChild(new TexSubImageCubeAlignCase (m_context, "cube_rgb8_39_8", "", GL_RGB8, 64, 11, 8, 39, 43, 8)); alignGroup->addChild(new TexSubImageCubeAlignCase (m_context, "cube_rgba8_47_1", "", GL_RGBA8, 64, 10, 1, 47, 27, 1)); alignGroup->addChild(new TexSubImageCubeAlignCase (m_context, "cube_rgba8_47_2", "", GL_RGBA8, 64, 10, 1, 47, 27, 2)); alignGroup->addChild(new TexSubImageCubeAlignCase (m_context, "cube_rgba8_47_4", "", GL_RGBA8, 64, 10, 1, 47, 27, 4)); alignGroup->addChild(new TexSubImageCubeAlignCase (m_context, "cube_rgba8_47_8", "", GL_RGBA8, 64, 10, 1, 47, 27, 8)); } // glTexSubImage2D() pixel transfer mode cases. { tcu::TestCaseGroup* paramGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage2d_unpack_params", "glTexSubImage2D() pixel transfer mode cases"); addChild(paramGroup); static const struct { const char* name; deUint32 format; int width; int height; int subX; int subY; int subW; int subH; int rowLength; int skipRows; int skipPixels; int alignment; } cases[] = { { "rgb8_alignment", GL_RGB8, 54, 60, 11, 7, 31, 30, 0, 0, 0, 2 }, { "rgb8_row_length", GL_RGB8, 54, 60, 11, 7, 31, 30, 50, 0, 0, 4 }, { "rgb8_skip_rows", GL_RGB8, 54, 60, 11, 7, 31, 30, 0, 3, 0, 4 }, { "rgb8_skip_pixels", GL_RGB8, 54, 60, 11, 7, 31, 30, 36, 0, 5, 4 }, { "r8_complex1", GL_R8, 54, 60, 11, 7, 31, 30, 64, 1, 3, 1 }, { "r8_complex2", GL_R8, 54, 60, 11, 7, 31, 30, 64, 1, 3, 2 }, { "r8_complex3", GL_R8, 54, 60, 11, 7, 31, 30, 64, 1, 3, 4 }, { "r8_complex4", GL_R8, 54, 60, 11, 7, 31, 30, 64, 1, 3, 8 }, { "rgba8_complex1", GL_RGBA8, 92, 84, 13, 19, 56, 61, 69, 0, 0, 8 }, { "rgba8_complex2", GL_RGBA8, 92, 84, 13, 19, 56, 61, 69, 0, 7, 8 }, { "rgba8_complex3", GL_RGBA8, 92, 84, 13, 19, 56, 61, 69, 3, 0, 8 }, { "rgba8_complex4", GL_RGBA8, 92, 84, 13, 19, 56, 61, 69, 3, 7, 8 }, { "rgba32f_complex", GL_RGBA32F, 92, 84, 13, 19, 56, 61, 69, 3, 7, 8 } }; for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cases); ndx++) paramGroup->addChild(new TexSubImage2DParamsCase(m_context, cases[ndx].name, "", cases[ndx].format, cases[ndx].width, cases[ndx].height, cases[ndx].subX, cases[ndx].subY, cases[ndx].subW, cases[ndx].subH, cases[ndx].rowLength, cases[ndx].skipRows, cases[ndx].skipPixels, cases[ndx].alignment)); } // glTexSubImage2D() PBO cases. { tcu::TestCaseGroup* pboGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage2d_pbo", "glTexSubImage2D() pixel buffer object tests"); addChild(pboGroup); static const struct { const char* name; deUint32 format; int width; int height; int subX; int subY; int subW; int subH; int rowLength; int skipRows; int skipPixels; int alignment; int offset; } paramCases[] = { { "rgb8_offset", GL_RGB8, 54, 60, 11, 7, 31, 30, 0, 0, 0, 4, 67 }, { "rgb8_alignment", GL_RGB8, 54, 60, 11, 7, 31, 30, 0, 0, 0, 2, 0 }, { "rgb8_row_length", GL_RGB8, 54, 60, 11, 7, 31, 30, 50, 0, 0, 4, 0 }, { "rgb8_skip_rows", GL_RGB8, 54, 60, 11, 7, 31, 30, 0, 3, 0, 4, 0 }, { "rgb8_skip_pixels", GL_RGB8, 54, 60, 11, 7, 31, 30, 36, 0, 5, 4, 0 } }; for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(colorFormats); ndx++) { pboGroup->addChild(new TexSubImage2DBufferCase(m_context, (std::string(colorFormats[ndx].name) + "_2d").c_str(), "", colorFormats[ndx].internalFormat, 54, // Width 60, // Height 11, // Sub X 7, // Sub Y 31, // Sub W 30, // Sub H 0, // Row len 0, // Skip rows 0, // Skip pixels 4, // Alignment 0 /* offset */)); pboGroup->addChild(new TexSubImageCubeBufferCase(m_context, (std::string(colorFormats[ndx].name) + "_cube").c_str(), "", colorFormats[ndx].internalFormat, 64, // Size 11, // Sub X 7, // Sub Y 31, // Sub W 30, // Sub H 0, // Row len 0, // Skip rows 0, // Skip pixels 4, // Alignment 0 /* offset */)); } for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(paramCases); ndx++) { pboGroup->addChild(new TexSubImage2DBufferCase(m_context, (std::string(paramCases[ndx].name) + "_2d").c_str(), "", paramCases[ndx].format, paramCases[ndx].width, paramCases[ndx].height, paramCases[ndx].subX, paramCases[ndx].subY, paramCases[ndx].subW, paramCases[ndx].subH, paramCases[ndx].rowLength, paramCases[ndx].skipRows, paramCases[ndx].skipPixels, paramCases[ndx].alignment, paramCases[ndx].offset)); pboGroup->addChild(new TexSubImageCubeBufferCase(m_context, (std::string(paramCases[ndx].name) + "_cube").c_str(), "", paramCases[ndx].format, paramCases[ndx].width, paramCases[ndx].subX, paramCases[ndx].subY, paramCases[ndx].subW, paramCases[ndx].subH, paramCases[ndx].rowLength, paramCases[ndx].skipRows, paramCases[ndx].skipPixels, paramCases[ndx].alignment, paramCases[ndx].offset)); } } // glTexSubImage2D() depth cases. { tcu::TestCaseGroup* shadow2dGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage2d_depth", "glTexSubImage2D() with depth or depth/stencil format"); addChild(shadow2dGroup); for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++) { const int tex2DWidth = 64; const int tex2DHeight = 32; shadow2dGroup->addChild(new TexSubImage2DDepthCase(m_context, depthStencilFormats[ndx].name, "", depthStencilFormats[ndx].internalFormat, tex2DWidth, tex2DHeight)); } } // Basic glCopyTexImage2D() cases { tcu::TestCaseGroup* copyTexImageGroup = new tcu::TestCaseGroup(m_testCtx, "basic_copyteximage2d", "Basic glCopyTexImage2D() usage"); addChild(copyTexImageGroup); copyTexImageGroup->addChild(new BasicCopyTexImage2DCase (m_context, "2d_alpha", "", GL_ALPHA, 128, 64)); copyTexImageGroup->addChild(new BasicCopyTexImage2DCase (m_context, "2d_luminance", "", GL_LUMINANCE, 128, 64)); copyTexImageGroup->addChild(new BasicCopyTexImage2DCase (m_context, "2d_luminance_alpha", "", GL_LUMINANCE_ALPHA, 128, 64)); copyTexImageGroup->addChild(new BasicCopyTexImage2DCase (m_context, "2d_rgb", "", GL_RGB, 128, 64)); copyTexImageGroup->addChild(new BasicCopyTexImage2DCase (m_context, "2d_rgba", "", GL_RGBA, 128, 64)); copyTexImageGroup->addChild(new BasicCopyTexImageCubeCase (m_context, "cube_alpha", "", GL_ALPHA, 64)); copyTexImageGroup->addChild(new BasicCopyTexImageCubeCase (m_context, "cube_luminance", "", GL_LUMINANCE, 64)); copyTexImageGroup->addChild(new BasicCopyTexImageCubeCase (m_context, "cube_luminance_alpha", "", GL_LUMINANCE_ALPHA, 64)); copyTexImageGroup->addChild(new BasicCopyTexImageCubeCase (m_context, "cube_rgb", "", GL_RGB, 64)); copyTexImageGroup->addChild(new BasicCopyTexImageCubeCase (m_context, "cube_rgba", "", GL_RGBA, 64)); } // Basic glCopyTexSubImage2D() cases { tcu::TestCaseGroup* copyTexSubImageGroup = new tcu::TestCaseGroup(m_testCtx, "basic_copytexsubimage2d", "Basic glCopyTexSubImage2D() usage"); addChild(copyTexSubImageGroup); copyTexSubImageGroup->addChild(new BasicCopyTexSubImage2DCase (m_context, "2d_alpha", "", GL_ALPHA, GL_UNSIGNED_BYTE, 128, 64)); copyTexSubImageGroup->addChild(new BasicCopyTexSubImage2DCase (m_context, "2d_luminance", "", GL_LUMINANCE, GL_UNSIGNED_BYTE, 128, 64)); copyTexSubImageGroup->addChild(new BasicCopyTexSubImage2DCase (m_context, "2d_luminance_alpha", "", GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 128, 64)); copyTexSubImageGroup->addChild(new BasicCopyTexSubImage2DCase (m_context, "2d_rgb", "", GL_RGB, GL_UNSIGNED_BYTE, 128, 64)); copyTexSubImageGroup->addChild(new BasicCopyTexSubImage2DCase (m_context, "2d_rgba", "", GL_RGBA, GL_UNSIGNED_BYTE, 128, 64)); copyTexSubImageGroup->addChild(new BasicCopyTexSubImageCubeCase (m_context, "cube_alpha", "", GL_ALPHA, GL_UNSIGNED_BYTE, 64)); copyTexSubImageGroup->addChild(new BasicCopyTexSubImageCubeCase (m_context, "cube_luminance", "", GL_LUMINANCE, GL_UNSIGNED_BYTE, 64)); copyTexSubImageGroup->addChild(new BasicCopyTexSubImageCubeCase (m_context, "cube_luminance_alpha", "", GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 64)); copyTexSubImageGroup->addChild(new BasicCopyTexSubImageCubeCase (m_context, "cube_rgb", "", GL_RGB, GL_UNSIGNED_BYTE, 64)); copyTexSubImageGroup->addChild(new BasicCopyTexSubImageCubeCase (m_context, "cube_rgba", "", GL_RGBA, GL_UNSIGNED_BYTE, 64)); } // 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; deUint32 format = colorFormats[formatNdx].internalFormat; const int tex2DArrayWidth = 57; const int tex2DArrayHeight = 44; const int tex2DArrayLevels = 5; const int tex3DWidth = 63; const int tex3DHeight = 29; const int tex3DDepth = 11; basicTexImageGroup->addChild(new BasicTexImage2DArrayCase (m_context, (string(fmtName) + "_2d_array").c_str(), "", format, tex2DArrayWidth, tex2DArrayHeight, tex2DArrayLevels)); basicTexImageGroup->addChild(new BasicTexImage3DCase (m_context, (string(fmtName) + "_3d").c_str(), "", format, tex3DWidth, tex3DHeight, tex3DDepth)); } } // glTexImage3D() unpack params cases. { tcu::TestCaseGroup* paramGroup = new tcu::TestCaseGroup(m_testCtx, "teximage3d_unpack_params", "glTexImage3D() unpack parameters"); addChild(paramGroup); static const struct { const char* name; deUint32 format; int width; int height; int depth; int imageHeight; int rowLength; int skipImages; int skipRows; int skipPixels; int alignment; } cases[] = { { "rgb8_image_height", GL_RGB8, 23, 19, 8, 26, 0, 0, 0, 0, 4 }, { "rgb8_row_length", GL_RGB8, 23, 19, 8, 0, 27, 0, 0, 0, 4 }, { "rgb8_skip_images", GL_RGB8, 23, 19, 8, 0, 0, 3, 0, 0, 4 }, { "rgb8_skip_rows", GL_RGB8, 23, 19, 8, 22, 0, 0, 3, 0, 4 }, { "rgb8_skip_pixels", GL_RGB8, 23, 19, 8, 0, 25, 0, 0, 2, 4 }, { "r8_complex1", GL_R8, 13, 17, 11, 23, 15, 2, 3, 1, 1 }, { "r8_complex2", GL_R8, 13, 17, 11, 23, 15, 2, 3, 1, 2 }, { "r8_complex3", GL_R8, 13, 17, 11, 23, 15, 2, 3, 1, 4 }, { "r8_complex4", GL_R8, 13, 17, 11, 23, 15, 2, 3, 1, 8 }, { "rgba8_complex1", GL_RGBA8, 11, 20, 8, 25, 14, 0, 0, 0, 8 }, { "rgba8_complex2", GL_RGBA8, 11, 20, 8, 25, 14, 0, 2, 0, 8 }, { "rgba8_complex3", GL_RGBA8, 11, 20, 8, 25, 14, 0, 0, 3, 8 }, { "rgba8_complex4", GL_RGBA8, 11, 20, 8, 25, 14, 0, 2, 3, 8 }, { "rgba32f_complex", GL_RGBA32F, 11, 20, 8, 25, 14, 0, 2, 3, 8 } }; for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cases); ndx++) paramGroup->addChild(new TexImage3DParamsCase(m_context, cases[ndx].name, "", cases[ndx].format, cases[ndx].width, cases[ndx].height, cases[ndx].depth, cases[ndx].imageHeight, cases[ndx].rowLength, cases[ndx].skipImages, cases[ndx].skipRows, cases[ndx].skipPixels, cases[ndx].alignment)); } // 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; deUint32 format; int width; int height; int depth; int imageHeight; int rowLength; int skipImages; int skipRows; int skipPixels; int alignment; int offset; } parameterCases[] = { { "rgb8_offset", GL_RGB8, 23, 19, 8, 0, 0, 0, 0, 0, 1, 67 }, { "rgb8_alignment", GL_RGB8, 23, 19, 8, 0, 0, 0, 0, 0, 2, 0 }, { "rgb8_image_height", GL_RGB8, 23, 19, 8, 26, 0, 0, 0, 0, 4, 0 }, { "rgb8_row_length", GL_RGB8, 23, 19, 8, 0, 27, 0, 0, 0, 4, 0 }, { "rgb8_skip_images", GL_RGB8, 23, 19, 8, 0, 0, 3, 0, 0, 4, 0 }, { "rgb8_skip_rows", GL_RGB8, 23, 19, 8, 22, 0, 0, 3, 0, 4, 0 }, { "rgb8_skip_pixels", GL_RGB8, 23, 19, 8, 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 deUint32 format = colorFormats[formatNdx].internalFormat; const int tex3DWidth = 11; const int tex3DHeight = 20; const int tex3DDepth = 8; pboGroup->addChild(new TexImage2DArrayBufferCase (m_context, (fmtName + "_2d_array").c_str(), "", format, tex3DWidth, tex3DHeight, tex3DDepth, 0, 0, 0, 0, 0, 4, 0)); pboGroup->addChild(new TexImage3DBufferCase (m_context, (fmtName + "_3d").c_str(), "", format, tex3DWidth, tex3DHeight, tex3DDepth, 0, 0, 0, 0, 0, 4, 0)); } for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(parameterCases); ndx++) { pboGroup->addChild(new TexImage2DArrayBufferCase(m_context, (string(parameterCases[ndx].name) + "_2d_array").c_str(), "", parameterCases[ndx].format, parameterCases[ndx].width, parameterCases[ndx].depth, parameterCases[ndx].height, parameterCases[ndx].imageHeight, parameterCases[ndx].rowLength, parameterCases[ndx].skipImages, parameterCases[ndx].skipRows, parameterCases[ndx].skipPixels, parameterCases[ndx].alignment, parameterCases[ndx].offset)); pboGroup->addChild(new TexImage3DBufferCase(m_context, (string(parameterCases[ndx].name) + "_3d").c_str(), "", parameterCases[ndx].format, parameterCases[ndx].width, parameterCases[ndx].depth, parameterCases[ndx].height, 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 tex3DWidth = 32; const int tex3DHeight = 64; const int tex3DDepth = 8; shadow3dGroup->addChild(new TexImage2DArrayDepthCase(m_context, (std::string(depthStencilFormats[ndx].name) + "_2d_array").c_str(), "", depthStencilFormats[ndx].internalFormat, tex3DWidth, tex3DHeight, tex3DDepth)); } } // 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 tex3DWidth = 32; const int tex3DHeight = 64; const int tex3DDepth = 8; shadow3dGroup->addChild(new TexImage2DArrayDepthBufferCase(m_context, (std::string(depthStencilFormats[ndx].name) + "_2d_array").c_str(), "", depthStencilFormats[ndx].internalFormat, tex3DWidth, tex3DHeight, tex3DDepth)); } } // Basic TexSubImage3D usage. { tcu::TestCaseGroup* basicTexSubImageGroup = new tcu::TestCaseGroup(m_testCtx, "basic_texsubimage3d", "Basic glTexSubImage3D() usage"); addChild(basicTexSubImageGroup); for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++) { const char* fmtName = colorFormats[formatNdx].name; deUint32 format = colorFormats[formatNdx].internalFormat; const int tex3DWidth = 32; const int tex3DHeight = 64; const int tex3DDepth = 8; basicTexSubImageGroup->addChild(new BasicTexSubImage3DCase(m_context, (string(fmtName) + "_3d").c_str(), "", format, tex3DWidth, tex3DHeight, tex3DDepth)); } } // glTexSubImage3D() unpack params cases. { tcu::TestCaseGroup* paramGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage3d_unpack_params", "glTexSubImage3D() unpack parameters"); addChild(paramGroup); static const struct { const char* name; deUint32 format; int width; int height; 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; } cases[] = { { "rgb8_image_height", GL_RGB8, 26, 25, 10, 1, 2, 1, 23, 19, 8, 26, 0, 0, 0, 0, 4 }, { "rgb8_row_length", GL_RGB8, 26, 25, 10, 1, 2, 1, 23, 19, 8, 0, 27, 0, 0, 0, 4 }, { "rgb8_skip_images", GL_RGB8, 26, 25, 10, 1, 2, 1, 23, 19, 8, 0, 0, 3, 0, 0, 4 }, { "rgb8_skip_rows", GL_RGB8, 26, 25, 10, 1, 2, 1, 23, 19, 8, 22, 0, 0, 3, 0, 4 }, { "rgb8_skip_pixels", GL_RGB8, 26, 25, 10, 1, 2, 1, 23, 19, 8, 0, 25, 0, 0, 2, 4 }, { "r8_complex1", GL_R8, 15, 20, 11, 1, 1, 0, 13, 17, 11, 23, 15, 2, 3, 1, 1 }, { "r8_complex2", GL_R8, 15, 20, 11, 1, 1, 0, 13, 17, 11, 23, 15, 2, 3, 1, 2 }, { "r8_complex3", GL_R8, 15, 20, 11, 1, 1, 0, 13, 17, 11, 23, 15, 2, 3, 1, 4 }, { "r8_complex4", GL_R8, 15, 20, 11, 1, 1, 0, 13, 17, 11, 23, 15, 2, 3, 1, 8 }, { "rgba8_complex1", GL_RGBA8, 15, 25, 10, 0, 5, 1, 11, 20, 8, 25, 14, 0, 0, 0, 8 }, { "rgba8_complex2", GL_RGBA8, 15, 25, 10, 0, 5, 1, 11, 20, 8, 25, 14, 0, 2, 0, 8 }, { "rgba8_complex3", GL_RGBA8, 15, 25, 10, 0, 5, 1, 11, 20, 8, 25, 14, 0, 0, 3, 8 }, { "rgba8_complex4", GL_RGBA8, 15, 25, 10, 0, 5, 1, 11, 20, 8, 25, 14, 0, 2, 3, 8 }, { "rgba32f_complex", GL_RGBA32F, 15, 25, 10, 0, 5, 1, 11, 20, 8, 25, 14, 0, 2, 3, 8 } }; for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cases); ndx++) paramGroup->addChild(new TexSubImage3DParamsCase(m_context, cases[ndx].name, "", cases[ndx].format, cases[ndx].width, cases[ndx].height, cases[ndx].depth, cases[ndx].subX, cases[ndx].subY, cases[ndx].subZ, cases[ndx].subW, cases[ndx].subH, cases[ndx].subD, cases[ndx].imageHeight, cases[ndx].rowLength, cases[ndx].skipImages, cases[ndx].skipRows, cases[ndx].skipPixels, cases[ndx].alignment)); } // 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; deUint32 format; int width; int height; 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, 25, 10, 1, 2, 1, 23, 19, 8, 0, 0, 0, 0, 0, 4, 67 }, { "rgb8_image_height", GL_RGB8, 26, 25, 10, 1, 2, 1, 23, 19, 8, 26, 0, 0, 0, 0, 4, 0 }, { "rgb8_row_length", GL_RGB8, 26, 25, 10, 1, 2, 1, 23, 19, 8, 0, 27, 0, 0, 0, 4, 0 }, { "rgb8_skip_images", GL_RGB8, 26, 25, 10, 1, 2, 1, 23, 19, 8, 0, 0, 3, 0, 0, 4, 0 }, { "rgb8_skip_rows", GL_RGB8, 26, 25, 10, 1, 2, 1, 23, 19, 8, 22, 0, 0, 3, 0, 4, 0 }, { "rgb8_skip_pixels", GL_RGB8, 26, 25, 10, 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 TexSubImage2DArrayBufferCase(m_context, (std::string(colorFormats[ndx].name) + "_2d_array").c_str(), "", colorFormats[ndx].internalFormat, 26, // Width 25, // Height 10, // 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 */)); pboGroup->addChild(new TexSubImage3DBufferCase(m_context, (std::string(colorFormats[ndx].name) + "_3d").c_str(), "", colorFormats[ndx].internalFormat, 26, // Width 25, // Height 10, // 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 TexSubImage2DArrayBufferCase(m_context, (std::string(paramCases[ndx].name) + "_2d_array").c_str(), "", paramCases[ndx].format, paramCases[ndx].width, paramCases[ndx].height, 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)); pboGroup->addChild(new TexSubImage3DBufferCase(m_context, (std::string(paramCases[ndx].name) + "_3d").c_str(), "", paramCases[ndx].format, paramCases[ndx].width, paramCases[ndx].height, 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 tex2DArrayWidth = 57; const int tex2DArrayHeight = 44; const int tex2DArrayLevels = 5; shadow3dGroup->addChild(new TexSubImage2DArrayDepthCase(m_context, (std::string(depthStencilFormats[ndx].name) + "_2d_array").c_str(), "", depthStencilFormats[ndx].internalFormat, tex2DArrayWidth, tex2DArrayHeight, tex2DArrayLevels)); } } // glTexStorage2D() cases. { tcu::TestCaseGroup* texStorageGroup = new tcu::TestCaseGroup(m_testCtx, "texstorage2d", "Basic glTexStorage2D() usage"); addChild(texStorageGroup); // All formats. tcu::TestCaseGroup* formatGroup = new tcu::TestCaseGroup(m_testCtx, "format", "glTexStorage2D() 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; deUint32 internalFormat = colorFormats[formatNdx].internalFormat; const int tex2DWidth = 117; const int tex2DHeight = 97; int tex2DLevels = maxLevelCount(tex2DWidth, tex2DHeight); const int cubeSize = 57; int cubeLevels = maxLevelCount(cubeSize, cubeSize); formatGroup->addChild(new BasicTexStorage2DCase (m_context, (string(fmtName) + "_2d").c_str(), "", internalFormat, tex2DWidth, tex2DHeight, tex2DLevels)); formatGroup->addChild(new BasicTexStorageCubeCase (m_context, (string(fmtName) + "_cube").c_str(), "", internalFormat, cubeSize, cubeLevels)); } // Depth / stencil formats. for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(depthStencilFormats); formatNdx++) { const char* fmtName = depthStencilFormats[formatNdx].name; deUint32 internalFormat = depthStencilFormats[formatNdx].internalFormat; const int tex2DWidth = 117; const int tex2DHeight = 97; int tex2DLevels = maxLevelCount(tex2DWidth, tex2DHeight); const int cubeSize = 57; int cubeLevels = maxLevelCount(cubeSize, cubeSize); formatGroup->addChild(new BasicTexStorage2DCase (m_context, (string(fmtName) + "_2d").c_str(), "", internalFormat, tex2DWidth, tex2DHeight, tex2DLevels)); formatGroup->addChild(new BasicTexStorageCubeCase (m_context, (string(fmtName) + "_cube").c_str(), "", internalFormat, cubeSize, cubeLevels)); } // Sizes. static const struct { int width; int height; int levels; } tex2DSizes[] = { // W H L { 1, 1, 1 }, { 2, 2, 2 }, { 64, 32, 7 }, { 32, 64, 4 }, { 57, 63, 1 }, { 57, 63, 2 }, { 57, 63, 6 } }; static const struct { int size; int levels; } cubeSizes[] = { // S L { 1, 1 }, { 2, 2 }, { 57, 1 }, { 57, 2 }, { 57, 6 }, { 64, 4 }, { 64, 7 }, }; tcu::TestCaseGroup* sizeGroup = new tcu::TestCaseGroup(m_testCtx, "size", "glTexStorage2D() with various sizes"); texStorageGroup->addChild(sizeGroup); for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(tex2DSizes); ndx++) { const deUint32 format = GL_RGBA8; int width = tex2DSizes[ndx].width; int height = tex2DSizes[ndx].height; int levels = tex2DSizes[ndx].levels; string name = string("2d_") + de::toString(width) + "x" + de::toString(height) + "_" + de::toString(levels) + "_levels"; sizeGroup->addChild(new BasicTexStorage2DCase(m_context, name.c_str(), "", format, width, height, levels)); } for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cubeSizes); ndx++) { const deUint32 format = GL_RGBA8; int size = cubeSizes[ndx].size; int levels = cubeSizes[ndx].levels; string name = string("cube_") + de::toString(size) + "x" + de::toString(size) + "_" + de::toString(levels) + "_levels"; sizeGroup->addChild(new BasicTexStorageCubeCase(m_context, name.c_str(), "", format, size, levels)); } } // 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; deUint32 internalFormat = colorFormats[formatNdx].internalFormat; const int tex2DArrayWidth = 57; const int tex2DArrayHeight = 13; const int tex2DArrayLayers = 7; int tex2DArrayLevels = maxLevelCount(tex2DArrayWidth, tex2DArrayHeight); const int tex3DWidth = 59; const int tex3DHeight = 37; const int tex3DDepth = 11; int tex3DLevels = maxLevelCount(tex3DWidth, tex3DHeight, tex3DDepth); formatGroup->addChild(new BasicTexStorage2DArrayCase (m_context, (string(fmtName) + "_2d_array").c_str(), "", internalFormat, tex2DArrayWidth, tex2DArrayHeight, tex2DArrayLayers, tex2DArrayLevels)); formatGroup->addChild(new BasicTexStorage3DCase (m_context, (string(fmtName) + "_3d").c_str(), "", internalFormat, tex3DWidth, tex3DHeight, tex3DDepth, tex3DLevels)); } // 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; deUint32 internalFormat = depthStencilFormats[formatNdx].internalFormat; const int tex2DArrayWidth = 57; const int tex2DArrayHeight = 13; const int tex2DArrayLayers = 7; int tex2DArrayLevels = maxLevelCount(tex2DArrayWidth, tex2DArrayHeight); formatGroup->addChild(new BasicTexStorage2DArrayCase (m_context, (string(fmtName) + "_2d_array").c_str(), "", internalFormat, tex2DArrayWidth, tex2DArrayHeight, tex2DArrayLayers, tex2DArrayLevels)); } // Sizes. static const struct { int width; int height; int layers; int levels; } tex2DArraySizes[] = { // W H La Le { 1, 1, 1, 1 }, { 2, 2, 2, 2 }, { 64, 32, 3, 7 }, { 32, 64, 3, 4 }, { 57, 63, 5, 1 }, { 57, 63, 5, 2 }, { 57, 63, 5, 6 } }; static const struct { int width; int height; int depth; int levels; } tex3DSizes[] = { // W H D L { 1, 1, 1, 1 }, { 2, 2, 2, 2 }, { 64, 32, 16, 7 }, { 32, 64, 16, 4 }, { 32, 16, 64, 4 }, { 57, 63, 11, 1 }, { 57, 63, 11, 2 }, { 57, 63, 11, 6 } }; tcu::TestCaseGroup* sizeGroup = new tcu::TestCaseGroup(m_testCtx, "size", "glTexStorage2D() with various sizes"); texStorageGroup->addChild(sizeGroup); for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(tex2DArraySizes); ndx++) { const deUint32 format = GL_RGBA8; int width = tex2DArraySizes[ndx].width; int height = tex2DArraySizes[ndx].height; int layers = tex2DArraySizes[ndx].layers; int levels = tex2DArraySizes[ndx].levels; string name = string("2d_array_") + de::toString(width) + "x" + de::toString(height) + "x" + de::toString(layers) + "_" + de::toString(levels) + "_levels"; sizeGroup->addChild(new BasicTexStorage2DArrayCase(m_context, name.c_str(), "", format, width, height, layers, levels)); } for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(tex3DSizes); ndx++) { const deUint32 format = GL_RGBA8; int width = tex3DSizes[ndx].width; int height = tex3DSizes[ndx].height; int depth = tex3DSizes[ndx].depth; int levels = tex3DSizes[ndx].levels; string name = string("3d_") + de::toString(width) + "x" + de::toString(height) + "x" + de::toString(depth) + "_" + de::toString(levels) + "_levels"; sizeGroup->addChild(new BasicTexStorage3DCase(m_context, name.c_str(), "", format, width, height, depth, levels)); } } } } // Functional } // gles3 } // deqp