Added CTS_ARB_texture_filter_minmax tests
authorFilip Demczewski <filip.demczewski@mobica.com>
Thu, 24 Nov 2016 16:51:50 +0000 (17:51 +0100)
committerAlexander Galazin <Alexander.Galazin@arm.com>
Fri, 13 Jan 2017 16:43:53 +0000 (11:43 -0500)
Change-Id: I30d0ee7ef7e6796a2de85c4affd911d552dd106e

external/openglcts/modules/gl/CMakeLists.txt
external/openglcts/modules/gl/gl4cTestPackages.cpp
external/openglcts/modules/gl/gl4cTextureFilterMinmaxTests.cpp [new file with mode: 0644]
external/openglcts/modules/gl/gl4cTextureFilterMinmaxTests.hpp [new file with mode: 0644]
framework/opengl/wrapper/glwEnums.inl
scripts/opengl/src_util.py

index 45d8def1ebd6c7343ec67d8a9ed8c472735d1e9a..54500bdf676f356bbc826213a433948975e57f32 100644 (file)
@@ -88,6 +88,8 @@ set(GLCTS_GL_SRCS
        gl4cShaderImageSizeTests.cpp
        gl4cSyncTests.cpp
        gl4cSyncTests.hpp
+       gl4cTextureFilterMinmaxTests.cpp
+       gl4cTextureFilterMinmaxTests.hpp
        gl4cTextureViewTests.cpp
        gl4cTextureViewTests.hpp
        gl4cTextureBarrierTests.cpp
index 1c11bdd4ac3bfb734937b1601c1a08f3c1b51cde..f008905f30e752ef454e2e75cdebdcae74341726 100644 (file)
@@ -56,6 +56,7 @@
 #include "gl4cStencilTexturingTests.hpp"
 #include "gl4cSyncTests.hpp"
 #include "gl4cTextureBarrierTests.hpp"
+#include "gl4cTextureFilterMinmaxTests.hpp"
 #include "gl4cTextureGatherTests.hpp"
 #include "gl4cTextureViewTests.hpp"
 #include "gl4cVertexAttrib64BitTest.hpp"
@@ -326,6 +327,7 @@ void GL45TestPackage::init(void)
                addChild(new gl4cts::ParallelShaderCompileTests(getContext()));
                addChild(new gl4cts::PostDepthCoverage(getContext()));
                addChild(new gl4cts::SparseTexture2Tests(getContext()));
+               addChild(new gl4cts::TextureFilterMinmax(getContext()));
        }
        catch (...)
        {
diff --git a/external/openglcts/modules/gl/gl4cTextureFilterMinmaxTests.cpp b/external/openglcts/modules/gl/gl4cTextureFilterMinmaxTests.cpp
new file mode 100644 (file)
index 0000000..ca3200c
--- /dev/null
@@ -0,0 +1,814 @@
+/*-------------------------------------------------------------------------
+ * OpenGL Conformance Test Suite
+ * -----------------------------
+ *
+ * Copyright (c) 2016 The Khronos Group Inc.
+ *
+ * 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
+ */ /*-------------------------------------------------------------------*/
+
+/**
+ */ /*!
+ * \file  gl4cTextureFilterMinmaxTests.cpp
+ * \brief Conformance tests for the ARB_texture_filter_minmax functionality.
+ */ /*-------------------------------------------------------------------*/
+
+#include "gl4cTextureFilterMinmaxTests.hpp"
+#include "gluContextInfo.hpp"
+#include "gluDefs.hpp"
+#include "gluDrawUtil.hpp"
+#include "gluObjectWrapper.hpp"
+#include "gluShaderProgram.hpp"
+#include "gluTexture.hpp"
+#include "glwEnums.hpp"
+#include "glwFunctions.hpp"
+#include "tcuImageIO.hpp"
+#include "tcuRenderTarget.hpp"
+#include "tcuTestLog.hpp"
+#include "tcuTextureUtil.hpp"
+
+#include "deUniquePtr.hpp"
+
+#include <map>
+#include <vector>
+
+namespace gl4cts
+{
+
+static const int   TEXTURE_FILTER_MINMAX_SIZE                    = 32;
+static const float TEXTURE_FILTER_MINMAX_DOWNSCALE_FACTOR = 0.57f;
+static const float TEXTURE_FILTER_MINMAX_UPSCALE_FACTOR   = 1.63f;
+
+TextureFilterMinmaxUtils::TextureFilterMinmaxUtils()
+{
+       m_reductionModeParams.push_back(ReductionModeParam(GL_MIN, false));
+       m_reductionModeParams.push_back(ReductionModeParam(GL_WEIGHTED_AVERAGE_ARB, false));
+       m_reductionModeParams.push_back(ReductionModeParam(GL_MAX, false));
+
+       m_supportedTextureTypes.push_back(new Texture1D());
+       m_supportedTextureTypes.push_back(new Texture1DArray());
+       m_supportedTextureTypes.push_back(new Texture2D());
+       m_supportedTextureTypes.push_back(new Texture2DArray());
+       m_supportedTextureTypes.push_back(new Texture3D());
+       m_supportedTextureTypes.push_back(new TextureCube());
+
+       m_supportedTextureDataTypes.push_back(SupportedTextureDataType(GL_RED, GL_FLOAT, MINMAX));
+       m_supportedTextureDataTypes.push_back(SupportedTextureDataType(GL_RED, GL_UNSIGNED_BYTE, MINMAX));
+       m_supportedTextureDataTypes.push_back(
+               SupportedTextureDataType(GL_DEPTH_COMPONENT, GL_FLOAT, MINMAX | EXCLUDE_3D | EXCLUDE_CUBE));
+       m_supportedTextureDataTypes.push_back(
+               SupportedTextureDataType(GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, MINMAX | EXCLUDE_3D | EXCLUDE_CUBE));
+       m_supportedTextureDataTypes.push_back(SupportedTextureDataType(GL_LUMINANCE, GL_FLOAT, COMPATIBILITY));
+}
+
+TextureFilterMinmaxUtils::~TextureFilterMinmaxUtils()
+{
+       for (SupportedTextureTypeIter iter = m_supportedTextureTypes.begin(); iter != m_supportedTextureTypes.end(); ++iter)
+       {
+               SupportedTextureType* textureType = *iter;
+               delete textureType;
+       }
+}
+
+// SupportedTextureType
+
+void TextureFilterMinmaxUtils::SupportedTextureType::replaceAll(std::string& str, const std::string& from,
+                                                                                                                               const std::string& to)
+{
+       size_t start = 0;
+       while ((start = str.find(from, start)) != std::string::npos)
+       {
+               str.replace(start, from.length(), to);
+               start += to.length();
+       }
+}
+
+TextureFilterMinmaxUtils::SupportedTextureType::SupportedTextureType(glw::GLenum               type,
+                                                                                                                                        const std::string& shaderTexcoordType,
+                                                                                                                                        const std::string& shaderSamplerType)
+       : m_type(type)
+{
+       m_vertexShader = "#version 450 core\n"
+                                        "in highp vec2 position;\n"
+                                        "in <texcoord_type> inTexcoord;\n"
+                                        "out <texcoord_type> texcoord;\n"
+                                        "void main()\n"
+                                        "{\n"
+                                        "      texcoord = inTexcoord;\n"
+                                        "      gl_Position = vec4(position, 0.0, 1.0);\n"
+                                        "}\n";
+
+       m_fragmentShader = "#version 450 core\n"
+                                          "uniform <sampler_type> sampler;\n"
+                                          "in <texcoord_type> texcoord;\n"
+                                          "out vec4 color;\n"
+                                          "void main()\n"
+                                          "{\n"
+                                          "    color = texture(sampler, texcoord);\n"
+                                          "}\n";
+
+       replaceAll(m_vertexShader, "<texcoord_type>", shaderTexcoordType);
+       replaceAll(m_fragmentShader, "<texcoord_type>", shaderTexcoordType);
+       replaceAll(m_fragmentShader, "<sampler_type>", shaderSamplerType);
+}
+
+void TextureFilterMinmaxUtils::SupportedTextureType::renderToFBO(const glu::RenderContext& context,
+                                                                                                                                glw::GLuint resultTextureId, tcu::IVec2 size,
+                                                                                                                                glw::GLint reductionMode)
+{
+       const glw::Functions& gl = context.getFunctions();
+
+       gl.bindTexture(GL_TEXTURE_2D, resultTextureId);
+       GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
+
+       gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, size.x(), size.y());
+       GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed.");
+
+       glw::GLuint fbo = 0;
+       gl.genFramebuffers(1, &fbo);
+       GLU_EXPECT_NO_ERROR(gl.getError(), "genFramebuffers error occurred");
+
+       gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
+       GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer error occurred");
+
+       gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resultTextureId, 0);
+       GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferTexture2D error occurred");
+
+       if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
+       {
+               throw 0;
+       }
+
+       gl.viewport(0, 0, size.x(), size.y());
+       renderQuad(context, reductionMode);
+
+       gl.deleteFramebuffers(1, &fbo);
+}
+
+void TextureFilterMinmaxUtils::SupportedTextureType::renderQuad(const glu::RenderContext& context,
+                                                                                                                               glw::GLint                                reductionMode)
+{
+       const glw::Functions& gl = context.getFunctions();
+
+       deUint16 const quadIndices[] = { 0, 1, 2, 2, 1, 3 };
+
+       float const position[] = { -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f };
+
+       std::vector<float> texCoords = getTexCoords();
+
+       glu::VertexArrayBinding vertexArrays[] = { glu::va::Float("position", 2, 4, 0, position),
+                                                                                          glu::va::Float("inTexcoord", 1, 4, 0, texCoords.data()) };
+
+       gl.bindTexture(m_type, this->getTextureGL());
+       GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
+
+       gl.texParameteri(m_type, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+       gl.texParameteri(m_type, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+       gl.texParameteri(m_type, GL_TEXTURE_REDUCTION_MODE_ARB, reductionMode);
+
+       glu::ShaderProgram program(context, glu::makeVtxFragSources(m_vertexShader, m_fragmentShader));
+       if (!program.isOk())
+       {
+               TCU_FAIL("Shader compilation failed");
+       }
+
+       gl.useProgram(program.getProgram());
+       GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram failed");
+
+       gl.uniform1i(gl.getUniformLocation(program.getProgram(), "sampler"), 0);
+       GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i failed");
+
+       gl.clear(GL_COLOR_BUFFER_BIT);
+
+       glu::draw(context, program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays,
+                         glu::pr::TriangleStrip(DE_LENGTH_OF_ARRAY(quadIndices), quadIndices));
+}
+
+// Texture1D
+
+TextureFilterMinmaxUtils::Texture1D::Texture1D() : SupportedTextureType(GL_TEXTURE_1D, "float", "sampler1D")
+{
+}
+
+glw::GLuint TextureFilterMinmaxUtils::Texture1D::getTextureGL()
+{
+       return m_texture->getGLTexture();
+}
+
+std::vector<float> TextureFilterMinmaxUtils::Texture1D::getTexCoords()
+{
+       float const texCoord[] = { 0.0f, 0.0f, 1.0f, 1.0f };
+       return std::vector<float>(texCoord, texCoord + sizeof(texCoord) / sizeof(float));
+}
+
+void TextureFilterMinmaxUtils::Texture1D::generate(const glu::RenderContext& context, tcu::IVec3 size,
+                                                                                                  glw::GLenum format, glw::GLenum type, bool generateMipmaps)
+{
+       const glw::Functions& gl = context.getFunctions();
+
+       m_texture = de::MovePtr<glu::Texture1D>(new glu::Texture1D(context, format, type, size.x()));
+
+       m_texture->getRefTexture().allocLevel(0);
+       if (generateMipmaps)
+       {
+               m_texture->getRefTexture().allocLevel(1);
+       }
+       GLU_EXPECT_NO_ERROR(gl.getError(), "glu::Texture1D error occurred");
+
+       tcu::fillWithGrid(m_texture->getRefTexture().getLevel(0), 4, tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f),
+                                         tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
+       GLU_EXPECT_NO_ERROR(gl.getError(), "glu::Texture1D error occurred");
+
+       m_texture->upload();
+       GLU_EXPECT_NO_ERROR(gl.getError(), "glu::Texture1D error occurred");
+
+       if (generateMipmaps)
+       {
+               gl.generateTextureMipmap(m_texture->getGLTexture());
+       }
+
+       gl.activeTexture(GL_TEXTURE0);
+}
+
+// Texture1DArray
+
+TextureFilterMinmaxUtils::Texture1DArray::Texture1DArray()
+       : SupportedTextureType(GL_TEXTURE_1D_ARRAY, "vec2", "sampler1DArray")
+{
+}
+
+glw::GLuint TextureFilterMinmaxUtils::Texture1DArray::getTextureGL()
+{
+       return m_texture->getGLTexture();
+}
+
+std::vector<float> TextureFilterMinmaxUtils::Texture1DArray::getTexCoords()
+{
+       float const texCoord[] = { 0.0f, 0.5f, 0.0f, 0.5f, 1.0f, 0.5f, 1.0f, 0.5f };
+       return std::vector<float>(texCoord, texCoord + sizeof(texCoord) / sizeof(float));
+}
+
+void TextureFilterMinmaxUtils::Texture1DArray::generate(const glu::RenderContext& context, tcu::IVec3 size,
+                                                                                                               glw::GLenum format, glw::GLenum type, bool generateMipmaps)
+{
+       DE_UNREF(generateMipmaps);
+
+       const glw::Functions& gl = context.getFunctions();
+
+       m_texture = de::MovePtr<glu::Texture1DArray>(new glu::Texture1DArray(context, format, type, size.x(), 2));
+
+       m_texture->getRefTexture().allocLevel(0);
+       m_texture->getRefTexture().allocLevel(1);
+       GLU_EXPECT_NO_ERROR(gl.getError(), "glu::Texture1DArray error occurred");
+
+       tcu::fillWithGrid(m_texture->getRefTexture().getLevel(0), 4, tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f),
+                                         tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
+       GLU_EXPECT_NO_ERROR(gl.getError(), "glu::Texture1DArray error occurred");
+
+       tcu::fillWithGrid(m_texture->getRefTexture().getLevel(1), 4, tcu::Vec4(0.0f, 1.0f, 1.0f, 1.0f),
+                                         tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
+       GLU_EXPECT_NO_ERROR(gl.getError(), "glu::Texture1DArray error occurred");
+
+       m_texture->upload();
+       GLU_EXPECT_NO_ERROR(gl.getError(), "glu::Texture1DArray error occurred");
+
+       gl.activeTexture(GL_TEXTURE0);
+}
+
+// Texture2D
+
+TextureFilterMinmaxUtils::Texture2D::Texture2D() : SupportedTextureType(GL_TEXTURE_2D, "vec2", "sampler2D")
+{
+}
+
+glw::GLuint TextureFilterMinmaxUtils::Texture2D::getTextureGL()
+{
+       return m_texture->getGLTexture();
+}
+
+std::vector<float> TextureFilterMinmaxUtils::Texture2D::getTexCoords()
+{
+       float const texCoord[] = { 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f };
+       return std::vector<float>(texCoord, texCoord + sizeof(texCoord) / sizeof(float));
+}
+
+void TextureFilterMinmaxUtils::Texture2D::generate(const glu::RenderContext& context, tcu::IVec3 size,
+                                                                                                  glw::GLenum format, glw::GLenum type, bool generateMipmaps)
+{
+       const glw::Functions& gl = context.getFunctions();
+
+       m_texture = de::MovePtr<glu::Texture2D>(new glu::Texture2D(context, format, type, size.x(), size.y()));
+
+       m_texture->getRefTexture().allocLevel(0);
+       if (generateMipmaps)
+       {
+               m_texture->getRefTexture().allocLevel(1);
+       }
+       GLU_EXPECT_NO_ERROR(gl.getError(), "glu::Texture2D error occurred");
+
+       tcu::fillWithGrid(m_texture->getRefTexture().getLevel(0), 4, tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f),
+                                         tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
+       GLU_EXPECT_NO_ERROR(gl.getError(), "glu::Texture2D error occurred");
+
+       m_texture->upload();
+       GLU_EXPECT_NO_ERROR(gl.getError(), "glu::Texture2D error occurred");
+
+       if (generateMipmaps)
+       {
+               gl.generateTextureMipmap(m_texture->getGLTexture());
+       }
+
+       gl.activeTexture(GL_TEXTURE0);
+}
+
+// Texture2DArray
+
+TextureFilterMinmaxUtils::Texture2DArray::Texture2DArray()
+       : SupportedTextureType(GL_TEXTURE_2D_ARRAY, "vec3", "sampler2DArray")
+{
+}
+
+glw::GLuint TextureFilterMinmaxUtils::Texture2DArray::getTextureGL()
+{
+       return m_texture->getGLTexture();
+}
+
+std::vector<float> TextureFilterMinmaxUtils::Texture2DArray::getTexCoords()
+{
+       float const texCoord[] = { 0.0f, 0.0f, 0.5f, 0.0f, 1.0f, 0.5f, 1.0f, 0.0f, 0.5f, 1.0f, 1.0f, 0.5f };
+       return std::vector<float>(texCoord, texCoord + sizeof(texCoord) / sizeof(float));
+}
+
+void TextureFilterMinmaxUtils::Texture2DArray::generate(const glu::RenderContext& context, tcu::IVec3 size,
+                                                                                                               glw::GLenum format, glw::GLenum type, bool generateMipmaps)
+{
+       DE_UNREF(generateMipmaps);
+
+       const glw::Functions& gl = context.getFunctions();
+
+       m_texture = de::MovePtr<glu::Texture2DArray>(new glu::Texture2DArray(context, format, type, size.x(), size.y(), 2));
+
+       m_texture->getRefTexture().allocLevel(0);
+       m_texture->getRefTexture().allocLevel(1);
+       GLU_EXPECT_NO_ERROR(gl.getError(), "glu::Texture2DArray error occurred");
+
+       tcu::fillWithGrid(m_texture->getRefTexture().getLevel(0), 4, tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f),
+                                         tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
+       GLU_EXPECT_NO_ERROR(gl.getError(), "glu::Texture2DArray error occurred");
+
+       tcu::fillWithGrid(m_texture->getRefTexture().getLevel(1), 4, tcu::Vec4(0.0f, 1.0f, 1.0f, 1.0f),
+                                         tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
+       GLU_EXPECT_NO_ERROR(gl.getError(), "glu::Texture2DArray error occurred");
+
+       m_texture->upload();
+       GLU_EXPECT_NO_ERROR(gl.getError(), "glu::Texture2DArray error occurred");
+
+       gl.activeTexture(GL_TEXTURE0);
+}
+
+// Texture3D
+
+TextureFilterMinmaxUtils::Texture3D::Texture3D() : SupportedTextureType(GL_TEXTURE_3D, "vec3", "sampler3D")
+{
+}
+
+glw::GLuint TextureFilterMinmaxUtils::Texture3D::getTextureGL()
+{
+       return m_texture->getGLTexture();
+}
+
+std::vector<float> TextureFilterMinmaxUtils::Texture3D::getTexCoords()
+{
+       float const texCoord[] = { 0.0f, 0.0f, 0.5f, 0.0f, 1.0f, 0.5f, 1.0f, 0.0f, 0.5f, 1.0f, 1.0f, 0.5f };
+       return std::vector<float>(texCoord, texCoord + sizeof(texCoord) / sizeof(float));
+}
+
+void TextureFilterMinmaxUtils::Texture3D::generate(const glu::RenderContext& context, tcu::IVec3 size,
+                                                                                                  glw::GLenum format, glw::GLenum type, bool generateMipmaps)
+{
+       DE_UNREF(generateMipmaps);
+
+       const glw::Functions& gl = context.getFunctions();
+
+       m_texture = de::MovePtr<glu::Texture3D>(new glu::Texture3D(context, format, type, size.x(), size.y(), size.z()));
+
+       m_texture->getRefTexture().allocLevel(0);
+       GLU_EXPECT_NO_ERROR(gl.getError(), "glu::Texture3D error occurred");
+
+       tcu::fillWithGrid(m_texture->getRefTexture().getLevel(0), 4, tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f),
+                                         tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
+       GLU_EXPECT_NO_ERROR(gl.getError(), "glu::Texture3D error occurred");
+
+       m_texture->upload();
+       GLU_EXPECT_NO_ERROR(gl.getError(), "glu::Texture3D error occurred");
+
+       gl.activeTexture(GL_TEXTURE0);
+}
+
+// TextureCube
+
+TextureFilterMinmaxUtils::TextureCube::TextureCube() : SupportedTextureType(GL_TEXTURE_CUBE_MAP, "vec3", "samplerCube")
+{
+}
+
+glw::GLuint TextureFilterMinmaxUtils::TextureCube::getTextureGL()
+{
+       return m_texture->getGLTexture();
+}
+
+std::vector<float> TextureFilterMinmaxUtils::TextureCube::getTexCoords()
+{
+       float const texCoord[] = { 1.0f, 1.0f, 0.0f, -1.0f, 1.0f, 0.0f, -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f };
+       return std::vector<float>(texCoord, texCoord + sizeof(texCoord) / sizeof(float));
+}
+
+void TextureFilterMinmaxUtils::TextureCube::generate(const glu::RenderContext& context, tcu::IVec3 size,
+                                                                                                        glw::GLenum format, glw::GLenum type, bool generateMipmaps)
+{
+       DE_UNREF(generateMipmaps);
+
+       const glw::Functions& gl = context.getFunctions();
+
+       m_texture = de::MovePtr<glu::TextureCube>(new glu::TextureCube(context, format, type, size.x()));
+
+       for (int faceIndex = 0; faceIndex < tcu::CUBEFACE_LAST; ++faceIndex)
+       {
+               m_texture->getRefTexture().allocLevel((tcu::CubeFace)faceIndex, 0);
+               GLU_EXPECT_NO_ERROR(gl.getError(), "glu::TextureCube error occurred");
+
+               tcu::fillWithGrid(m_texture->getRefTexture().getLevelFace(0, (tcu::CubeFace)faceIndex), 4,
+                                                 tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
+               GLU_EXPECT_NO_ERROR(gl.getError(), "glu::TextureCube error occurred");
+       }
+
+       m_texture->upload();
+       GLU_EXPECT_NO_ERROR(gl.getError(), "glu::TextureCube error occurred");
+
+       gl.activeTexture(GL_TEXTURE0);
+}
+
+// TextureFilterMinmaxUtils methods
+
+std::vector<glw::GLuint> TextureFilterMinmaxUtils::getDataFromTexture(const glu::RenderContext& context,
+                                                                                                                                         glw::GLuint textureId, tcu::IVec2 textureSize,
+                                                                                                                                         glw::GLenum format, glw::GLenum type)
+{
+       const glw::Functions& gl = context.getFunctions();
+
+       glw::GLsizei imageLength = textureSize.x() * textureSize.y();
+
+       std::vector<glw::GLuint> data;
+       data.resize(imageLength);
+
+       gl.bindTexture(GL_TEXTURE_2D, textureId);
+       GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture error occurred");
+
+       gl.getTexImage(GL_TEXTURE_2D, 0, format, type, &data[0]);
+       GLU_EXPECT_NO_ERROR(gl.getError(), "getTexImage error occurred");
+
+       return data;
+}
+
+glw::GLuint TextureFilterMinmaxUtils::calcPixelSumValue(const glu::RenderContext& context, glw::GLuint textureId,
+                                                                                                               tcu::IVec2 textureSize, glw::GLenum format, glw::GLenum type)
+{
+       std::vector<glw::GLuint> textureData = getDataFromTexture(context, textureId, textureSize, format, type);
+
+       glw::GLuint sum = 0;
+
+       for (size_t texel = 0; texel < textureData.size(); ++texel)
+       {
+               tcu::RGBA rgba(textureData[texel]);
+               sum += rgba.getRed();
+               sum += rgba.getGreen();
+               sum += rgba.getBlue();
+               sum += rgba.getAlpha();
+       }
+
+       return sum;
+}
+
+/** Constructor.
+*
+*  @param context Rendering context
+*/
+TextureFilterMinmaxParameterQueriesTestCase::TextureFilterMinmaxParameterQueriesTestCase(deqp::Context& context)
+       : TestCase(context, "TextureFilterMinmaxParameterQueries",
+                          "Implements all parameter queries tests described in CTS_ARB_texture_filter_minmax")
+{
+       /* Left blank intentionally */
+}
+
+/** Executes test iteration.
+ *
+ *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
+ */
+tcu::TestNode::IterateResult TextureFilterMinmaxParameterQueriesTestCase::iterate()
+{
+       const glw::Functions& gl = m_context.getRenderContext().getFunctions();
+
+       testReductionModeQueriesDefaultValues(gl);
+
+       for (TextureFilterMinmaxUtils::ReductionModeParamIter iter = m_utils.getReductionModeParams().begin();
+                iter != m_utils.getReductionModeParams().end(); ++iter)
+       {
+               testReductionModeQueries(gl, iter->m_reductionMode);
+       }
+
+       m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
+
+       return STOP;
+}
+
+void TextureFilterMinmaxParameterQueriesTestCase::testReductionModeQueriesDefaultValues(const glw::Functions& gl)
+{
+       const glu::RenderContext& renderContext = m_context.getRenderContext();
+       de::MovePtr<glu::Sampler> sampler               = de::MovePtr<glu::Sampler>(new glu::Sampler(renderContext));
+       GLU_EXPECT_NO_ERROR(gl.getError(), "glu::Sampler error occurred");
+
+       glw::GLint params;
+
+       gl.getSamplerParameteriv(**sampler, GL_TEXTURE_REDUCTION_MODE_ARB, &params);
+       GLU_EXPECT_NO_ERROR(gl.getError(), "getSamplerParameteriv error occurred");
+       TCU_CHECK_MSG(params == GL_WEIGHTED_AVERAGE_ARB, "getSamplerParameteriv value mismatch with expected default");
+
+       for (TextureFilterMinmaxUtils::SupportedTextureTypeIter iter = m_utils.getSupportedTextureTypes().begin();
+                iter != m_utils.getSupportedTextureTypes().end(); ++iter)
+       {
+               TextureFilterMinmaxUtils::SupportedTextureType* textureType = *iter;
+
+               gl.getTexParameteriv(textureType->getType(), GL_TEXTURE_REDUCTION_MODE_ARB, &params);
+               GLU_EXPECT_NO_ERROR(gl.getError(), "getTexParameteriv error occurred");
+               TCU_CHECK_MSG(params == GL_WEIGHTED_AVERAGE_ARB, "getTexParameteriv value mismatch with expected default");
+
+               gl.getTexParameterIiv(textureType->getType(), GL_TEXTURE_REDUCTION_MODE_ARB, &params);
+               GLU_EXPECT_NO_ERROR(gl.getError(), "getTexParameterIiv error occurred");
+               TCU_CHECK_MSG(params == GL_WEIGHTED_AVERAGE_ARB, "getTexParameterIiv value mismatch with expected default");
+       }
+
+       bool is_arb_es31_compatibility = m_context.getContextInfo().isExtensionSupported("GL_ARB_ES3_1_compatibility");
+
+       for (TextureFilterMinmaxUtils::SupportedTextureDataTypeIter iter = m_utils.getSupportedTextureDataTypes().begin();
+                iter != m_utils.getSupportedTextureDataTypes().end(); ++iter)
+       {
+               if (iter->hasFlag(TextureFilterMinmaxUtils::COMPATIBILITY) && !is_arb_es31_compatibility)
+                       continue;
+
+               de::MovePtr<glu::Texture2D> texture = de::MovePtr<glu::Texture2D>(new glu::Texture2D(
+                       renderContext, iter->m_format, iter->m_type, TEXTURE_FILTER_MINMAX_SIZE, TEXTURE_FILTER_MINMAX_SIZE));
+               texture->upload();
+               GLU_EXPECT_NO_ERROR(gl.getError(), "glu::Texture2D error occurred");
+
+               gl.getTextureParameteriv(texture->getGLTexture(), GL_TEXTURE_REDUCTION_MODE_ARB, &params);
+               GLU_EXPECT_NO_ERROR(gl.getError(), "getTextureParameteriv error occurred");
+               TCU_CHECK_MSG(params == GL_WEIGHTED_AVERAGE_ARB, "getTextureParameteriv value mismatch with expected default");
+
+               gl.getTextureParameterIiv(texture->getGLTexture(), GL_TEXTURE_REDUCTION_MODE_ARB, &params);
+               GLU_EXPECT_NO_ERROR(gl.getError(), "getTextureParameterIiv error occurred");
+               TCU_CHECK_MSG(params == GL_WEIGHTED_AVERAGE_ARB, "getTextureParameterIiv value mismatch with expected default");
+       }
+}
+
+void TextureFilterMinmaxParameterQueriesTestCase::testReductionModeQueries(const glw::Functions& gl, glw::GLint pname)
+{
+       const glu::RenderContext& renderContext = m_context.getRenderContext();
+       de::MovePtr<glu::Sampler> sampler               = de::MovePtr<glu::Sampler>(new glu::Sampler(renderContext));
+       GLU_EXPECT_NO_ERROR(gl.getError(), "glu::Sampler error occurred");
+
+       gl.samplerParameteri(**sampler, GL_TEXTURE_REDUCTION_MODE_ARB, pname);
+       GLU_EXPECT_NO_ERROR(gl.getError(), "samplerParameteri error occurred");
+
+       for (TextureFilterMinmaxUtils::SupportedTextureTypeIter iter = m_utils.getSupportedTextureTypes().begin();
+                iter != m_utils.getSupportedTextureTypes().end(); ++iter)
+       {
+               TextureFilterMinmaxUtils::SupportedTextureType* textureType = *iter;
+
+               gl.texParameteriv(textureType->getType(), GL_TEXTURE_REDUCTION_MODE_ARB, &pname);
+               GLU_EXPECT_NO_ERROR(gl.getError(), "texParameteriv error occurred");
+
+               gl.texParameterIiv(textureType->getType(), GL_TEXTURE_REDUCTION_MODE_ARB, &pname);
+               GLU_EXPECT_NO_ERROR(gl.getError(), "texParameterIiv error occurred");
+       }
+
+       bool is_arb_es31_compatibility = m_context.getContextInfo().isExtensionSupported("GL_ARB_ES3_1_compatibility");
+
+       for (TextureFilterMinmaxUtils::SupportedTextureDataTypeIter iter = m_utils.getSupportedTextureDataTypes().begin();
+                iter != m_utils.getSupportedTextureDataTypes().end(); ++iter)
+       {
+               if (iter->hasFlag(TextureFilterMinmaxUtils::COMPATIBILITY) && !is_arb_es31_compatibility)
+                       continue;
+
+               de::MovePtr<glu::Texture2D> texture = de::MovePtr<glu::Texture2D>(new glu::Texture2D(
+                       renderContext, iter->m_format, iter->m_type, TEXTURE_FILTER_MINMAX_SIZE, TEXTURE_FILTER_MINMAX_SIZE));
+               texture->upload();
+               GLU_EXPECT_NO_ERROR(gl.getError(), "glu::Texture2D error occurred");
+
+               gl.textureParameteriv(texture->getGLTexture(), GL_TEXTURE_REDUCTION_MODE_ARB, &pname);
+               GLU_EXPECT_NO_ERROR(gl.getError(), "textureParameteriv error occurred");
+
+               gl.textureParameterIiv(texture->getGLTexture(), GL_TEXTURE_REDUCTION_MODE_ARB, &pname);
+               GLU_EXPECT_NO_ERROR(gl.getError(), "textureParameterIiv error occurred");
+       }
+}
+
+/** Base class for minmax render tests. Constructor.
+*
+*  @param context Rendering context
+*  @param name TestCase name
+*  @param description TestCase description
+*  @param renderScale Scale of rendered texture
+*  @param mipmapping Is mipmapping enabled
+*/
+TextureFilterMinmaxFilteringTestCaseBase::TextureFilterMinmaxFilteringTestCaseBase(deqp::Context& context,
+                                                                                                                                                                  const char*  name,
+                                                                                                                                                                  const char*  description,
+                                                                                                                                                                  float renderScale, bool mipmapping)
+       : deqp::TestCase(context, name, description), m_renderScale(renderScale), m_mipmapping(mipmapping)
+{
+}
+
+/** Executes test iteration.
+*
+*  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
+*/
+tcu::TestNode::IterateResult TextureFilterMinmaxFilteringTestCaseBase::iterate()
+{
+       const glu::RenderContext& renderContext = m_context.getRenderContext();
+       const glw::Functions&    gl                     = renderContext.getFunctions();
+
+       for (TextureFilterMinmaxUtils::SupportedTextureTypeIter textureTypeIter =
+                        m_utils.getSupportedTextureTypes().begin();
+                textureTypeIter != m_utils.getSupportedTextureTypes().end(); ++textureTypeIter)
+       {
+               TextureFilterMinmaxUtils::SupportedTextureType* textureType = *textureTypeIter;
+
+               for (TextureFilterMinmaxUtils::SupportedTextureDataTypeIter dataTypeIter =
+                                m_utils.getSupportedTextureDataTypes().begin();
+                        dataTypeIter != m_utils.getSupportedTextureDataTypes().end(); ++dataTypeIter)
+               {
+                       if (!dataTypeIter->hasFlag(TextureFilterMinmaxUtils::MINMAX))
+                               continue;
+
+                       if (dataTypeIter->hasFlag(TextureFilterMinmaxUtils::EXCLUDE_3D) && textureType->getType() == GL_TEXTURE_3D)
+                               continue;
+
+                       if (dataTypeIter->hasFlag(TextureFilterMinmaxUtils::EXCLUDE_CUBE) &&
+                               textureType->getType() == GL_TEXTURE_CUBE_MAP)
+                               continue;
+
+                       std::map<glw::GLint, glw::GLuint> reductionModeTexelSumMap;
+
+                       for (TextureFilterMinmaxUtils::ReductionModeParamIter paramIter = m_utils.getReductionModeParams().begin();
+                                paramIter != m_utils.getReductionModeParams().end(); ++paramIter)
+                       {
+                               if (paramIter->m_queryTestOnly)
+                                       continue;
+
+                               tcu::IVec2 scaledTextureSize(int(float(TEXTURE_FILTER_MINMAX_SIZE) * m_renderScale));
+
+                               textureType->generate(renderContext, tcu::IVec3(TEXTURE_FILTER_MINMAX_SIZE), dataTypeIter->m_format,
+                                                                         dataTypeIter->m_type, m_mipmapping);
+
+                               glw::GLuint resultTextureId = 0;
+                               gl.genTextures(1, &resultTextureId);
+                               GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed.");
+
+                               textureType->renderToFBO(renderContext, resultTextureId, scaledTextureSize, paramIter->m_reductionMode);
+
+                               reductionModeTexelSumMap[paramIter->m_reductionMode] = m_utils.calcPixelSumValue(
+                                       renderContext, resultTextureId, scaledTextureSize, GL_RED, GL_UNSIGNED_BYTE);
+
+                               gl.deleteTextures(1, &resultTextureId);
+                       }
+
+                       TCU_CHECK_MSG(reductionModeTexelSumMap[GL_MIN] < reductionModeTexelSumMap[GL_WEIGHTED_AVERAGE_ARB],
+                                                 "Sum of texels for GL_MIN should be smaller than for GL_WEIGHTED_AVERAGE_ARB");
+
+                       TCU_CHECK_MSG(reductionModeTexelSumMap[GL_MAX] > reductionModeTexelSumMap[GL_WEIGHTED_AVERAGE_ARB],
+                                                 "Sum of texels for GL_MAX should be greater than for GL_WEIGHTED_AVERAGE_ARB");
+               }
+       }
+
+       m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
+
+       return STOP;
+}
+
+/** Constructor.
+*
+*  @param context Rendering context
+*/
+TextureFilterMinmaxMinificationFilteringTestCase::TextureFilterMinmaxMinificationFilteringTestCase(
+       deqp::Context& context)
+       : TextureFilterMinmaxFilteringTestCaseBase(
+                 context, "TextureFilterMinmaxMinificationFiltering",
+                 "Implements minification filtering tests described in CTS_ARB_texture_filter_minmax",
+                 TEXTURE_FILTER_MINMAX_DOWNSCALE_FACTOR, false)
+{
+       /* Left blank intentionally */
+}
+
+/** Constructor.
+*
+*  @param context Rendering context
+*/
+TextureFilterMinmaxMagnificationFilteringTestCase::TextureFilterMinmaxMagnificationFilteringTestCase(
+       deqp::Context& context)
+       : TextureFilterMinmaxFilteringTestCaseBase(
+                 context, "TextureFilterMinmaxMagnificationFiltering",
+                 "Implements magnification filtering tests described in CTS_ARB_texture_filter_minmax",
+                 TEXTURE_FILTER_MINMAX_UPSCALE_FACTOR, false)
+{
+       /* Left blank intentionally */
+}
+
+/** Constructor.
+*
+*  @param context Rendering context
+*/
+TextureFilterMinmaxMipmapMinificationFilteringTestCase::TextureFilterMinmaxMipmapMinificationFilteringTestCase(
+       deqp::Context& context)
+       : TextureFilterMinmaxFilteringTestCaseBase(
+                 context, "TextureFilterMinmaxMipmapMinificationFiltering",
+                 "Implements mipmap minification filtering tests described in CTS_ARB_texture_filter_minmax",
+                 TEXTURE_FILTER_MINMAX_DOWNSCALE_FACTOR, true)
+{
+       /* Left blank intentionally */
+}
+
+/** Constructor.
+*
+*  @param context Rendering context
+*/
+TextureFilterMinmaxSupportTestCase::TextureFilterMinmaxSupportTestCase(deqp::Context& context)
+       : TestCase(context, "TextureFilterMinmaxSupport", "Implements calling GetInternalFormat* and validates with "
+                                                                                                         "expected result described in CTS_ARB_texture_filter_minmax")
+{
+}
+
+/** Executes test iteration.
+*
+*  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
+*/
+tcu::TestNode::IterateResult TextureFilterMinmaxSupportTestCase::iterate()
+{
+       const glu::RenderContext& renderContext = m_context.getRenderContext();
+       const glw::Functions&    gl                     = renderContext.getFunctions();
+
+       for (TextureFilterMinmaxUtils::SupportedTextureTypeIter textureTypeIter =
+                        m_utils.getSupportedTextureTypes().begin();
+                textureTypeIter != m_utils.getSupportedTextureTypes().end(); ++textureTypeIter)
+       {
+               TextureFilterMinmaxUtils::SupportedTextureType* textureType = *textureTypeIter;
+
+               for (TextureFilterMinmaxUtils::SupportedTextureDataTypeIter dataTypeIter =
+                                m_utils.getSupportedTextureDataTypes().begin();
+                        dataTypeIter != m_utils.getSupportedTextureDataTypes().end(); ++dataTypeIter)
+               {
+                       glw::GLint params = 0;
+                       gl.getInternalformativ(textureType->getType(), dataTypeIter->m_format, GL_TEXTURE_REDUCTION_MODE_ARB,
+                                                                  sizeof(glw::GLint), &params);
+                       GLU_EXPECT_NO_ERROR(gl.getError(), "getInternalformativ() call failed.");
+                       TCU_CHECK_MSG(params, "GetInternalformativ incorrect value");
+               }
+       }
+
+       m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
+
+       return STOP;
+}
+
+/** Constructor.
+ *
+ *  @param context Rendering context.
+ */
+TextureFilterMinmax::TextureFilterMinmax(deqp::Context& context)
+       : TestCaseGroup(context, "texture_filter_minmax_tests",
+                                       "Verify conformance of CTS_ARB_texture_filter_minmax implementation")
+{
+}
+
+/** Initializes the test group contents. */
+void TextureFilterMinmax::init()
+{
+       addChild(new TextureFilterMinmaxParameterQueriesTestCase(m_context));
+       addChild(new TextureFilterMinmaxMinificationFilteringTestCase(m_context));
+       addChild(new TextureFilterMinmaxMagnificationFilteringTestCase(m_context));
+       addChild(new TextureFilterMinmaxMipmapMinificationFilteringTestCase(m_context));
+       addChild(new TextureFilterMinmaxSupportTestCase(m_context));
+}
+} /* gl4cts namespace */
diff --git a/external/openglcts/modules/gl/gl4cTextureFilterMinmaxTests.hpp b/external/openglcts/modules/gl/gl4cTextureFilterMinmaxTests.hpp
new file mode 100644 (file)
index 0000000..1033e62
--- /dev/null
@@ -0,0 +1,339 @@
+#ifndef _GL4CTEXTUREFILTERMINMAXTESTS_HPP
+#define _GL4CTEXTUREFILTERMINMAXTESTS_HPP
+/*-------------------------------------------------------------------------
+ * OpenGL Conformance Test Suite
+ * -----------------------------
+ *
+ * Copyright (c) 2016 The Khronos Group Inc.
+ *
+ * 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
+ */ /*-------------------------------------------------------------------*/
+
+/**
+ */ /*!
+ * \file  gl4cTextureFilterMinmaxTests.hpp
+ * \brief Conformance tests for the ARB_texture_filter_minmax functionality.
+ */ /*-------------------------------------------------------------------*/
+
+#include "deUniquePtr.hpp"
+#include "glcTestCase.hpp"
+#include "gluTexture.hpp"
+#include "glwDefs.hpp"
+#include "glwEnums.hpp"
+#include "tcuDefs.hpp"
+
+#include <string>
+#include <vector>
+
+namespace gl4cts
+{
+class TextureFilterMinmaxUtils
+{
+public:
+       enum TextureTestFlag
+       {
+               MINMAX            = (1u << 0),
+               COMPATIBILITY = (1u << 1),
+               EXCLUDE_3D      = (1u << 2),
+               EXCLUDE_CUBE  = (1u << 3)
+       };
+
+       struct SupportedTextureDataType
+       {
+
+               glw::GLenum m_format;
+               glw::GLenum m_type;
+               int                     m_testFlags;
+
+               SupportedTextureDataType(glw::GLenum format, glw::GLenum type, int testFlags = MINMAX)
+                       : m_format(format), m_type(type), m_testFlags(testFlags)
+               {
+               }
+
+               inline bool hasFlag(TextureTestFlag flag) const
+               {
+                       return (m_testFlags & flag) != 0;
+               }
+       };
+
+       struct ReductionModeParam
+       {
+               glw::GLint m_reductionMode;
+               bool       m_queryTestOnly;
+
+               ReductionModeParam(glw::GLint reductionMode, bool queryTestOnly)
+                       : m_reductionMode(reductionMode), m_queryTestOnly(queryTestOnly)
+               {
+               }
+       };
+
+       class SupportedTextureType
+       {
+       protected:
+               glw::GLenum m_type;
+               tcu::IVec3  m_size;
+               std::string m_vertexShader;
+               std::string m_fragmentShader;
+
+               void replaceAll(std::string& str, const std::string& from, const std::string& to);
+
+               void renderQuad(const glu::RenderContext& context, glw::GLint reductionMode);
+
+               virtual glw::GLuint getTextureGL() = 0;
+
+               virtual std::vector<float> getTexCoords() = 0;
+
+       public:
+               SupportedTextureType(glw::GLenum type, const std::string& shaderTexcoordType,
+                                                        const std::string& shaderSamplerType);
+               virtual ~SupportedTextureType(){};
+
+               inline glw::GLenum getType() const
+               {
+                       return m_type;
+               }
+
+               virtual void generate(const glu::RenderContext& context, tcu::IVec3 size, glw::GLenum format, glw::GLenum type,
+                                                         bool generateMipmaps = false) = 0;
+
+               void renderToFBO(const glu::RenderContext& context, glw::GLuint resultTextureId, tcu::IVec2 size,
+                                                glw::GLint reductionMode);
+       };
+
+       class Texture1D : public SupportedTextureType
+       {
+       protected:
+               de::MovePtr<glu::Texture1D> m_texture;
+
+               glw::GLuint                getTextureGL();
+               std::vector<float> getTexCoords();
+
+       public:
+               Texture1D();
+
+               void generate(const glu::RenderContext& context, tcu::IVec3 size, glw::GLenum format, glw::GLenum type,
+                                         bool generateMipmaps = false);
+       };
+
+       class Texture1DArray : public SupportedTextureType
+       {
+       protected:
+               de::MovePtr<glu::Texture1DArray> m_texture;
+
+               glw::GLuint                getTextureGL();
+               std::vector<float> getTexCoords();
+
+       public:
+               Texture1DArray();
+
+               void generate(const glu::RenderContext& context, tcu::IVec3 size, glw::GLenum format, glw::GLenum type,
+                                         bool generateMipmaps = false);
+       };
+
+       class Texture2D : public SupportedTextureType
+       {
+       protected:
+               de::MovePtr<glu::Texture2D> m_texture;
+
+               glw::GLuint                getTextureGL();
+               std::vector<float> getTexCoords();
+
+       public:
+               Texture2D();
+
+               void generate(const glu::RenderContext& context, tcu::IVec3 size, glw::GLenum format, glw::GLenum type,
+                                         bool generateMipmaps = false);
+       };
+
+       class Texture2DArray : public SupportedTextureType
+       {
+       protected:
+               de::MovePtr<glu::Texture2DArray> m_texture;
+
+               glw::GLuint                getTextureGL();
+               std::vector<float> getTexCoords();
+
+       public:
+               Texture2DArray();
+
+               void generate(const glu::RenderContext& context, tcu::IVec3 size, glw::GLenum format, glw::GLenum type,
+                                         bool generateMipmaps = false);
+       };
+
+       class Texture3D : public SupportedTextureType
+       {
+       protected:
+               de::MovePtr<glu::Texture3D> m_texture;
+
+               glw::GLuint                getTextureGL();
+               std::vector<float> getTexCoords();
+
+       public:
+               Texture3D();
+
+               void generate(const glu::RenderContext& context, tcu::IVec3 size, glw::GLenum format, glw::GLenum type,
+                                         bool generateMipmaps = false);
+       };
+
+       class TextureCube : public SupportedTextureType
+       {
+       protected:
+               de::MovePtr<glu::TextureCube> m_texture;
+
+               glw::GLuint                getTextureGL();
+               std::vector<float> getTexCoords();
+
+       public:
+               TextureCube();
+
+               void generate(const glu::RenderContext& context, tcu::IVec3 size, glw::GLenum format, glw::GLenum type,
+                                         bool generateMipmaps = false);
+       };
+
+       /* Public methods */
+       TextureFilterMinmaxUtils();
+       ~TextureFilterMinmaxUtils();
+
+       std::vector<glw::GLuint> getDataFromTexture(const glu::RenderContext& context, glw::GLuint textureId,
+                                                                                               tcu::IVec2 textureSize, glw::GLenum format, glw::GLenum type);
+
+       glw::GLuint calcPixelSumValue(const glu::RenderContext& context, glw::GLuint textureId, tcu::IVec2 textureSize,
+                                                                 glw::GLenum format, glw::GLenum type);
+
+       inline const std::vector<ReductionModeParam>& getReductionModeParams()
+       {
+               return m_reductionModeParams;
+       }
+
+       inline const std::vector<SupportedTextureDataType>& getSupportedTextureDataTypes()
+       {
+               return m_supportedTextureDataTypes;
+       }
+
+       inline const std::vector<SupportedTextureType*>& getSupportedTextureTypes()
+       {
+               return m_supportedTextureTypes;
+       }
+
+       typedef std::vector<ReductionModeParam>::const_iterator           ReductionModeParamIter;
+       typedef std::vector<SupportedTextureDataType>::const_iterator SupportedTextureDataTypeIter;
+       typedef std::vector<SupportedTextureType*>::const_iterator      SupportedTextureTypeIter;
+
+private:
+       /* Private members */
+       std::vector<ReductionModeParam>           m_reductionModeParams;
+       std::vector<SupportedTextureDataType> m_supportedTextureDataTypes;
+       std::vector<SupportedTextureType*>      m_supportedTextureTypes;
+};
+
+/** Test verifies default values and manual setting of reduction mode queries
+ **/
+class TextureFilterMinmaxParameterQueriesTestCase : public deqp::TestCase
+{
+public:
+       /* Public methods */
+       TextureFilterMinmaxParameterQueriesTestCase(deqp::Context& context);
+
+       tcu::TestNode::IterateResult iterate();
+
+private:
+       /* Private methods */
+       void testReductionModeQueriesDefaultValues(const glw::Functions& gl);
+       void testReductionModeQueries(const glw::Functions& gl, glw::GLint pname);
+
+       /* Private members */
+       TextureFilterMinmaxUtils m_utils;
+};
+
+/** Base class for rendering based filtering tests
+**/
+class TextureFilterMinmaxFilteringTestCaseBase : public deqp::TestCase
+{
+public:
+       /* Public methods */
+       TextureFilterMinmaxFilteringTestCaseBase(deqp::Context& context, const char* name, const char* description,
+                                                                                        float renderScale, bool mipmapping);
+
+       tcu::TestNode::IterateResult iterate();
+
+protected:
+       /* Protected members */
+       TextureFilterMinmaxUtils m_utils;
+       float                                    m_renderScale;
+       bool                                     m_mipmapping;
+};
+
+/** Test verifies results of minification filtering for different reduction modes, targets, texture formats
+**/
+class TextureFilterMinmaxMinificationFilteringTestCase : public TextureFilterMinmaxFilteringTestCaseBase
+{
+public:
+       /* Public methods */
+       TextureFilterMinmaxMinificationFilteringTestCase(deqp::Context& context);
+};
+
+/** Test verifies results of magnification filtering for different reduction modes, targets, texture formats
+**/
+class TextureFilterMinmaxMagnificationFilteringTestCase : public TextureFilterMinmaxFilteringTestCaseBase
+{
+public:
+       /* Public methods */
+       TextureFilterMinmaxMagnificationFilteringTestCase(deqp::Context& context);
+};
+
+/** Test verifies results of minification filtering for different reduction modes, targets, texture formats
+       with mipmapping enabled
+**/
+class TextureFilterMinmaxMipmapMinificationFilteringTestCase : public TextureFilterMinmaxFilteringTestCaseBase
+{
+public:
+       /* Public methods */
+       TextureFilterMinmaxMipmapMinificationFilteringTestCase(deqp::Context& context);
+};
+
+/** Test verifies results of calling GetInternalFormat to verify support for specific texture types
+**/
+class TextureFilterMinmaxSupportTestCase : public deqp::TestCase
+{
+public:
+       /* Public methods */
+       TextureFilterMinmaxSupportTestCase(deqp::Context& context);
+
+       tcu::TestNode::IterateResult iterate();
+
+private:
+       /* Private members */
+       TextureFilterMinmaxUtils m_utils;
+};
+
+/** Test group which encapsulates all texture filter minmax conformance tests */
+class TextureFilterMinmax : public deqp::TestCaseGroup
+{
+public:
+       /* Public methods */
+       TextureFilterMinmax(deqp::Context& context);
+
+       void init();
+
+private:
+       TextureFilterMinmax(const TextureFilterMinmax& other);
+       TextureFilterMinmax& operator=(const TextureFilterMinmax& other);
+};
+
+} /* glcts namespace */
+
+#endif // _GL4CTEXTUREFILTERMINMAXTESTS_HPP
index cd912dcf5ff3abc5a7ecf50086dbca3040834e73..8da9ddef62c5fadac913f2d97f51eb7784a351c4 100644 (file)
 #define GL_NEGATIVE_ONE_TO_ONE                                                                                 0x935E
 #define GL_ZERO_TO_ONE                                                                                                 0x935F
 #define GL_CLEAR_TEXTURE                                                                                               0x9365
+#define GL_TEXTURE_REDUCTION_MODE_ARB                                                                  0x9366
+#define GL_WEIGHTED_AVERAGE_ARB                                                                                        0x9367
 #define GL_MULTISAMPLES_NV                                                                                             0x9371
 #define GL_SUPERSAMPLE_SCALE_X_NV                                                                              0x9372
 #define GL_SUPERSAMPLE_SCALE_Y_NV                                                                              0x9373
index 5ba7baab2dfadff1e02b685013164a13172cd913..638c53e5447cf35a0f5687c7690bb8de9126bae6 100644 (file)
@@ -101,6 +101,7 @@ EXTENSIONS                  = [
        'GL_ARB_sparse_texture',
        'GL_ARB_tessellation_shader',
        'GL_ARB_texture_barrier',
+       'GL_ARB_texture_filter_minmax',
        'GL_ARB_texture_storage',
        'GL_ARB_texture_storage_multisample',
        'GL_ARB_texture_multisample',