/*------------------------------------------------------------------------- * drawElements Quality Program OpenGL ES 3.1 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 level state query tests *//*--------------------------------------------------------------------*/ #include "es31fTextureLevelStateQueryTests.hpp" #include "glsStateQueryUtil.hpp" #include "tcuTestLog.hpp" #include "gluRenderContext.hpp" #include "gluCallLogWrapper.hpp" #include "gluTextureUtil.hpp" #include "gluStrUtil.hpp" #include "gluContextInfo.hpp" #include "glwFunctions.hpp" #include "glwEnums.hpp" #include "deStringUtil.hpp" #include "tcuTextureUtil.hpp" namespace deqp { namespace gles31 { namespace Functional { namespace { enum VerifierType { VERIFIER_INT = 0, VERIFIER_FLOAT }; struct TextureGenerationSpec { struct TextureLevelSpec { int width; int height; int depth; int level; glw::GLenum internalFormat; bool compressed; }; glw::GLenum bindTarget; glw::GLenum queryTarget; bool immutable; bool fixedSamplePos; // !< fixed sample pos argument for multisample textures int sampleCount; std::vector<TextureLevelSpec> levels; std::string description; }; static bool textureTypeHasDepth (glw::GLenum textureBindTarget) { switch (textureBindTarget) { case GL_TEXTURE_2D: return false; case GL_TEXTURE_3D: return true; case GL_TEXTURE_2D_ARRAY: return true; case GL_TEXTURE_CUBE_MAP: return false; case GL_TEXTURE_2D_MULTISAMPLE: return false; case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: return true; default: DE_ASSERT(DE_FALSE); return false; } } struct IntegerPrinter { static std::string getIntegerName (int v) { return de::toString(v); } static std::string getFloatName (float v) { return de::toString(v); } }; struct PixelFormatPrinter { static std::string getIntegerName (int v) { return de::toString(glu::getPixelFormatStr(v)); } static std::string getFloatName (float v) { return de::toString(glu::getPixelFormatStr((int)v)); } }; template <typename Printer> static bool verifyTextureLevelParameterEqualWithPrinter (glu::CallLogWrapper& gl, glw::GLenum target, int level, glw::GLenum pname, int refValue, VerifierType type) { gl.getLog() << tcu::TestLog::Message << "Verifying " << glu::getTextureLevelParameterStr(pname) << ", expecting " << Printer::getIntegerName(refValue) << tcu::TestLog::EndMessage; if (type == VERIFIER_INT) { gls::StateQueryUtil::StateQueryMemoryWriteGuard<int> result; gl.glGetTexLevelParameteriv(target, level, pname, &result); GLU_EXPECT_NO_ERROR(gl.glGetError(), "glGetTexLevelParameteriv"); if (result.isUndefined()) { gl.getLog() << tcu::TestLog::Message << "Error: Get* did not write a value." << tcu::TestLog::EndMessage; return false; } else if (result.isMemoryContaminated()) { gl.getLog() << tcu::TestLog::Message << "Error: detected illegal memory write." << tcu::TestLog::EndMessage; return false; } if (result == refValue) return true; gl.getLog() << tcu::TestLog::Message << "Error: Expected " << Printer::getIntegerName(refValue) << ", got " << Printer::getIntegerName(result) << tcu::TestLog::EndMessage; return false; } else if (type == VERIFIER_FLOAT) { gls::StateQueryUtil::StateQueryMemoryWriteGuard<float> result; gl.glGetTexLevelParameterfv(target, level, pname, &result); GLU_EXPECT_NO_ERROR(gl.glGetError(), "glGetTexLevelParameterfv"); if (result.isUndefined()) { gl.getLog() << tcu::TestLog::Message << "Error: Get* did not write a value." << tcu::TestLog::EndMessage; return false; } else if (result.isMemoryContaminated()) { gl.getLog() << tcu::TestLog::Message << "Error: detected illegal memory write." << tcu::TestLog::EndMessage; return false; } if (result == (float)refValue) return true; gl.getLog() << tcu::TestLog::Message << "Error: Expected " << Printer::getIntegerName(refValue) << ", got " << Printer::getFloatName(result) << tcu::TestLog::EndMessage; return false; } DE_ASSERT(DE_FALSE); return false; } static bool verifyTextureLevelParameterEqual (glu::CallLogWrapper& gl, glw::GLenum target, int level, glw::GLenum pname, int refValue, VerifierType type) { return verifyTextureLevelParameterEqualWithPrinter<IntegerPrinter>(gl, target, level, pname, refValue, type); } static bool verifyTextureLevelParameterInternalFormatEqual (glu::CallLogWrapper& gl, glw::GLenum target, int level, glw::GLenum pname, int refValue, VerifierType type) { return verifyTextureLevelParameterEqualWithPrinter<PixelFormatPrinter>(gl, target, level, pname, refValue, type); } static bool verifyTextureLevelParameterGreaterOrEqual (glu::CallLogWrapper& gl, glw::GLenum target, int level, glw::GLenum pname, int refValue, VerifierType type) { gl.getLog() << tcu::TestLog::Message << "Verifying " << glu::getTextureLevelParameterStr(pname) << ", expecting " << refValue << " or greater" << tcu::TestLog::EndMessage; if (type == VERIFIER_INT) { gls::StateQueryUtil::StateQueryMemoryWriteGuard<int> result; gl.glGetTexLevelParameteriv(target, level, pname, &result); GLU_EXPECT_NO_ERROR(gl.glGetError(), "glGetTexLevelParameteriv"); if (result.isUndefined()) { gl.getLog() << tcu::TestLog::Message << "Error: Get* did not write a value." << tcu::TestLog::EndMessage; return false; } else if (result.isMemoryContaminated()) { gl.getLog() << tcu::TestLog::Message << "Error: detected illegal memory write." << tcu::TestLog::EndMessage; return false; } if (result >= refValue) return true; gl.getLog() << tcu::TestLog::Message << "Error: Expected " << refValue << " or larger, got " << result << tcu::TestLog::EndMessage; return false; } else if (type == VERIFIER_FLOAT) { gls::StateQueryUtil::StateQueryMemoryWriteGuard<float> result; gl.glGetTexLevelParameterfv(target, level, pname, &result); GLU_EXPECT_NO_ERROR(gl.glGetError(), "glGetTexLevelParameterfv"); if (result.isUndefined()) { gl.getLog() << tcu::TestLog::Message << "Error: Get* did not write a value." << tcu::TestLog::EndMessage; return false; } else if (result.isMemoryContaminated()) { gl.getLog() << tcu::TestLog::Message << "Error: detected illegal memory write." << tcu::TestLog::EndMessage; return false; } if (result >= (float)refValue) return true; gl.getLog() << tcu::TestLog::Message << "Error: Expected " << refValue << " or larger, got " << result << tcu::TestLog::EndMessage; return false; } DE_ASSERT(DE_FALSE); return false; } static bool verifyTextureLevelParameterInternalFormatAnyOf (glu::CallLogWrapper& gl, glw::GLenum target, int level, glw::GLenum pname, const int* refValues, int numRefValues, VerifierType type) { // Log what we try to do { tcu::MessageBuilder msg(&gl.getLog()); msg << "Verifying " << glu::getTextureLevelParameterStr(pname) << ", expecting any of {"; for (int ndx = 0; ndx < numRefValues; ++ndx) { if (ndx != 0) msg << ", "; msg << glu::getPixelFormatStr(refValues[ndx]); } msg << "}"; msg << tcu::TestLog::EndMessage; } // verify if (type == VERIFIER_INT) { gls::StateQueryUtil::StateQueryMemoryWriteGuard<int> result; gl.glGetTexLevelParameteriv(target, level, pname, &result); GLU_EXPECT_NO_ERROR(gl.glGetError(), "glGetTexLevelParameteriv"); if (result.isUndefined()) { gl.getLog() << tcu::TestLog::Message << "Error: Get* did not write a value." << tcu::TestLog::EndMessage; return false; } else if (result.isMemoryContaminated()) { gl.getLog() << tcu::TestLog::Message << "Error: detected illegal memory write." << tcu::TestLog::EndMessage; return false; } for (int ndx = 0; ndx < numRefValues; ++ndx) if (result == refValues[ndx]) return true; gl.getLog() << tcu::TestLog::Message << "Error: got " << result << ", (" << glu::getPixelFormatStr(result) << ")" << tcu::TestLog::EndMessage; return false; } else if (type == VERIFIER_FLOAT) { gls::StateQueryUtil::StateQueryMemoryWriteGuard<float> result; gl.glGetTexLevelParameterfv(target, level, pname, &result); GLU_EXPECT_NO_ERROR(gl.glGetError(), "glGetTexLevelParameterfv"); if (result.isUndefined()) { gl.getLog() << tcu::TestLog::Message << "Error: Get* did not write a value." << tcu::TestLog::EndMessage; return false; } else if (result.isMemoryContaminated()) { gl.getLog() << tcu::TestLog::Message << "Error: detected illegal memory write." << tcu::TestLog::EndMessage; return false; } for (int ndx = 0; ndx < numRefValues; ++ndx) if (result == (float)refValues[ndx]) return true; gl.getLog() << tcu::TestLog::Message << "Error: got " << result << ", (" << glu::getPixelFormatStr((int)result) << ")" << tcu::TestLog::EndMessage; return false; } DE_ASSERT(DE_FALSE); return false; } static void generateColorTextureGenerationGroup (std::vector<TextureGenerationSpec>& group, int max2DSamples, int max2DArraySamples, glw::GLenum internalFormat) { // initial setups static const struct InitialSetup { glw::GLenum bindTarget; glw::GLenum queryTarget; bool immutable; const char* description; } initialSetups[] = { { GL_TEXTURE_2D, GL_TEXTURE_2D, true, "GL_TEXTURE_2D, initial values" }, { GL_TEXTURE_3D, GL_TEXTURE_3D, true, "GL_TEXTURE_3D, initial values" }, { GL_TEXTURE_2D_ARRAY, GL_TEXTURE_2D_ARRAY, true, "GL_TEXTURE_2D_ARRAY, initial values" }, { GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, true, "GL_TEXTURE_CUBE_MAP, initial values" }, { GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_2D_MULTISAMPLE, true, "GL_TEXTURE_2D_MULTISAMPLE, initial values" }, { GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_TEXTURE_2D_MULTISAMPLE_ARRAY,true, "GL_TEXTURE_2D_MULTISAMPLE_ARRAY, initial values" }, }; // multisample setups static const struct MultisampleSetup { glw::GLenum bindTarget; int sampleCount; const char* description; } msSetups[] = { { GL_TEXTURE_2D_MULTISAMPLE, 1, "immutable GL_TEXTURE_2D_MULTISAMPLE, low sample count" }, { GL_TEXTURE_2D_MULTISAMPLE, max2DSamples, "immutable GL_TEXTURE_2D_MULTISAMPLE, max sample count" }, { GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 1, "immutable GL_TEXTURE_2D_MULTISAMPLE_ARRAY, low sample count" }, { GL_TEXTURE_2D_MULTISAMPLE_ARRAY, max2DArraySamples, "immutable GL_TEXTURE_2D_MULTISAMPLE_ARRAY, max sample count" }, }; // normal setups static const struct NormalSetup { glw::GLenum bindTarget; glw::GLenum queryTarget; bool immutable; int level; const char* description; } normalSetups[] = { { GL_TEXTURE_2D, GL_TEXTURE_2D, true, 0, "immutable GL_TEXTURE_2D" }, { GL_TEXTURE_3D, GL_TEXTURE_3D, true, 0, "immutable GL_TEXTURE_3D" }, { GL_TEXTURE_2D_ARRAY, GL_TEXTURE_2D_ARRAY, true, 0, "immutable GL_TEXTURE_2D_ARRAY" }, { GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, true, 0, "immutable GL_TEXTURE_CUBE_MAP" }, { GL_TEXTURE_2D, GL_TEXTURE_2D, false, 0, "mutable GL_TEXTURE_2D" }, { GL_TEXTURE_3D, GL_TEXTURE_3D, false, 0, "mutable GL_TEXTURE_3D" }, { GL_TEXTURE_2D_ARRAY, GL_TEXTURE_2D_ARRAY, false, 0, "mutable GL_TEXTURE_2D_ARRAY" }, { GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, false, 0, "mutable GL_TEXTURE_CUBE_MAP" }, { GL_TEXTURE_2D, GL_TEXTURE_2D, false, 3, "mutable GL_TEXTURE_2D, mip level 3" }, { GL_TEXTURE_3D, GL_TEXTURE_3D, false, 3, "mutable GL_TEXTURE_3D, mip level 3" }, { GL_TEXTURE_2D_ARRAY, GL_TEXTURE_2D_ARRAY, false, 3, "mutable GL_TEXTURE_2D_ARRAY, mip level 3" }, { GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, false, 3, "mutable GL_TEXTURE_CUBE_MAP, mip level 3" }, }; for (int initialSetupNdx = 0; initialSetupNdx < DE_LENGTH_OF_ARRAY(initialSetups); ++initialSetupNdx) { TextureGenerationSpec texGen; texGen.bindTarget = initialSetups[initialSetupNdx].bindTarget; texGen.queryTarget = initialSetups[initialSetupNdx].queryTarget; texGen.immutable = initialSetups[initialSetupNdx].immutable; texGen.sampleCount = 0; texGen.description = initialSetups[initialSetupNdx].description; group.push_back(texGen); } for (int msSetupNdx = 0; msSetupNdx < DE_LENGTH_OF_ARRAY(msSetups); ++msSetupNdx) { TextureGenerationSpec texGen; TextureGenerationSpec::TextureLevelSpec level; texGen.bindTarget = msSetups[msSetupNdx].bindTarget; texGen.queryTarget = msSetups[msSetupNdx].bindTarget; texGen.immutable = true; texGen.sampleCount = msSetups[msSetupNdx].sampleCount; texGen.fixedSamplePos = false; texGen.description = msSetups[msSetupNdx].description; level.width = 32; level.height = 32; level.depth = (textureTypeHasDepth(texGen.bindTarget)) ? (8) : (0); level.level = 0; level.internalFormat = internalFormat; level.compressed = false; texGen.levels.push_back(level); group.push_back(texGen); } for (int normalSetupNdx = 0; normalSetupNdx < DE_LENGTH_OF_ARRAY(normalSetups); ++normalSetupNdx) { TextureGenerationSpec texGen; TextureGenerationSpec::TextureLevelSpec level; texGen.bindTarget = normalSetups[normalSetupNdx].bindTarget; texGen.queryTarget = normalSetups[normalSetupNdx].queryTarget; texGen.immutable = normalSetups[normalSetupNdx].immutable; texGen.sampleCount = 0; texGen.description = normalSetups[normalSetupNdx].description; level.width = 32; level.height = 32; level.depth = (textureTypeHasDepth(texGen.bindTarget)) ? (8) : (0); level.level = normalSetups[normalSetupNdx].level; level.internalFormat = internalFormat; level.compressed = false; texGen.levels.push_back(level); group.push_back(texGen); } } static void generateColorMultisampleTextureGenerationGroup (std::vector<TextureGenerationSpec>& group, int max2DSamples, int max2DArraySamples, glw::GLenum internalFormat) { // multisample setups static const struct MultisampleSetup { glw::GLenum bindTarget; bool initialized; int sampleCount; bool fixedSamples; const char* description; } msSetups[] = { { GL_TEXTURE_2D_MULTISAMPLE, false, 0, false, "GL_TEXTURE_2D_MULTISAMPLE, initial values" }, { GL_TEXTURE_2D_MULTISAMPLE, true, 1, false, "GL_TEXTURE_2D_MULTISAMPLE, low sample count" }, { GL_TEXTURE_2D_MULTISAMPLE, true, max2DSamples, false, "GL_TEXTURE_2D_MULTISAMPLE, max sample count" }, { GL_TEXTURE_2D_MULTISAMPLE, true, max2DSamples, true, "GL_TEXTURE_2D_MULTISAMPLE, fixed sample positions" }, { GL_TEXTURE_2D_MULTISAMPLE_ARRAY, false, 0, false, "GL_TEXTURE_2D_MULTISAMPLE_ARRAY, initial values" }, { GL_TEXTURE_2D_MULTISAMPLE_ARRAY, true, 1, false, "GL_TEXTURE_2D_MULTISAMPLE_ARRAY, low sample count" }, { GL_TEXTURE_2D_MULTISAMPLE_ARRAY, true, max2DArraySamples, false, "GL_TEXTURE_2D_MULTISAMPLE_ARRAY, max sample count" }, { GL_TEXTURE_2D_MULTISAMPLE_ARRAY, true, max2DArraySamples, true, "GL_TEXTURE_2D_MULTISAMPLE_ARRAY, fixed sample positions" }, }; for (int msSetupNdx = 0; msSetupNdx < DE_LENGTH_OF_ARRAY(msSetups); ++msSetupNdx) { TextureGenerationSpec texGen; texGen.bindTarget = msSetups[msSetupNdx].bindTarget; texGen.queryTarget = msSetups[msSetupNdx].bindTarget; texGen.immutable = true; texGen.sampleCount = msSetups[msSetupNdx].sampleCount; texGen.fixedSamplePos = msSetups[msSetupNdx].fixedSamples; texGen.description = msSetups[msSetupNdx].description; if (msSetups[msSetupNdx].initialized) { TextureGenerationSpec::TextureLevelSpec level; level.width = 32; level.height = 32; level.depth = (textureTypeHasDepth(texGen.bindTarget)) ? (8) : (0); level.level = 0; level.internalFormat = internalFormat; level.compressed = false; texGen.levels.push_back(level); } group.push_back(texGen); } } static void generateInternalFormatTextureGenerationGroup (std::vector<TextureGenerationSpec>& group) { // initial setups static const struct InitialSetup { glw::GLenum bindTarget; glw::GLenum queryTarget; bool immutable; const char* description; } initialSetups[] = { { GL_TEXTURE_2D, GL_TEXTURE_2D, true, "GL_TEXTURE_2D, initial values" }, { GL_TEXTURE_3D, GL_TEXTURE_3D, true, "GL_TEXTURE_3D, initial values" }, { GL_TEXTURE_2D_ARRAY, GL_TEXTURE_2D_ARRAY, true, "GL_TEXTURE_2D_ARRAY, initial values" }, { GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, true, "GL_TEXTURE_CUBE_MAP, initial values" }, { GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_2D_MULTISAMPLE, true, "GL_TEXTURE_2D_MULTISAMPLE, initial values" }, { GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_TEXTURE_2D_MULTISAMPLE_ARRAY,true, "GL_TEXTURE_2D_MULTISAMPLE_ARRAY, initial values" }, }; // Renderable internal formats (subset) static const glw::GLenum renderableInternalFormats[] = { GL_R8, GL_RGB565, GL_RGB5_A1, GL_RGB10_A2UI, GL_SRGB8_ALPHA8, GL_RG32I, GL_RGBA16UI, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT32F, GL_DEPTH24_STENCIL8, GL_DEPTH32F_STENCIL8 }; // Internal formats static const glw::GLenum internalFormats[] = { GL_R8, GL_R8_SNORM, GL_RG8, GL_RG8_SNORM, GL_RGB8, GL_RGB8_SNORM, GL_RGB565, GL_RGBA4, GL_RGB5_A1, GL_RGBA8, GL_RGBA8_SNORM, GL_RGB10_A2, GL_RGB10_A2UI, GL_SRGB8, GL_SRGB8_ALPHA8, GL_R16F, GL_RG16F, GL_RGB16F, GL_RGBA16F, GL_R32F, GL_RG32F, GL_RGB32F, GL_RGBA32F, GL_R11F_G11F_B10F, GL_RGB9_E5, GL_R8I, GL_R8UI, GL_R16I, GL_R16UI, GL_R32I, GL_R32UI, GL_RG8I, GL_RG8UI, GL_RG16I, GL_RG16UI, GL_RG32I, GL_RG32UI, GL_RGB8I, GL_RGB8UI, GL_RGB16I, GL_RGB16UI, GL_RGB32I, GL_RGB32UI, GL_RGBA8I, GL_RGBA8UI, GL_RGBA16I, GL_RGBA16UI, GL_RGBA32I, GL_RGBA32UI, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT16, GL_DEPTH32F_STENCIL8, GL_DEPTH24_STENCIL8 }; for (int initialSetupNdx = 0; initialSetupNdx < DE_LENGTH_OF_ARRAY(initialSetups); ++initialSetupNdx) { TextureGenerationSpec texGen; texGen.bindTarget = initialSetups[initialSetupNdx].bindTarget; texGen.queryTarget = initialSetups[initialSetupNdx].queryTarget; texGen.immutable = initialSetups[initialSetupNdx].immutable; texGen.sampleCount = 0; texGen.description = initialSetups[initialSetupNdx].description; group.push_back(texGen); } // test some color/stencil/depth renderable with multisample texture2d for (int internalFormatNdx = 0; internalFormatNdx < DE_LENGTH_OF_ARRAY(renderableInternalFormats); ++internalFormatNdx) { TextureGenerationSpec texGen; TextureGenerationSpec::TextureLevelSpec level; texGen.bindTarget = GL_TEXTURE_2D_MULTISAMPLE; texGen.queryTarget = GL_TEXTURE_2D_MULTISAMPLE; texGen.immutable = true; texGen.sampleCount = 1; texGen.fixedSamplePos = false; texGen.description = std::string() + "GL_TEXTURE_2D_MULTISAMPLE, internal format " + glu::getPixelFormatName(renderableInternalFormats[internalFormatNdx]); level.width = 32; level.height = 32; level.depth = 0; level.level = 0; level.internalFormat = renderableInternalFormats[internalFormatNdx]; level.compressed = false; texGen.levels.push_back(level); group.push_back(texGen); } // test all with texture2d for (int internalFormatNdx = 0; internalFormatNdx < DE_LENGTH_OF_ARRAY(internalFormats); ++internalFormatNdx) { TextureGenerationSpec texGen; TextureGenerationSpec::TextureLevelSpec level; texGen.bindTarget = GL_TEXTURE_2D; texGen.queryTarget = GL_TEXTURE_2D; texGen.immutable = true; texGen.sampleCount = 0; texGen.description = std::string() + "GL_TEXTURE_2D, internal format " + glu::getPixelFormatName(internalFormats[internalFormatNdx]); level.width = 32; level.height = 32; level.depth = 0; level.level = 0; level.internalFormat = internalFormats[internalFormatNdx]; level.compressed = false; texGen.levels.push_back(level); group.push_back(texGen); } // test rgba8 with mip level 3 { TextureGenerationSpec texGen; TextureGenerationSpec::TextureLevelSpec level; texGen.bindTarget = GL_TEXTURE_2D; texGen.queryTarget = GL_TEXTURE_2D; texGen.immutable = false; texGen.sampleCount = 0; texGen.description = std::string() + "GL_TEXTURE_2D, internal format GL_RGBA8"; level.width = 32; level.height = 32; level.depth = 0; level.level = 3; level.internalFormat = GL_RGBA8; level.compressed = false; texGen.levels.push_back(level); group.push_back(texGen); } } static void generateCompressedTextureGenerationGroup (std::vector<TextureGenerationSpec>& group) { // initial ms { TextureGenerationSpec texGen; texGen.bindTarget = GL_TEXTURE_2D_MULTISAMPLE; texGen.queryTarget = GL_TEXTURE_2D_MULTISAMPLE; texGen.immutable = true; texGen.sampleCount = 0; texGen.description = "GL_TEXTURE_2D_MULTISAMPLE, initial values"; group.push_back(texGen); } // initial non-ms { TextureGenerationSpec texGen; texGen.bindTarget = GL_TEXTURE_2D; texGen.queryTarget = GL_TEXTURE_2D; texGen.immutable = true; texGen.sampleCount = 0; texGen.description = "GL_TEXTURE_2D, initial values"; group.push_back(texGen); } // compressed { TextureGenerationSpec texGen; TextureGenerationSpec::TextureLevelSpec level; texGen.bindTarget = GL_TEXTURE_2D; texGen.queryTarget = GL_TEXTURE_2D; texGen.immutable = false; texGen.sampleCount = 0; texGen.description = "GL_TEXTURE_2D, compressed"; level.width = 32; level.height = 32; level.depth = 0; level.level = 0; level.internalFormat = GL_COMPRESSED_RGB8_ETC2; level.compressed = true; texGen.levels.push_back(level); group.push_back(texGen); } } void applyTextureGenergationSpec (glu::CallLogWrapper& gl, const TextureGenerationSpec& spec) { DE_ASSERT(!(spec.immutable && spec.levels.size() > 1)); // !< immutable textures have only one level for (int levelNdx = 0; levelNdx < (int)spec.levels.size(); ++levelNdx) { const glu::TransferFormat transferFormat = (spec.levels[levelNdx].compressed) ? (glu::TransferFormat()) : (glu::getTransferFormat(glu::mapGLInternalFormat(spec.levels[levelNdx].internalFormat))); if (spec.immutable && !spec.levels[levelNdx].compressed && spec.bindTarget == GL_TEXTURE_2D) gl.glTexStorage2D(spec.bindTarget, 1, spec.levels[levelNdx].internalFormat, spec.levels[levelNdx].width, spec.levels[levelNdx].height); else if (spec.immutable && !spec.levels[levelNdx].compressed && spec.bindTarget == GL_TEXTURE_3D) gl.glTexStorage3D(spec.bindTarget, 1, spec.levels[levelNdx].internalFormat, spec.levels[levelNdx].width, spec.levels[levelNdx].height, spec.levels[levelNdx].depth); else if (spec.immutable && !spec.levels[levelNdx].compressed && spec.bindTarget == GL_TEXTURE_2D_ARRAY) gl.glTexStorage3D(spec.bindTarget, 1, spec.levels[levelNdx].internalFormat, spec.levels[levelNdx].width, spec.levels[levelNdx].height, spec.levels[levelNdx].depth); else if (spec.immutable && !spec.levels[levelNdx].compressed && spec.bindTarget == GL_TEXTURE_CUBE_MAP) gl.glTexStorage2D(spec.bindTarget, 1, spec.levels[levelNdx].internalFormat, spec.levels[levelNdx].width, spec.levels[levelNdx].height); else if (spec.immutable && !spec.levels[levelNdx].compressed && spec.bindTarget == GL_TEXTURE_2D_MULTISAMPLE) gl.glTexStorage2DMultisample(spec.bindTarget, spec.sampleCount, spec.levels[levelNdx].internalFormat, spec.levels[levelNdx].width, spec.levels[levelNdx].height, (spec.fixedSamplePos) ? (GL_TRUE) : (GL_FALSE)); else if (spec.immutable && !spec.levels[levelNdx].compressed && spec.bindTarget == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) gl.glTexStorage3DMultisample(spec.bindTarget, spec.sampleCount, spec.levels[levelNdx].internalFormat, spec.levels[levelNdx].width, spec.levels[levelNdx].height, spec.levels[levelNdx].depth, (spec.fixedSamplePos) ? (GL_TRUE) : (GL_FALSE)); else if (!spec.immutable && !spec.levels[levelNdx].compressed && spec.bindTarget == GL_TEXTURE_2D) gl.glTexImage2D(spec.bindTarget, spec.levels[levelNdx].level, spec.levels[levelNdx].internalFormat, spec.levels[levelNdx].width, spec.levels[levelNdx].height, 0, transferFormat.format, transferFormat.dataType, DE_NULL); else if (!spec.immutable && !spec.levels[levelNdx].compressed && spec.bindTarget == GL_TEXTURE_3D) gl.glTexImage3D(spec.bindTarget, spec.levels[levelNdx].level, spec.levels[levelNdx].internalFormat, spec.levels[levelNdx].width, spec.levels[levelNdx].height, spec.levels[levelNdx].depth, 0, transferFormat.format, transferFormat.dataType, DE_NULL); else if (!spec.immutable && !spec.levels[levelNdx].compressed && spec.bindTarget == GL_TEXTURE_2D_ARRAY) gl.glTexImage3D(spec.bindTarget, spec.levels[levelNdx].level, spec.levels[levelNdx].internalFormat, spec.levels[levelNdx].width, spec.levels[levelNdx].height, spec.levels[levelNdx].depth, 0, transferFormat.format, transferFormat.dataType, DE_NULL); else if (!spec.immutable && !spec.levels[levelNdx].compressed && spec.bindTarget == GL_TEXTURE_CUBE_MAP) gl.glTexImage2D(spec.queryTarget, spec.levels[levelNdx].level, spec.levels[levelNdx].internalFormat, spec.levels[levelNdx].width, spec.levels[levelNdx].height, 0, transferFormat.format, transferFormat.dataType, DE_NULL); else if (!spec.immutable && spec.levels[levelNdx].compressed && spec.bindTarget == GL_TEXTURE_2D) { DE_ASSERT(spec.levels[levelNdx].width == 32); DE_ASSERT(spec.levels[levelNdx].height == 32); DE_ASSERT(spec.levels[levelNdx].internalFormat == GL_COMPRESSED_RGB8_ETC2); static const deUint8 buffer[64 * 8] = { 0 }; gl.glCompressedTexImage2D(spec.bindTarget, spec.levels[levelNdx].level, spec.levels[levelNdx].internalFormat, spec.levels[levelNdx].width, spec.levels[levelNdx].height, 0, sizeof(buffer), buffer); } else DE_ASSERT(DE_FALSE); GLU_EXPECT_NO_ERROR(gl.glGetError(), "set level"); } } class TextureLevelCase : public TestCase { public: TextureLevelCase (Context& ctx, const char* name, const char* desc, VerifierType type); ~TextureLevelCase (void); void init (void); void deinit (void); IterateResult iterate (void); protected: void getFormatSamples (glw::GLenum target, std::vector<int>& samples); bool testConfig (const TextureGenerationSpec& spec); virtual bool checkTextureState (glu::CallLogWrapper& gl, const TextureGenerationSpec& spec) = 0; virtual void generateTestIterations (std::vector<TextureGenerationSpec>& iterations) = 0; const VerifierType m_type; const glw::GLenum m_internalFormat; glw::GLuint m_texture; private: int m_iteration; std::vector<TextureGenerationSpec> m_iterations; bool m_allIterationsOk; std::vector<int> m_failedIterations; }; TextureLevelCase::TextureLevelCase (Context& ctx, const char* name, const char* desc, VerifierType type) : TestCase (ctx, name, desc) , m_type (type) , m_internalFormat (GL_RGBA8) , m_texture (0) , m_iteration (0) , m_allIterationsOk (true) { } TextureLevelCase::~TextureLevelCase (void) { deinit(); } void TextureLevelCase::init (void) { generateTestIterations(m_iterations); } void TextureLevelCase::deinit (void) { if (m_texture) { m_context.getRenderContext().getFunctions().deleteTextures(1, &m_texture); m_texture = 0; } } void TextureLevelCase::getFormatSamples (glw::GLenum target, std::vector<int>& samples) { const glw::Functions gl = m_context.getRenderContext().getFunctions(); int sampleCount = -1; // fake values for unsupported queries to simplify code. The extension will be checked later for each config anyway (in testConfig()) if (target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY && !m_context.getContextInfo().isExtensionSupported("GL_OES_texture_storage_multisample_2d_array")) { samples.resize(1); samples[0] = 0; return; } gl.getInternalformativ(target, m_internalFormat, GL_NUM_SAMPLE_COUNTS, 1, &sampleCount); if (sampleCount < 0) throw tcu::TestError("internal format query failed"); samples.resize(sampleCount); if (sampleCount > 0) { gl.getInternalformativ(target, m_internalFormat, GL_SAMPLES, sampleCount, &samples[0]); GLU_EXPECT_NO_ERROR(gl.getError(), "get max samples"); } } TextureLevelCase::IterateResult TextureLevelCase::iterate (void) { const bool result = testConfig(m_iterations[m_iteration]); if (!result) { m_failedIterations.push_back(m_iteration); m_allIterationsOk = false; } if (++m_iteration < (int)m_iterations.size()) return CONTINUE; if (m_allIterationsOk) m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); else { tcu::MessageBuilder msg(&m_testCtx.getLog()); msg << "Following iteration(s) failed: "; for (int ndx = 0; ndx < (int)m_failedIterations.size(); ++ndx) { if (ndx) msg << ", "; msg << (m_failedIterations[ndx] + 1); } msg << tcu::TestLog::EndMessage; m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "One or more iterations failed"); } return STOP; } bool TextureLevelCase::testConfig (const TextureGenerationSpec& spec) { const tcu::ScopedLogSection section(m_testCtx.getLog(), "Iteration", std::string() + "Iteration " + de::toString(m_iteration+1) + "/" + de::toString((int)m_iterations.size()) + " - " + spec.description); glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); bool result; // skip unsupported targets if (spec.bindTarget == GL_TEXTURE_2D_MULTISAMPLE_ARRAY && !m_context.getContextInfo().isExtensionSupported("GL_OES_texture_storage_multisample_2d_array")) { m_testCtx.getLog() << tcu::TestLog::Message << "Target binding requires GL_OES_texture_storage_multisample_2d_array extension, skipping." << tcu::TestLog::EndMessage; return true; } // test supported targets gl.enableLogging(true); gl.glGenTextures(1, &m_texture); gl.glBindTexture(spec.bindTarget, m_texture); GLU_EXPECT_NO_ERROR(gl.glGetError(), "gen tex"); // Set the state applyTextureGenergationSpec(gl, spec); // Verify the state result = checkTextureState(gl, spec); gl.glDeleteTextures(1, &m_texture); m_texture = 0; return result; } /*--------------------------------------------------------------------*//*! * \brief Test all texture targets *//*--------------------------------------------------------------------*/ class TextureLevelCommonCase : public TextureLevelCase { public: TextureLevelCommonCase (Context& ctx, const char* name, const char* desc, VerifierType type); protected: virtual void generateTestIterations (std::vector<TextureGenerationSpec>& iterations); }; TextureLevelCommonCase::TextureLevelCommonCase (Context& ctx, const char* name, const char* desc, VerifierType type) : TextureLevelCase(ctx, name, desc, type) { } void TextureLevelCommonCase::generateTestIterations (std::vector<TextureGenerationSpec>& iterations) { std::vector<int> texture2DSamples; std::vector<int> texture2DArraySamples; getFormatSamples(GL_TEXTURE_2D_MULTISAMPLE, texture2DSamples); getFormatSamples(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, texture2DArraySamples); TCU_CHECK(!texture2DSamples.empty()); TCU_CHECK(!texture2DArraySamples.empty()); // gen iterations generateColorTextureGenerationGroup(iterations, texture2DSamples[0], texture2DArraySamples[0], m_internalFormat); } /*--------------------------------------------------------------------*//*! * \brief Test all multisample texture targets *//*--------------------------------------------------------------------*/ class TextureLevelMultisampleCase : public TextureLevelCase { public: TextureLevelMultisampleCase (Context& ctx, const char* name, const char* desc, VerifierType type); protected: virtual void generateTestIterations (std::vector<TextureGenerationSpec>& iterations); }; TextureLevelMultisampleCase::TextureLevelMultisampleCase (Context& ctx, const char* name, const char* desc, VerifierType type) : TextureLevelCase(ctx, name, desc, type) { } void TextureLevelMultisampleCase::generateTestIterations (std::vector<TextureGenerationSpec>& iterations) { std::vector<int> texture2DSamples; std::vector<int> texture2DArraySamples; getFormatSamples(GL_TEXTURE_2D_MULTISAMPLE, texture2DSamples); getFormatSamples(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, texture2DArraySamples); TCU_CHECK(!texture2DSamples.empty()); TCU_CHECK(!texture2DArraySamples.empty()); // gen iterations generateColorMultisampleTextureGenerationGroup(iterations, texture2DSamples[0], texture2DArraySamples[0], m_internalFormat); } class TextureLevelSampleCase : public TextureLevelMultisampleCase { public: TextureLevelSampleCase (Context& ctx, const char* name, const char* desc, VerifierType type) : TextureLevelMultisampleCase(ctx, name, desc, type) { } private: bool checkTextureState (glu::CallLogWrapper& gl, const TextureGenerationSpec& spec) { const int queryLevel = (spec.levels.empty()) ? (0) : (spec.levels[0].level); const int refValue = (spec.levels.empty()) ? (0) : (spec.sampleCount); return verifyTextureLevelParameterGreaterOrEqual(gl, spec.queryTarget, queryLevel, GL_TEXTURE_SAMPLES, refValue, m_type); } }; class TextureLevelFixedSamplesCase : public TextureLevelMultisampleCase { public: TextureLevelFixedSamplesCase (Context& ctx, const char* name, const char* desc, VerifierType type) : TextureLevelMultisampleCase(ctx, name, desc, type) { } private: bool checkTextureState (glu::CallLogWrapper& gl, const TextureGenerationSpec& spec) { const int queryLevel = 0; const int refValue = (spec.levels.empty()) ? (1) : ((spec.fixedSamplePos) ? (1) : (0)); return verifyTextureLevelParameterEqual(gl, spec.queryTarget, queryLevel, GL_TEXTURE_FIXED_SAMPLE_LOCATIONS, refValue, m_type); } }; class TextureLevelWidthCase : public TextureLevelCommonCase { public: TextureLevelWidthCase (Context& ctx, const char* name, const char* desc, VerifierType type) : TextureLevelCommonCase(ctx, name, desc, type) { } private: bool checkTextureState (glu::CallLogWrapper& gl, const TextureGenerationSpec& spec) { const int initialValue = 0; bool allOk = true; if (spec.levels.empty()) { const int queryLevel = 0; const int refValue = initialValue; allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, queryLevel, GL_TEXTURE_WIDTH, refValue, m_type); } else { for (int levelNdx = 0; levelNdx < (int)spec.levels.size(); ++levelNdx) { const int queryLevel = spec.levels[levelNdx].level; const int refValue = spec.levels[levelNdx].width; allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, queryLevel, GL_TEXTURE_WIDTH, refValue, m_type); } } return allOk; } }; class TextureLevelHeightCase : public TextureLevelCommonCase { public: TextureLevelHeightCase (Context& ctx, const char* name, const char* desc, VerifierType type) : TextureLevelCommonCase(ctx, name, desc, type) { } private: bool checkTextureState (glu::CallLogWrapper& gl, const TextureGenerationSpec& spec) { const int initialValue = 0; bool allOk = true; if (spec.levels.empty()) { const int queryLevel = 0; const int refValue = initialValue; allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, queryLevel, GL_TEXTURE_HEIGHT, refValue, m_type); } else { for (int levelNdx = 0; levelNdx < (int)spec.levels.size(); ++levelNdx) { const int queryLevel = spec.levels[levelNdx].level; const int refValue = spec.levels[levelNdx].height; allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, queryLevel, GL_TEXTURE_HEIGHT, refValue, m_type); } } return allOk; } }; class TextureLevelDepthCase : public TextureLevelCommonCase { public: TextureLevelDepthCase (Context& ctx, const char* name, const char* desc, VerifierType type) : TextureLevelCommonCase(ctx, name, desc, type) { } private: void generateTestIterations (std::vector<TextureGenerationSpec>& iterations) { std::vector<TextureGenerationSpec> allIterations; this->TextureLevelCommonCase::generateTestIterations(allIterations); // test only cases with depth for (int ndx = 0; ndx < (int)allIterations.size(); ++ndx) if (textureTypeHasDepth(allIterations[ndx].bindTarget)) iterations.push_back(allIterations[ndx]); } bool checkTextureState (glu::CallLogWrapper& gl, const TextureGenerationSpec& spec) { const int initialValue = 0; bool allOk = true; if (spec.levels.empty()) { const int queryLevel = 0; const int refValue = initialValue; allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, queryLevel, GL_TEXTURE_DEPTH, refValue, m_type); } else { for (int levelNdx = 0; levelNdx < (int)spec.levels.size(); ++levelNdx) { const int queryLevel = spec.levels[levelNdx].level; const int refValue = spec.levels[levelNdx].depth; allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, queryLevel, GL_TEXTURE_DEPTH, refValue, m_type); } } return allOk; } }; class TextureLevelInternalFormatCase : public TextureLevelCase { public: TextureLevelInternalFormatCase (Context& ctx, const char* name, const char* desc, VerifierType type) : TextureLevelCase(ctx, name, desc, type) { } private: void generateTestIterations (std::vector<TextureGenerationSpec>& iterations) { generateInternalFormatTextureGenerationGroup(iterations); } bool checkTextureState (glu::CallLogWrapper& gl, const TextureGenerationSpec& spec) { bool allOk = true; if (spec.levels.empty()) { const int queryLevel = 0; const int initialValues[2] = { GL_RGBA, GL_R8 }; allOk &= verifyTextureLevelParameterInternalFormatAnyOf(gl, spec.queryTarget, queryLevel, GL_TEXTURE_INTERNAL_FORMAT, initialValues, DE_LENGTH_OF_ARRAY(initialValues), m_type); } else { for (int levelNdx = 0; levelNdx < (int)spec.levels.size(); ++levelNdx) { const int queryLevel = spec.levels[levelNdx].level; const int refValue = spec.levels[levelNdx].internalFormat; allOk &= verifyTextureLevelParameterInternalFormatEqual(gl, spec.queryTarget, queryLevel, GL_TEXTURE_INTERNAL_FORMAT, refValue, m_type); } } return allOk; } }; class TextureLevelSizeCase : public TextureLevelCase { public: TextureLevelSizeCase (Context& ctx, const char* name, const char* desc, VerifierType type, glw::GLenum pname); private: void generateTestIterations (std::vector<TextureGenerationSpec>& iterations); bool checkTextureState (glu::CallLogWrapper& gl, const TextureGenerationSpec& spec); int getMinimumComponentResolution (glw::GLenum internalFormat); const glw::GLenum m_pname; }; TextureLevelSizeCase::TextureLevelSizeCase (Context& ctx, const char* name, const char* desc, VerifierType type, glw::GLenum pname) : TextureLevelCase (ctx, name, desc, type) , m_pname (pname) { } void TextureLevelSizeCase::generateTestIterations (std::vector<TextureGenerationSpec>& iterations) { generateInternalFormatTextureGenerationGroup(iterations); } bool TextureLevelSizeCase::checkTextureState (glu::CallLogWrapper& gl, const TextureGenerationSpec& spec) { bool allOk = true; if (spec.levels.empty()) { allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, 0, m_pname, 0, m_type); } else { for (int levelNdx = 0; levelNdx < (int)spec.levels.size(); ++levelNdx) { const int queryLevel = spec.levels[levelNdx].level; const int refValue = getMinimumComponentResolution(spec.levels[levelNdx].internalFormat); allOk &= verifyTextureLevelParameterGreaterOrEqual(gl, spec.queryTarget, queryLevel, m_pname, refValue, m_type); } } return allOk; } int TextureLevelSizeCase::getMinimumComponentResolution (glw::GLenum internalFormat) { const tcu::TextureFormat format = glu::mapGLInternalFormat(internalFormat); const tcu::IVec4 channelBitDepth = tcu::getTextureFormatBitDepth(format); switch (m_pname) { case GL_TEXTURE_RED_SIZE: if (format.order == tcu::TextureFormat::R || format.order == tcu::TextureFormat::RG || format.order == tcu::TextureFormat::RGB || format.order == tcu::TextureFormat::RGBA || format.order == tcu::TextureFormat::BGRA || format.order == tcu::TextureFormat::ARGB || format.order == tcu::TextureFormat::sRGB || format.order == tcu::TextureFormat::sRGBA) return channelBitDepth[0]; else return 0; case GL_TEXTURE_GREEN_SIZE: if (format.order == tcu::TextureFormat::RG || format.order == tcu::TextureFormat::RGB || format.order == tcu::TextureFormat::RGBA || format.order == tcu::TextureFormat::BGRA || format.order == tcu::TextureFormat::ARGB || format.order == tcu::TextureFormat::sRGB || format.order == tcu::TextureFormat::sRGBA) return channelBitDepth[1]; else return 0; case GL_TEXTURE_BLUE_SIZE: if (format.order == tcu::TextureFormat::RGB || format.order == tcu::TextureFormat::RGBA || format.order == tcu::TextureFormat::BGRA || format.order == tcu::TextureFormat::ARGB || format.order == tcu::TextureFormat::sRGB || format.order == tcu::TextureFormat::sRGBA) return channelBitDepth[2]; else return 0; case GL_TEXTURE_ALPHA_SIZE: if (format.order == tcu::TextureFormat::RGBA || format.order == tcu::TextureFormat::BGRA || format.order == tcu::TextureFormat::ARGB || format.order == tcu::TextureFormat::sRGBA) return channelBitDepth[3]; else return 0; case GL_TEXTURE_DEPTH_SIZE: if (format.order == tcu::TextureFormat::D || format.order == tcu::TextureFormat::DS) return channelBitDepth[0]; else return 0; case GL_TEXTURE_STENCIL_SIZE: if (format.order == tcu::TextureFormat::DS) return channelBitDepth[3]; else return 0; case GL_TEXTURE_SHARED_SIZE: if (internalFormat == GL_RGB9_E5) return 5; else return 0; default: DE_ASSERT(DE_FALSE); return 0; } } class TextureLevelTypeCase : public TextureLevelCase { public: TextureLevelTypeCase (Context& ctx, const char* name, const char* desc, VerifierType type, glw::GLenum pname); private: void generateTestIterations (std::vector<TextureGenerationSpec>& iterations); bool checkTextureState (glu::CallLogWrapper& gl, const TextureGenerationSpec& spec); int getComponentType (glw::GLenum internalFormat); const glw::GLenum m_pname; }; TextureLevelTypeCase::TextureLevelTypeCase (Context& ctx, const char* name, const char* desc, VerifierType type, glw::GLenum pname) : TextureLevelCase (ctx, name, desc, type) , m_pname (pname) { } void TextureLevelTypeCase::generateTestIterations (std::vector<TextureGenerationSpec>& iterations) { generateInternalFormatTextureGenerationGroup(iterations); } bool TextureLevelTypeCase::checkTextureState (glu::CallLogWrapper& gl, const TextureGenerationSpec& spec) { bool allOk = true; if (spec.levels.empty()) { allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, 0, m_pname, GL_NONE, m_type); } else { for (int levelNdx = 0; levelNdx < (int)spec.levels.size(); ++levelNdx) { const int queryLevel = spec.levels[levelNdx].level; const int refValue = getComponentType(spec.levels[levelNdx].internalFormat); allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, queryLevel, m_pname, refValue, m_type); } } return allOk; } int TextureLevelTypeCase::getComponentType (glw::GLenum internalFormat) { const tcu::TextureFormat format = glu::mapGLInternalFormat(internalFormat); const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type); glw::GLenum channelType = GL_NONE; // depth-stencil special cases if (format.type == tcu::TextureFormat::UNSIGNED_INT_24_8) { if (m_pname == GL_TEXTURE_DEPTH_TYPE) return GL_UNSIGNED_NORMALIZED; else return GL_NONE; } else if (format.type == tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV) { if (m_pname == GL_TEXTURE_DEPTH_TYPE) return GL_FLOAT; else return GL_NONE; } else { switch (channelClass) { case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT: channelType = GL_SIGNED_NORMALIZED; break; case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT: channelType = GL_UNSIGNED_NORMALIZED; break; case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER: channelType = GL_INT; break; case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER: channelType = GL_UNSIGNED_INT; break; case tcu::TEXTURECHANNELCLASS_FLOATING_POINT: channelType = GL_FLOAT; break; default: DE_ASSERT(DE_FALSE); } } switch (m_pname) { case GL_TEXTURE_RED_TYPE: if (format.order == tcu::TextureFormat::R || format.order == tcu::TextureFormat::RG || format.order == tcu::TextureFormat::RGB || format.order == tcu::TextureFormat::RGBA || format.order == tcu::TextureFormat::BGRA || format.order == tcu::TextureFormat::ARGB || format.order == tcu::TextureFormat::sRGB || format.order == tcu::TextureFormat::sRGBA) return channelType; else return GL_NONE; case GL_TEXTURE_GREEN_TYPE: if (format.order == tcu::TextureFormat::RG || format.order == tcu::TextureFormat::RGB || format.order == tcu::TextureFormat::RGBA || format.order == tcu::TextureFormat::BGRA || format.order == tcu::TextureFormat::ARGB || format.order == tcu::TextureFormat::sRGB || format.order == tcu::TextureFormat::sRGBA) return channelType; else return GL_NONE; case GL_TEXTURE_BLUE_TYPE: if (format.order == tcu::TextureFormat::RGB || format.order == tcu::TextureFormat::RGBA || format.order == tcu::TextureFormat::BGRA || format.order == tcu::TextureFormat::ARGB || format.order == tcu::TextureFormat::sRGB || format.order == tcu::TextureFormat::sRGBA) return channelType; else return GL_NONE; case GL_TEXTURE_ALPHA_TYPE: if (format.order == tcu::TextureFormat::RGBA || format.order == tcu::TextureFormat::BGRA || format.order == tcu::TextureFormat::ARGB || format.order == tcu::TextureFormat::sRGBA) return channelType; else return GL_NONE; case GL_TEXTURE_DEPTH_TYPE: if (format.order == tcu::TextureFormat::D || format.order == tcu::TextureFormat::DS) return channelType; else return GL_NONE; default: DE_ASSERT(DE_FALSE); return 0; } } class TextureLevelCompressedCase : public TextureLevelCase { public: TextureLevelCompressedCase (Context& ctx, const char* name, const char* desc, VerifierType type) : TextureLevelCase(ctx, name, desc, type) { } private: void generateTestIterations (std::vector<TextureGenerationSpec>& iterations) { generateCompressedTextureGenerationGroup(iterations); } bool checkTextureState (glu::CallLogWrapper& gl, const TextureGenerationSpec& spec) { bool allOk = true; if (spec.levels.empty()) { allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, 0, GL_TEXTURE_COMPRESSED, 0, m_type); } else { for (int levelNdx = 0; levelNdx < (int)spec.levels.size(); ++levelNdx) { const int queryLevel = spec.levels[levelNdx].level; const int refValue = (spec.levels[levelNdx].compressed) ? (1) : (0); allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, queryLevel, GL_TEXTURE_COMPRESSED, refValue, m_type); } } return allOk; } }; } // anonymous TextureLevelStateQueryTests::TextureLevelStateQueryTests (Context& context) : TestCaseGroup(context, "texture_level", "GetTexLevelParameter tests") { } TextureLevelStateQueryTests::~TextureLevelStateQueryTests (void) { } void TextureLevelStateQueryTests::init (void) { tcu::TestCaseGroup* const integerGroup = new tcu::TestCaseGroup(m_testCtx, "integer", "use GetTexLevelParameteriv"); tcu::TestCaseGroup* const floatGroup = new tcu::TestCaseGroup(m_testCtx, "float", "use GetTexLevelParameterfv"); addChild(integerGroup); addChild(floatGroup); for (int groupNdx = 0; groupNdx < 2; ++groupNdx) { tcu::TestCaseGroup* const group = (groupNdx == 0) ? (integerGroup) : (floatGroup); const VerifierType verifier = (groupNdx == 0) ? (VERIFIER_INT) : (VERIFIER_FLOAT); group->addChild(new TextureLevelSampleCase (m_context, "texture_samples", "Verify TEXTURE_SAMPLES", verifier)); group->addChild(new TextureLevelFixedSamplesCase (m_context, "texture_fixed_sample_locations", "Verify TEXTURE_FIXED_SAMPLE_LOCATIONS", verifier)); group->addChild(new TextureLevelWidthCase (m_context, "texture_width", "Verify TEXTURE_WIDTH", verifier)); group->addChild(new TextureLevelHeightCase (m_context, "texture_height", "Verify TEXTURE_HEIGHT", verifier)); group->addChild(new TextureLevelDepthCase (m_context, "texture_depth", "Verify TEXTURE_DEPTH", verifier)); group->addChild(new TextureLevelInternalFormatCase (m_context, "texture_internal_format", "Verify TEXTURE_INTERNAL_FORMAT", verifier)); group->addChild(new TextureLevelSizeCase (m_context, "texture_red_size", "Verify TEXTURE_RED_SIZE", verifier, GL_TEXTURE_RED_SIZE)); group->addChild(new TextureLevelSizeCase (m_context, "texture_green_size", "Verify TEXTURE_GREEN_SIZE", verifier, GL_TEXTURE_GREEN_SIZE)); group->addChild(new TextureLevelSizeCase (m_context, "texture_blue_size", "Verify TEXTURE_BLUE_SIZE", verifier, GL_TEXTURE_BLUE_SIZE)); group->addChild(new TextureLevelSizeCase (m_context, "texture_alpha_size", "Verify TEXTURE_ALPHA_SIZE", verifier, GL_TEXTURE_ALPHA_SIZE)); group->addChild(new TextureLevelSizeCase (m_context, "texture_depth_size", "Verify TEXTURE_DEPTH_SIZE", verifier, GL_TEXTURE_DEPTH_SIZE)); group->addChild(new TextureLevelSizeCase (m_context, "texture_stencil_size", "Verify TEXTURE_STENCIL_SIZE", verifier, GL_TEXTURE_STENCIL_SIZE)); group->addChild(new TextureLevelSizeCase (m_context, "texture_shared_size", "Verify TEXTURE_SHARED_SIZE", verifier, GL_TEXTURE_SHARED_SIZE)); group->addChild(new TextureLevelTypeCase (m_context, "texture_red_type", "Verify TEXTURE_RED_TYPE", verifier, GL_TEXTURE_RED_TYPE)); group->addChild(new TextureLevelTypeCase (m_context, "texture_green_type", "Verify TEXTURE_GREEN_TYPE", verifier, GL_TEXTURE_GREEN_TYPE)); group->addChild(new TextureLevelTypeCase (m_context, "texture_blue_type", "Verify TEXTURE_BLUE_TYPE", verifier, GL_TEXTURE_BLUE_TYPE)); group->addChild(new TextureLevelTypeCase (m_context, "texture_alpha_type", "Verify TEXTURE_ALPHA_TYPE", verifier, GL_TEXTURE_ALPHA_TYPE)); group->addChild(new TextureLevelTypeCase (m_context, "texture_depth_type", "Verify TEXTURE_DEPTH_TYPE", verifier, GL_TEXTURE_DEPTH_TYPE)); group->addChild(new TextureLevelCompressedCase (m_context, "texture_compressed", "Verify TEXTURE_COMPRESSED", verifier)); } } } // Functional } // gles31 } // deqp