13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program OpenGL ES 3.0 Module
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * -------------------------------------------------
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License.
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License.
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*!
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Texture filtering tests.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es3fTextureFilteringTests.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glsTextureTestUtil.hpp"
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluPixelTransfer.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluTexture.hpp"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluTextureUtil.hpp"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTextureUtil.hpp"
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuImageCompare.hpp"
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTexLookupVerifier.hpp"
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuVectorUtil.hpp"
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp"
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deString.h"
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwFunctions.hpp"
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwEnums.hpp"
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gles3
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace Functional
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector;
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string;
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::TestLog;
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace gls::TextureTestUtil;
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TEX2D_VIEWPORT_WIDTH		= 64,
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TEX2D_VIEWPORT_HEIGHT		= 64,
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TEX2D_MIN_VIEWPORT_WIDTH	= 64,
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TEX2D_MIN_VIEWPORT_HEIGHT	= 64,
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TEX3D_VIEWPORT_WIDTH		= 64,
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TEX3D_VIEWPORT_HEIGHT		= 64,
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TEX3D_MIN_VIEWPORT_WIDTH	= 64,
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TEX3D_MIN_VIEWPORT_HEIGHT	= 64
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Texture2DFilteringCase : public tcu::TestCase
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									Texture2DFilteringCase		(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT, deUint32 internalFormat, int width, int height);
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									Texture2DFilteringCase		(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT, const std::vector<std::string>& filenames);
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									~Texture2DFilteringCase		(void);
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void							init						(void);
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void							deinit						(void);
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult					iterate						(void);
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									Texture2DFilteringCase		(const Texture2DFilteringCase& other);
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Texture2DFilteringCase&			operator=					(const Texture2DFilteringCase& other);
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::RenderContext&				m_renderCtx;
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::ContextInfo&			m_renderCtxInfo;
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					m_minFilter;
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					m_magFilter;
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					m_wrapS;
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					m_wrapT;
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					m_internalFormat;
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						m_width;
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						m_height;
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const std::vector<std::string>	m_filenames;
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct FilterCase
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::Texture2D*	texture;
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec2				minCoord;
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec2				maxCoord;
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FilterCase (void)
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			: texture(DE_NULL)
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FilterCase (const glu::Texture2D* tex_, const tcu::Vec2& minCoord_, const tcu::Vec2& maxCoord_)
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			: texture	(tex_)
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			, minCoord	(minCoord_)
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			, maxCoord	(maxCoord_)
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<glu::Texture2D*>	m_textures;
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<FilterCase>			m_cases;
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureRenderer					m_renderer;
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int								m_caseNdx;
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1193c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DFilteringCase::Texture2DFilteringCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT, deUint32 internalFormat, int width, int height)
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase			(testCtx, name, desc)
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderCtx		(renderCtx)
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderCtxInfo	(ctxInfo)
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_minFilter		(minFilter)
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_magFilter		(magFilter)
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapS			(wrapS)
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapT			(wrapT)
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_internalFormat	(internalFormat)
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width			(width)
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height			(height)
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderer		(renderCtx, testCtx, glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_caseNdx			(0)
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1353c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DFilteringCase::Texture2DFilteringCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT, const std::vector<std::string>& filenames)
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase			(testCtx, name, desc)
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderCtx		(renderCtx)
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderCtxInfo	(ctxInfo)
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_minFilter		(minFilter)
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_magFilter		(magFilter)
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapS			(wrapS)
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapT			(wrapT)
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_internalFormat	(GL_NONE)
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width			(0)
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height			(0)
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_filenames		(filenames)
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderer		(renderCtx, testCtx, glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_caseNdx			(0)
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1523c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DFilteringCase::~Texture2DFilteringCase (void)
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deinit();
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture2DFilteringCase::init (void)
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	try
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!m_filenames.empty())
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_textures.reserve(1);
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_textures.push_back(glu::Texture2D::create(m_renderCtx, m_renderCtxInfo, m_testCtx.getArchive(), (int)m_filenames.size(), m_filenames));
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Create 2 textures.
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_textures.reserve(2);
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int ndx = 0; ndx < 2; ndx++)
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_textures.push_back(new glu::Texture2D(m_renderCtx, m_internalFormat, m_width, m_height));
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool						mipmaps		= true;
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int						numLevels	= mipmaps ? deLog2Floor32(de::max(m_width, m_height))+1 : 1;
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const tcu::TextureFormatInfo	fmtInfo		= tcu::getTextureFormatInfo(m_textures[0]->getRefTexture().getFormat());
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const tcu::Vec4					cBias		= fmtInfo.valueMin;
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const tcu::Vec4					cScale		= fmtInfo.valueMax-fmtInfo.valueMin;
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Fill first gradient texture.
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::Vec4 gMin = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::Vec4 gMax = tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f)*cScale + cBias;
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_textures[0]->getRefTexture().allocLevel(levelNdx);
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::fillWithComponentGradients(m_textures[0]->getRefTexture().getLevel(levelNdx), gMin, gMax);
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Fill second with grid texture.
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32	step	= 0x00ffffff / numLevels;
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32	rgb		= step*levelNdx;
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32	colorA	= 0xff000000 | rgb;
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32	colorB	= 0xff000000 | ~rgb;
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_textures[1]->getRefTexture().allocLevel(levelNdx);
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::fillWithGrid(m_textures[1]->getRefTexture().getLevel(levelNdx), 4, toVec4(tcu::RGBA(colorA))*cScale + cBias, toVec4(tcu::RGBA(colorB))*cScale + cBias);
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Upload.
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (std::vector<glu::Texture2D*>::iterator i = m_textures.begin(); i != m_textures.end(); i++)
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				(*i)->upload();
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Compute cases.
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const struct
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int		texNdx;
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float	lodX;
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float	lodY;
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float	oX;
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float	oY;
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			} cases[] =
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{ 0,	1.6f,	2.9f,	-1.0f,	-2.7f	},
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{ 0,	-2.0f,	-1.35f,	-0.2f,	0.7f	},
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{ 1,	0.14f,	0.275f,	-1.5f,	-1.1f	},
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{ 1,	-0.92f,	-2.64f,	0.4f,	-0.1f	},
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			};
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const float	viewportW	= (float)de::min<int>(TEX2D_VIEWPORT_WIDTH, m_renderCtx.getRenderTarget().getWidth());
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const float	viewportH	= (float)de::min<int>(TEX2D_VIEWPORT_HEIGHT, m_renderCtx.getRenderTarget().getHeight());
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(cases); caseNdx++)
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int	texNdx	= de::clamp(cases[caseNdx].texNdx, 0, (int)m_textures.size()-1);
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const float	lodX	= cases[caseNdx].lodX;
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const float	lodY	= cases[caseNdx].lodY;
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const float	oX		= cases[caseNdx].oX;
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const float	oY		= cases[caseNdx].oY;
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const float	sX		= deFloatExp2(lodX)*viewportW / float(m_textures[texNdx]->getRefTexture().getWidth());
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const float	sY		= deFloatExp2(lodY)*viewportH / float(m_textures[texNdx]->getRefTexture().getHeight());
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_cases.push_back(FilterCase(m_textures[texNdx], tcu::Vec2(oX, oY), tcu::Vec2(oX+sX, oY+sY)));
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_caseNdx = 0;
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	catch (...)
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Clean up to save memory.
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Texture2DFilteringCase::deinit();
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw;
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture2DFilteringCase::deinit (void)
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (std::vector<glu::Texture2D*>::iterator i = m_textures.begin(); i != m_textures.end(); i++)
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete *i;
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_textures.clear();
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderer.clear();
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_cases.clear();
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2613c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DFilteringCase::IterateResult Texture2DFilteringCase::iterate (void)
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&			gl			= m_renderCtx.getFunctions();
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const RandomViewport			viewport	(m_renderCtx.getRenderTarget(), TEX2D_VIEWPORT_WIDTH, TEX2D_VIEWPORT_HEIGHT, deStringHash(getName()) ^ deInt32Hash(m_caseNdx));
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::TextureFormat		texFmt		= m_textures[0]->getRefTexture().getFormat();
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::TextureFormatInfo	fmtInfo		= tcu::getTextureFormatInfo(texFmt);
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const FilterCase&				curCase		= m_cases[m_caseNdx];
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::ScopedLogSection		section		(m_testCtx.getLog(), string("Test") + de::toString(m_caseNdx), string("Test ") + de::toString(m_caseNdx));
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ReferenceParams					refParams	(TEXTURETYPE_2D);
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface					rendered	(viewport.width, viewport.height);
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<float>					texCoord;
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (viewport.width < TEX2D_MIN_VIEWPORT_WIDTH || viewport.height < TEX2D_MIN_VIEWPORT_HEIGHT)
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::NotSupportedError("Too small render target", "", __FILE__, __LINE__);
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Setup params for reference.
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	refParams.sampler		= glu::mapGLSampler(m_wrapS, m_wrapT, m_minFilter, m_magFilter);
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	refParams.samplerType	= getSamplerType(texFmt);
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	refParams.lodMode		= LODMODE_EXACT;
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	refParams.colorBias		= fmtInfo.lookupBias;
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	refParams.colorScale	= fmtInfo.lookupScale;
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compute texture coordinates.
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << TestLog::Message << "Texture coordinates: " << curCase.minCoord << " -> " << curCase.maxCoord << TestLog::EndMessage;
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	computeQuadTexCoord2D(texCoord, curCase.minCoord, curCase.maxCoord);
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindTexture	(GL_TEXTURE_2D, curCase.texture->getGLTexture());
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	m_minFilter);
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	m_magFilter);
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		m_wrapS);
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		m_wrapT);
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderer.renderQuad(0, &texCoord[0], refParams);
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::readPixels(m_renderCtx, viewport.x, viewport.y, rendered.getAccess());
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool				isNearestOnly	= m_minFilter == GL_NEAREST && m_magFilter == GL_NEAREST;
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::PixelFormat	pixelFormat		= m_renderCtx.getRenderTarget().getPixelFormat();
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::IVec4		colorBits		= max(getBitsVec(pixelFormat) - (isNearestOnly ? 1 : 2), tcu::IVec4(0)); // 1 inaccurate bit if nearest only, 2 otherwise
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::LodPrecision		lodPrecision;
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::LookupPrecision	lookupPrecision;
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lodPrecision.derivateBits		= 18;
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lodPrecision.lodBits			= 6;
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lookupPrecision.colorThreshold	= tcu::computeFixedPointThreshold(colorBits) / refParams.colorScale;
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lookupPrecision.coordBits		= tcu::IVec3(20,20,0);
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lookupPrecision.uvwBits			= tcu::IVec3(7,7,0);
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lookupPrecision.colorMask		= getCompareMask(pixelFormat);
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool isHighQuality = verifyTextureResult(m_testCtx, rendered.getAccess(), curCase.texture->getRefTexture(),
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													   &texCoord[0], refParams, lookupPrecision, lodPrecision, pixelFormat);
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!isHighQuality)
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Evaluate against lower precision requirements.
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			lodPrecision.lodBits	= 4;
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			lookupPrecision.uvwBits	= tcu::IVec3(4,4,0);
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog() << TestLog::Message << "Warning: Verification against high precision requirements failed, trying with lower requirements." << TestLog::EndMessage;
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool isOk = verifyTextureResult(m_testCtx, rendered.getAccess(), curCase.texture->getRefTexture(),
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												  &texCoord[0], refParams, lookupPrecision, lodPrecision, pixelFormat);
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!isOk)
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_testCtx.getLog() << TestLog::Message << "ERROR: Verification against low precision requirements failed, failing test case." << TestLog::EndMessage;
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_testCtx.setTestResult(QP_TEST_RESULT_QUALITY_WARNING, "Low-quality filtering result");
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_caseNdx += 1;
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m_caseNdx < (int)m_cases.size() ? CONTINUE : STOP;
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass TextureCubeFilteringCase : public tcu::TestCase
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									TextureCubeFilteringCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT, bool onlySampleFaceInterior, deUint32 internalFormat, int width, int height);
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									TextureCubeFilteringCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT, bool onlySampleFaceInterior, const std::vector<std::string>& filenames);
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									~TextureCubeFilteringCase	(void);
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void							init						(void);
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void							deinit						(void);
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult					iterate						(void);
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									TextureCubeFilteringCase	(const TextureCubeFilteringCase& other);
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureCubeFilteringCase&		operator=					(const TextureCubeFilteringCase& other);
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::RenderContext&				m_renderCtx;
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::ContextInfo&			m_renderCtxInfo;
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					m_minFilter;
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					m_magFilter;
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					m_wrapS;
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					m_wrapT;
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool						m_onlySampleFaceInterior; //!< If true, we avoid sampling anywhere near a face's edges.
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					m_internalFormat;
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						m_width;
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						m_height;
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const std::vector<std::string>	m_filenames;
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct FilterCase
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::TextureCube*	texture;
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec2				bottomLeft;
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec2				topRight;
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FilterCase (void)
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			: texture(DE_NULL)
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FilterCase (const glu::TextureCube* tex_, const tcu::Vec2& bottomLeft_, const tcu::Vec2& topRight_)
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			: texture	(tex_)
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			, bottomLeft(bottomLeft_)
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			, topRight	(topRight_)
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<glu::TextureCube*>	m_textures;
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<FilterCase>			m_cases;
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureRenderer					m_renderer;
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int								m_caseNdx;
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3963c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeFilteringCase::TextureCubeFilteringCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT, bool onlySampleFaceInterior, deUint32 internalFormat, int width, int height)
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase					(testCtx, name, desc)
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderCtx				(renderCtx)
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderCtxInfo			(ctxInfo)
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_minFilter				(minFilter)
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_magFilter				(magFilter)
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapS					(wrapS)
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapT					(wrapT)
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_onlySampleFaceInterior	(onlySampleFaceInterior)
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_internalFormat			(internalFormat)
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width					(width)
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height					(height)
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderer				(renderCtx, testCtx, glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_caseNdx					(0)
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4133c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeFilteringCase::TextureCubeFilteringCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT, bool onlySampleFaceInterior, const std::vector<std::string>& filenames)
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase					(testCtx, name, desc)
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderCtx				(renderCtx)
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderCtxInfo			(ctxInfo)
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_minFilter				(minFilter)
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_magFilter				(magFilter)
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapS					(wrapS)
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapT					(wrapT)
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_onlySampleFaceInterior	(onlySampleFaceInterior)
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_internalFormat			(GL_NONE)
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width					(0)
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height					(0)
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_filenames				(filenames)
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderer				(renderCtx, testCtx, glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_caseNdx					(0)
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4313c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeFilteringCase::~TextureCubeFilteringCase (void)
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deinit();
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCubeFilteringCase::init (void)
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	try
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!m_filenames.empty())
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_textures.reserve(1);
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_textures.push_back(glu::TextureCube::create(m_renderCtx, m_renderCtxInfo, m_testCtx.getArchive(), (int)m_filenames.size() / 6, m_filenames));
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(m_width == m_height);
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_textures.reserve(2);
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int ndx = 0; ndx < 2; ndx++)
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_textures.push_back(new glu::TextureCube(m_renderCtx, m_internalFormat, m_width));
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				numLevels	= deLog2Floor32(de::max(m_width, m_height))+1;
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::TextureFormatInfo	fmtInfo		= tcu::getTextureFormatInfo(m_textures[0]->getRefTexture().getFormat());
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4				cBias		= fmtInfo.valueMin;
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4				cScale		= fmtInfo.valueMax-fmtInfo.valueMin;
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Fill first with gradient texture.
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			static const tcu::Vec4 gradients[tcu::CUBEFACE_LAST][2] =
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{ tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // negative x
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{ tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // positive x
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{ tcu::Vec4(0.0f, 0.5f, 0.0f, 1.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // negative y
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{ tcu::Vec4(0.0f, 0.0f, 0.5f, 1.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // positive y
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{ tcu::Vec4(0.0f, 0.0f, 0.0f, 0.5f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f) }, // negative z
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{ tcu::Vec4(0.5f, 0.5f, 0.5f, 1.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }  // positive z
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			};
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_textures[0]->getRefTexture().allocLevel((tcu::CubeFace)face, levelNdx);
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					tcu::fillWithComponentGradients(m_textures[0]->getRefTexture().getLevelFace(levelNdx, (tcu::CubeFace)face), gradients[face][0]*cScale + cBias, gradients[face][1]*cScale + cBias);
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Fill second with grid texture.
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					deUint32	step	= 0x00ffffff / (numLevels*tcu::CUBEFACE_LAST);
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					deUint32	rgb		= step*levelNdx*face;
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					deUint32	colorA	= 0xff000000 | rgb;
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					deUint32	colorB	= 0xff000000 | ~rgb;
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_textures[1]->getRefTexture().allocLevel((tcu::CubeFace)face, levelNdx);
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					tcu::fillWithGrid(m_textures[1]->getRefTexture().getLevelFace(levelNdx, (tcu::CubeFace)face), 4, toVec4(tcu::RGBA(colorA))*cScale + cBias, toVec4(tcu::RGBA(colorB))*cScale + cBias);
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Upload.
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (std::vector<glu::TextureCube*>::iterator i = m_textures.begin(); i != m_textures.end(); i++)
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				(*i)->upload();
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Compute cases
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const glu::TextureCube*	tex0	= m_textures[0];
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const glu::TextureCube* tex1	= m_textures.size() > 1 ? m_textures[1] : tex0;
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_onlySampleFaceInterior)
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_cases.push_back(FilterCase(tex0, tcu::Vec2(-0.8f, -0.8f), tcu::Vec2(0.8f,  0.8f)));	// minification
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_cases.push_back(FilterCase(tex0, tcu::Vec2(0.5f, 0.65f), tcu::Vec2(0.8f,  0.8f)));	// magnification
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_cases.push_back(FilterCase(tex1, tcu::Vec2(-0.8f, -0.8f), tcu::Vec2(0.8f,  0.8f)));	// minification
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_cases.push_back(FilterCase(tex1, tcu::Vec2(0.2f, 0.2f), tcu::Vec2(0.6f,  0.5f)));		// magnification
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (m_renderCtx.getRenderTarget().getNumSamples() == 0)
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_cases.push_back(FilterCase(tex0, tcu::Vec2(-1.25f, -1.2f), tcu::Vec2(1.2f, 1.25f)));	// minification
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_cases.push_back(FilterCase(tex0, tcu::Vec2(-1.19f, -1.3f), tcu::Vec2(1.1f, 1.35f)));	// minification - w/ tweak to avoid hitting triangle edges with face switchpoint
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_cases.push_back(FilterCase(tex0, tcu::Vec2(0.8f, 0.8f), tcu::Vec2(1.25f, 1.20f)));	// magnification
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_cases.push_back(FilterCase(tex1, tcu::Vec2(-1.19f, -1.3f), tcu::Vec2(1.1f, 1.35f)));	// minification
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_cases.push_back(FilterCase(tex1, tcu::Vec2(-1.2f, -1.1f), tcu::Vec2(-0.8f, -0.8f)));	// magnification
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_caseNdx = 0;
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	catch (...)
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Clean up to save memory.
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TextureCubeFilteringCase::deinit();
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw;
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCubeFilteringCase::deinit (void)
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (std::vector<glu::TextureCube*>::iterator i = m_textures.begin(); i != m_textures.end(); i++)
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete *i;
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_textures.clear();
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderer.clear();
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_cases.clear();
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* getFaceDesc (const tcu::CubeFace face)
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (face)
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::CUBEFACE_NEGATIVE_X:	return "-X";
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::CUBEFACE_POSITIVE_X:	return "+X";
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::CUBEFACE_NEGATIVE_Y:	return "-Y";
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::CUBEFACE_POSITIVE_Y:	return "+Y";
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::CUBEFACE_NEGATIVE_Z:	return "-Z";
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::CUBEFACE_POSITIVE_Z:	return "+Z";
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return DE_NULL;
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5583c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeFilteringCase::IterateResult TextureCubeFilteringCase::iterate (void)
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&			gl				= m_renderCtx.getFunctions();
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						viewportSize	= 28;
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const RandomViewport			viewport		(m_renderCtx.getRenderTarget(), viewportSize, viewportSize, deStringHash(getName()) ^ deInt32Hash(m_caseNdx));
5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::ScopedLogSection		iterSection		(m_testCtx.getLog(), string("Test") + de::toString(m_caseNdx), string("Test ") + de::toString(m_caseNdx));
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const FilterCase&				curCase			= m_cases[m_caseNdx];
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::TextureFormat&		texFmt			= curCase.texture->getRefTexture().getFormat();
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::TextureFormatInfo	fmtInfo			= tcu::getTextureFormatInfo(texFmt);
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ReferenceParams					sampleParams	(TEXTURETYPE_CUBE);
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (viewport.width < viewportSize || viewport.height < viewportSize)
5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::NotSupportedError("Too small render target", DE_NULL, __FILE__, __LINE__);
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Setup texture
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindTexture	(GL_TEXTURE_CUBE_MAP, curCase.texture->getGLTexture());
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,	m_minFilter);
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER,	m_magFilter);
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,		m_wrapS);
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,		m_wrapT);
5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Other state
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Params for reference computation.
5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleParams.sampler					= glu::mapGLSampler(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, m_minFilter, m_magFilter);
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleParams.sampler.seamlessCubeMap	= true;
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleParams.samplerType				= getSamplerType(texFmt);
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleParams.colorBias					= fmtInfo.lookupBias;
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleParams.colorScale					= fmtInfo.lookupScale;
5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleParams.lodMode					= LODMODE_EXACT;
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << TestLog::Message << "Coordinates: " << curCase.bottomLeft << " -> " << curCase.topRight << TestLog::EndMessage;
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::CubeFace		face		= tcu::CubeFace(faceNdx);
5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Surface			result		(viewport.width, viewport.height);
5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<float>			texCoord;
5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		computeQuadTexCoordCube(texCoord, face, curCase.bottomLeft, curCase.topRight);
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << TestLog::Message << "Face " << getFaceDesc(face) << TestLog::EndMessage;
6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// \todo Log texture coordinates.
6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_renderer.renderQuad(0, &texCoord[0], sampleParams);
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "Draw");
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::readPixels(m_renderCtx, viewport.x, viewport.y, result.getAccess());
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "Read pixels");
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool				isNearestOnly	= m_minFilter == GL_NEAREST && m_magFilter == GL_NEAREST;
6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const tcu::PixelFormat	pixelFormat		= m_renderCtx.getRenderTarget().getPixelFormat();
6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const tcu::IVec4		colorBits		= max(getBitsVec(pixelFormat) - (isNearestOnly ? 1 : 2), tcu::IVec4(0)); // 1 inaccurate bit if nearest only, 2 otherwise
6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::LodPrecision		lodPrecision;
6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::LookupPrecision	lookupPrecision;
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			lodPrecision.derivateBits		= 10;
6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			lodPrecision.lodBits			= 5;
6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			lookupPrecision.colorThreshold	= tcu::computeFixedPointThreshold(colorBits) / sampleParams.colorScale;
6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			lookupPrecision.coordBits		= tcu::IVec3(10,10,10);
6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			lookupPrecision.uvwBits			= tcu::IVec3(6,6,0);
6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			lookupPrecision.colorMask		= getCompareMask(pixelFormat);
6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool isHighQuality = verifyTextureResult(m_testCtx, result.getAccess(), curCase.texture->getRefTexture(),
6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														   &texCoord[0], sampleParams, lookupPrecision, lodPrecision, pixelFormat);
6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!isHighQuality)
6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// Evaluate against lower precision requirements.
6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				lodPrecision.lodBits	= 4;
6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				lookupPrecision.uvwBits	= tcu::IVec3(4,4,0);
6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_testCtx.getLog() << TestLog::Message << "Warning: Verification against high precision requirements failed, trying with lower requirements." << TestLog::EndMessage;
6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const bool isOk = verifyTextureResult(m_testCtx, result.getAccess(), curCase.texture->getRefTexture(),
6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													  &texCoord[0], sampleParams, lookupPrecision, lodPrecision, pixelFormat);
6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (!isOk)
6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_testCtx.getLog() << TestLog::Message << "ERROR: Verification against low precision requirements failed, failing test case." << TestLog::EndMessage;
6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_testCtx.setTestResult(QP_TEST_RESULT_QUALITY_WARNING, "Low-quality filtering result");
6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_caseNdx += 1;
6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m_caseNdx < (int)m_cases.size() ? CONTINUE : STOP;
6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// 2D array filtering
6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Texture2DArrayFilteringCase : public TestCase
6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									Texture2DArrayFilteringCase		(Context& context, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT, deUint32 internalFormat, int width, int height, int numLayers);
6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									~Texture2DArrayFilteringCase	(void);
6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void							init							(void);
6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void							deinit							(void);
6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult					iterate							(void);
6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									Texture2DArrayFilteringCase		(const Texture2DArrayFilteringCase&);
6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Texture2DArrayFilteringCase&	operator=						(const Texture2DArrayFilteringCase&);
6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					m_minFilter;
6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					m_magFilter;
6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					m_wrapS;
6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					m_wrapT;
6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					m_internalFormat;
6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						m_width;
6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						m_height;
6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						m_numLayers;
6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct FilterCase
6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::Texture2DArray*	texture;
6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec2					lod;
6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec2					offset;
6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec2					layerRange;
6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FilterCase (void)
6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			: texture(DE_NULL)
6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FilterCase (const glu::Texture2DArray* tex_, const tcu::Vec2& lod_, const tcu::Vec2& offset_, const tcu::Vec2& layerRange_)
6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			: texture	(tex_)
6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			, lod		(lod_)
6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			, offset	(offset_)
6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			, layerRange(layerRange_)
6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::Texture2DArray*			m_gradientTex;
7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::Texture2DArray*			m_gridTex;
7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureRenderer					m_renderer;
7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<FilterCase>			m_cases;
7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int								m_caseNdx;
7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7093c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DArrayFilteringCase::Texture2DArrayFilteringCase (Context& context, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT, deUint32 internalFormat, int width, int height, int numLayers)
7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase			(context, name, desc)
7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_minFilter		(minFilter)
7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_magFilter		(magFilter)
7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapS			(wrapS)
7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapT			(wrapT)
7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_internalFormat	(internalFormat)
7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width			(width)
7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height			(height)
7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numLayers		(numLayers)
7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_gradientTex		(DE_NULL)
7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_gridTex			(DE_NULL)
7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderer		(m_context.getRenderContext(), context.getTestContext(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_caseNdx			(0)
7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7263c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DArrayFilteringCase::~Texture2DArrayFilteringCase (void)
7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Texture2DArrayFilteringCase::deinit();
7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture2DArrayFilteringCase::init (void)
7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	try
7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::TextureFormat		texFmt		= glu::mapGLInternalFormat(m_internalFormat);
7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::TextureFormatInfo	fmtInfo		= tcu::getTextureFormatInfo(texFmt);
7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec4					cScale		= fmtInfo.valueMax-fmtInfo.valueMin;
7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec4					cBias		= fmtInfo.valueMin;
7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int						numLevels	= deLog2Floor32(de::max(m_width, m_height)) + 1;
7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Create textures.
7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_gradientTex	= new glu::Texture2DArray(m_context.getRenderContext(), m_internalFormat, m_width, m_height, m_numLayers);
7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_gridTex		= new glu::Texture2DArray(m_context.getRenderContext(), m_internalFormat, m_width, m_height, m_numLayers);
7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::IVec4 levelSwz[] =
7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::IVec4(0,1,2,3),
7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::IVec4(2,1,3,0),
7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::IVec4(3,0,1,2),
7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::IVec4(1,3,2,0),
7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Fill first gradient texture (gradient direction varies between layers).
7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_gradientTex->getRefTexture().allocLevel(levelNdx);
7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const tcu::PixelBufferAccess levelBuf = m_gradientTex->getRefTexture().getLevel(levelNdx);
7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int layerNdx = 0; layerNdx < m_numLayers; layerNdx++)
7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const tcu::IVec4	swz		= levelSwz[layerNdx%DE_LENGTH_OF_ARRAY(levelSwz)];
7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const tcu::Vec4		gMin	= tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f).swizzle(swz[0],swz[1],swz[2],swz[3])*cScale + cBias;
7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const tcu::Vec4		gMax	= tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f).swizzle(swz[0],swz[1],swz[2],swz[3])*cScale + cBias;
7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::fillWithComponentGradients(tcu::getSubregion(levelBuf, 0, 0, layerNdx, levelBuf.getWidth(), levelBuf.getHeight(), 1), gMin, gMax);
7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Fill second with grid texture (each layer has unique colors).
7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_gridTex->getRefTexture().allocLevel(levelNdx);
7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const tcu::PixelBufferAccess levelBuf = m_gridTex->getRefTexture().getLevel(levelNdx);
7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int layerNdx = 0; layerNdx < m_numLayers; layerNdx++)
7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const deUint32	step	= 0x00ffffff / (numLevels*m_numLayers - 1);
7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const deUint32	rgb		= step * (levelNdx + layerNdx*numLevels);
7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const deUint32	colorA	= 0xff000000 | rgb;
7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const deUint32	colorB	= 0xff000000 | ~rgb;
7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::fillWithGrid(tcu::getSubregion(levelBuf, 0, 0, layerNdx, levelBuf.getWidth(), levelBuf.getHeight(), 1),
7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								  4, tcu::RGBA(colorA).toVec()*cScale + cBias, tcu::RGBA(colorB).toVec()*cScale + cBias);
7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Upload.
7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_gradientTex->upload();
7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_gridTex->upload();
7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Test cases
7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_cases.push_back(FilterCase(m_gradientTex,	tcu::Vec2( 1.5f,  2.8f  ),	tcu::Vec2(-1.0f, -2.7f), tcu::Vec2(-0.5f, float(m_numLayers)+0.5f)));
7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_cases.push_back(FilterCase(m_gridTex,		tcu::Vec2( 0.2f,  0.175f),	tcu::Vec2(-2.0f, -3.7f), tcu::Vec2(-0.5f, float(m_numLayers)+0.5f)));
7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_cases.push_back(FilterCase(m_gridTex,		tcu::Vec2(-0.8f, -2.3f  ),	tcu::Vec2( 0.2f, -0.1f), tcu::Vec2(float(m_numLayers)+0.5f, -0.5f)));
7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Level rounding - only in single-sample configs as multisample configs may produce smooth transition at the middle.
7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_context.getRenderTarget().getNumSamples() == 0)
8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_cases.push_back(FilterCase(m_gradientTex,	tcu::Vec2(-2.0f, -1.5f  ),	tcu::Vec2(-0.1f,  0.9f), tcu::Vec2(1.50001f, 1.49999f)));
8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_caseNdx = 0;
8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	catch (...)
8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Clean up to save memory.
8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Texture2DArrayFilteringCase::deinit();
8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw;
8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture2DArrayFilteringCase::deinit (void)
8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_gradientTex;
8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_gridTex;
8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_gradientTex	= DE_NULL;
8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_gridTex		= DE_NULL;
8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderer.clear();
8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_cases.clear();
8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8253c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DArrayFilteringCase::IterateResult Texture2DArrayFilteringCase::iterate (void)
8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&			gl			= m_context.getRenderContext().getFunctions();
8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const RandomViewport			viewport	(m_context.getRenderTarget(), TEX3D_VIEWPORT_WIDTH, TEX3D_VIEWPORT_HEIGHT, deStringHash(getName()) ^ deInt32Hash(m_caseNdx));
8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const FilterCase&				curCase		= m_cases[m_caseNdx];
8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::TextureFormat		texFmt		= curCase.texture->getRefTexture().getFormat();
8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::TextureFormatInfo	fmtInfo		= tcu::getTextureFormatInfo(texFmt);
8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::ScopedLogSection		section		(m_testCtx.getLog(), string("Test") + de::toString(m_caseNdx), string("Test ") + de::toString(m_caseNdx));
8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ReferenceParams					refParams	(TEXTURETYPE_2D_ARRAY);
8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface					rendered	(viewport.width, viewport.height);
8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Vec3						texCoord[4];
8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (viewport.width < TEX3D_MIN_VIEWPORT_WIDTH || viewport.height < TEX3D_MIN_VIEWPORT_HEIGHT)
8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::NotSupportedError("Too small render target", "", __FILE__, __LINE__);
8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Setup params for reference.
8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	refParams.sampler		= glu::mapGLSampler(m_wrapS, m_wrapT, m_wrapT, m_minFilter, m_magFilter);
8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	refParams.samplerType	= getSamplerType(texFmt);
8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	refParams.lodMode		= LODMODE_EXACT;
8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	refParams.colorBias		= fmtInfo.lookupBias;
8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	refParams.colorScale	= fmtInfo.lookupScale;
8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compute texture coordinates.
8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << TestLog::Message << "Approximate lod per axis = " << curCase.lod << ", offset = " << curCase.offset << TestLog::EndMessage;
8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float	lodX	= curCase.lod.x();
8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float	lodY	= curCase.lod.y();
8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float	oX		= curCase.offset.x();
8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float	oY		= curCase.offset.y();
8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float	sX		= deFloatExp2(lodX)*float(viewport.width)	/ float(m_gradientTex->getRefTexture().getWidth());
8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float	sY		= deFloatExp2(lodY)*float(viewport.height)	/ float(m_gradientTex->getRefTexture().getHeight());
8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float	l0		= curCase.layerRange.x();
8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float	l1		= curCase.layerRange.y();
8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		texCoord[0] = tcu::Vec3(oX,		oY,		l0);
8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		texCoord[1] = tcu::Vec3(oX,		oY+sY,	l0*0.5f + l1*0.5f);
8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		texCoord[2] = tcu::Vec3(oX+sX,	oY,		l0*0.5f + l1*0.5f);
8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		texCoord[3] = tcu::Vec3(oX+sX,	oY+sY,	l1);
8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindTexture	(GL_TEXTURE_2D_ARRAY, curCase.texture->getGLTexture());
8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER,	m_minFilter);
8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER,	m_magFilter);
8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S,		m_wrapS);
8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T,		m_wrapT);
8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderer.renderQuad(0, (const float*)&texCoord[0], refParams);
8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::readPixels(m_context.getRenderContext(), viewport.x, viewport.y, rendered.getAccess());
8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool				isNearestOnly	= m_minFilter == GL_NEAREST && m_magFilter == GL_NEAREST;
8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::PixelFormat	pixelFormat		= m_context.getRenderTarget().getPixelFormat();
8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::IVec4		colorBits		= max(getBitsVec(pixelFormat) - (isNearestOnly ? 1 : 2), tcu::IVec4(0)); // 1 inaccurate bit if nearest only, 2 otherwise
8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::LodPrecision		lodPrecision;
8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::LookupPrecision	lookupPrecision;
8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lodPrecision.derivateBits		= 18;
8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lodPrecision.lodBits			= 6;
8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lookupPrecision.colorThreshold	= tcu::computeFixedPointThreshold(colorBits) / refParams.colorScale;
8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lookupPrecision.coordBits		= tcu::IVec3(20,20,20);
8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lookupPrecision.uvwBits			= tcu::IVec3(7,7,0);
8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lookupPrecision.colorMask		= getCompareMask(pixelFormat);
8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool isHighQuality = verifyTextureResult(m_testCtx, rendered.getAccess(), curCase.texture->getRefTexture(),
8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													   (const float*)&texCoord[0], refParams, lookupPrecision, lodPrecision, pixelFormat);
8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!isHighQuality)
8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Evaluate against lower precision requirements.
8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			lodPrecision.lodBits	= 4;
8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			lookupPrecision.uvwBits	= tcu::IVec3(4,4,0);
8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog() << TestLog::Message << "Warning: Verification against high precision requirements failed, trying with lower requirements." << TestLog::EndMessage;
9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool isOk = verifyTextureResult(m_testCtx, rendered.getAccess(), curCase.texture->getRefTexture(),
9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												  (const float*)&texCoord[0], refParams, lookupPrecision, lodPrecision, pixelFormat);
9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!isOk)
9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_testCtx.getLog() << TestLog::Message << "ERROR: Verification against low precision requirements failed, failing test case." << TestLog::EndMessage;
9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_testCtx.setTestResult(QP_TEST_RESULT_QUALITY_WARNING, "Low-quality filtering result");
9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_caseNdx += 1;
9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m_caseNdx < (int)m_cases.size() ? CONTINUE : STOP;
9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// 3D filtering
9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Texture3DFilteringCase : public TestCase
9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									Texture3DFilteringCase		(Context& context, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT, deUint32 wrapR, deUint32 internalFormat, int width, int height, int depth);
9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									~Texture3DFilteringCase		(void);
9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void							init						(void);
9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void							deinit						(void);
9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult					iterate						(void);
9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									Texture3DFilteringCase		(const Texture3DFilteringCase& other);
9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Texture3DFilteringCase&			operator=					(const Texture3DFilteringCase& other);
9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					m_minFilter;
9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					m_magFilter;
9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					m_wrapS;
9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					m_wrapT;
9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					m_wrapR;
9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					m_internalFormat;
9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						m_width;
9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						m_height;
9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						m_depth;
9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct FilterCase
9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::Texture3D*	texture;
9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec3				lod;
9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec3				offset;
9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FilterCase (void)
9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			: texture(DE_NULL)
9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FilterCase (const glu::Texture3D* tex_, const tcu::Vec3& lod_, const tcu::Vec3& offset_)
9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			: texture	(tex_)
9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			, lod		(lod_)
9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			, offset	(offset_)
9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::Texture3D*					m_gradientTex;
9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::Texture3D*					m_gridTex;
9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureRenderer					m_renderer;
9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<FilterCase>			m_cases;
9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int								m_caseNdx;
9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9733c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture3DFilteringCase::Texture3DFilteringCase (Context& context, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT, deUint32 wrapR, deUint32 internalFormat, int width, int height, int depth)
9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase			(context, name, desc)
9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_minFilter		(minFilter)
9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_magFilter		(magFilter)
9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapS			(wrapS)
9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapT			(wrapT)
9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapR			(wrapR)
9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_internalFormat	(internalFormat)
9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width			(width)
9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height			(height)
9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_depth			(depth)
9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_gradientTex		(DE_NULL)
9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_gridTex			(DE_NULL)
9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderer		(m_context.getRenderContext(), context.getTestContext(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_caseNdx			(0)
9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9913c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture3DFilteringCase::~Texture3DFilteringCase (void)
9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Texture3DFilteringCase::deinit();
9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture3DFilteringCase::init (void)
9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	try
9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::TextureFormat		texFmt		= glu::mapGLInternalFormat(m_internalFormat);
10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::TextureFormatInfo	fmtInfo		= tcu::getTextureFormatInfo(texFmt);
10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec4					cScale		= fmtInfo.valueMax-fmtInfo.valueMin;
10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec4					cBias		= fmtInfo.valueMin;
10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int						numLevels	= deLog2Floor32(de::max(de::max(m_width, m_height), m_depth)) + 1;
10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Create textures.
10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_gradientTex	= new glu::Texture3D(m_context.getRenderContext(), m_internalFormat, m_width, m_height, m_depth);
10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_gridTex		= new glu::Texture3D(m_context.getRenderContext(), m_internalFormat, m_width, m_height, m_depth);
10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Fill first gradient texture.
10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4 gMin = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4 gMax = tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f)*cScale + cBias;
10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_gradientTex->getRefTexture().allocLevel(levelNdx);
10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::fillWithComponentGradients(m_gradientTex->getRefTexture().getLevel(levelNdx), gMin, gMax);
10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Fill second with grid texture.
10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deUint32	step	= 0x00ffffff / numLevels;
10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deUint32	rgb		= step*levelNdx;
10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deUint32	colorA	= 0xff000000 | rgb;
10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deUint32	colorB	= 0xff000000 | ~rgb;
10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_gridTex->getRefTexture().allocLevel(levelNdx);
10293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::fillWithGrid(m_gridTex->getRefTexture().getLevel(levelNdx), 4, tcu::RGBA(colorA).toVec()*cScale + cBias, tcu::RGBA(colorB).toVec()*cScale + cBias);
10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Upload.
10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_gradientTex->upload();
10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_gridTex->upload();
10353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Test cases
10373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_cases.push_back(FilterCase(m_gradientTex,	tcu::Vec3(1.5f, 2.8f, 1.0f),	tcu::Vec3(-1.0f, -2.7f, -2.275f)));
10383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_cases.push_back(FilterCase(m_gradientTex,	tcu::Vec3(-2.0f, -1.5f, -1.8f),	tcu::Vec3(-0.1f, 0.9f, -0.25f)));
10393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_cases.push_back(FilterCase(m_gridTex,		tcu::Vec3(0.2f, 0.175f, 0.3f),	tcu::Vec3(-2.0f, -3.7f, -1.825f)));
10403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_cases.push_back(FilterCase(m_gridTex,		tcu::Vec3(-0.8f, -2.3f, -2.5f),	tcu::Vec3(0.2f, -0.1f, 1.325f)));
10413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_caseNdx = 0;
10433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
10443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	catch (...)
10463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Clean up to save memory.
10483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Texture3DFilteringCase::deinit();
10493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw;
10503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture3DFilteringCase::deinit (void)
10543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_gradientTex;
10563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_gridTex;
10573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_gradientTex	= DE_NULL;
10593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_gridTex		= DE_NULL;
10603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderer.clear();
10623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_cases.clear();
10633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10653c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture3DFilteringCase::IterateResult Texture3DFilteringCase::iterate (void)
10663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&			gl			= m_context.getRenderContext().getFunctions();
10683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const RandomViewport			viewport	(m_context.getRenderTarget(), TEX3D_VIEWPORT_WIDTH, TEX3D_VIEWPORT_HEIGHT, deStringHash(getName()) ^ deInt32Hash(m_caseNdx));
10693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const FilterCase&				curCase		= m_cases[m_caseNdx];
10703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::TextureFormat		texFmt		= curCase.texture->getRefTexture().getFormat();
10713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::TextureFormatInfo	fmtInfo		= tcu::getTextureFormatInfo(texFmt);
10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::ScopedLogSection		section		(m_testCtx.getLog(), string("Test") + de::toString(m_caseNdx), string("Test ") + de::toString(m_caseNdx));
10733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ReferenceParams					refParams	(TEXTURETYPE_3D);
10743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface					rendered	(viewport.width, viewport.height);
10753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Vec3						texCoord[4];
10763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (viewport.width < TEX3D_MIN_VIEWPORT_WIDTH || viewport.height < TEX3D_MIN_VIEWPORT_HEIGHT)
10783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::NotSupportedError("Too small render target", "", __FILE__, __LINE__);
10793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Setup params for reference.
10813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	refParams.sampler		= glu::mapGLSampler(m_wrapS, m_wrapT, m_wrapR, m_minFilter, m_magFilter);
10823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	refParams.samplerType	= getSamplerType(texFmt);
10833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	refParams.lodMode		= LODMODE_EXACT;
10843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	refParams.colorBias		= fmtInfo.lookupBias;
10853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	refParams.colorScale	= fmtInfo.lookupScale;
10863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compute texture coordinates.
10883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << TestLog::Message << "Approximate lod per axis = " << curCase.lod << ", offset = " << curCase.offset << TestLog::EndMessage;
10893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float	lodX	= curCase.lod.x();
10923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float	lodY	= curCase.lod.y();
10933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float	lodZ	= curCase.lod.z();
10943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float	oX		= curCase.offset.x();
10953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float	oY		= curCase.offset.y();
10963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float oZ		= curCase.offset.z();
10973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float	sX		= deFloatExp2(lodX)*float(viewport.width)							/ float(m_gradientTex->getRefTexture().getWidth());
10983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float	sY		= deFloatExp2(lodY)*float(viewport.height)							/ float(m_gradientTex->getRefTexture().getHeight());
10993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float	sZ		= deFloatExp2(lodZ)*float(de::max(viewport.width, viewport.height))	/ float(m_gradientTex->getRefTexture().getDepth());
11003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		texCoord[0] = tcu::Vec3(oX,		oY,		oZ);
11023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		texCoord[1] = tcu::Vec3(oX,		oY+sY,	oZ + sZ*0.5f);
11033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		texCoord[2] = tcu::Vec3(oX+sX,	oY,		oZ + sZ*0.5f);
11043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		texCoord[3] = tcu::Vec3(oX+sX,	oY+sY,	oZ + sZ);
11053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindTexture	(GL_TEXTURE_3D, curCase.texture->getGLTexture());
11083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER,	m_minFilter);
11093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER,	m_magFilter);
11103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S,		m_wrapS);
11113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T,		m_wrapT);
11123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R,		m_wrapR);
11133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
11153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderer.renderQuad(0, (const float*)&texCoord[0], refParams);
11163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::readPixels(m_context.getRenderContext(), viewport.x, viewport.y, rendered.getAccess());
11173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool				isNearestOnly	= m_minFilter == GL_NEAREST && m_magFilter == GL_NEAREST;
11203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::PixelFormat	pixelFormat		= m_context.getRenderTarget().getPixelFormat();
11213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::IVec4		colorBits		= max(getBitsVec(pixelFormat) - (isNearestOnly ? 1 : 2), tcu::IVec4(0)); // 1 inaccurate bit if nearest only, 2 otherwise
11223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::LodPrecision		lodPrecision;
11233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::LookupPrecision	lookupPrecision;
11243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lodPrecision.derivateBits		= 18;
11263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lodPrecision.lodBits			= 6;
11273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lookupPrecision.colorThreshold	= tcu::computeFixedPointThreshold(colorBits) / refParams.colorScale;
11283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lookupPrecision.coordBits		= tcu::IVec3(20,20,20);
11293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lookupPrecision.uvwBits			= tcu::IVec3(7,7,7);
11303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lookupPrecision.colorMask		= getCompareMask(pixelFormat);
11313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool isHighQuality = verifyTextureResult(m_testCtx, rendered.getAccess(), curCase.texture->getRefTexture(),
11333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													   (const float*)&texCoord[0], refParams, lookupPrecision, lodPrecision, pixelFormat);
11343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!isHighQuality)
11363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Evaluate against lower precision requirements.
11383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			lodPrecision.lodBits	= 4;
11393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			lookupPrecision.uvwBits	= tcu::IVec3(4,4,4);
11403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog() << TestLog::Message << "Warning: Verification against high precision requirements failed, trying with lower requirements." << TestLog::EndMessage;
11423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool isOk = verifyTextureResult(m_testCtx, rendered.getAccess(), curCase.texture->getRefTexture(),
11443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												  (const float*)&texCoord[0], refParams, lookupPrecision, lodPrecision, pixelFormat);
11453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!isOk)
11473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
11483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_testCtx.getLog() << TestLog::Message << "ERROR: Verification against low precision requirements failed, failing test case." << TestLog::EndMessage;
11493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
11503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
11513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
11523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_testCtx.setTestResult(QP_TEST_RESULT_QUALITY_WARNING, "Low-quality filtering result");
11533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_caseNdx += 1;
11573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m_caseNdx < (int)m_cases.size() ? CONTINUE : STOP;
11583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11603c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureFilteringTests::TextureFilteringTests (Context& context)
11613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCaseGroup(context, "filtering", "Texture Filtering Tests")
11623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11653c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureFilteringTests::~TextureFilteringTests (void)
11663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11693c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureFilteringTests::init (void)
11703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
11723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		name;
11743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32		mode;
11753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} wrapModes[] =
11763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "clamp",		GL_CLAMP_TO_EDGE },
11783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "repeat",		GL_REPEAT },
11793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "mirror",		GL_MIRRORED_REPEAT }
11803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
11813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
11833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		name;
11853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32		mode;
11863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} minFilterModes[] =
11873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "nearest",				GL_NEAREST					},
11893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "linear",					GL_LINEAR					},
11903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "nearest_mipmap_nearest",	GL_NEAREST_MIPMAP_NEAREST	},
11913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "linear_mipmap_nearest",	GL_LINEAR_MIPMAP_NEAREST	},
11923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "nearest_mipmap_linear",	GL_NEAREST_MIPMAP_LINEAR	},
11933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "linear_mipmap_linear",	GL_LINEAR_MIPMAP_LINEAR		}
11943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
11953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
11973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		name;
11993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32		mode;
12003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} magFilterModes[] =
12013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "nearest",	GL_NEAREST },
12033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "linear",		GL_LINEAR }
12043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
12053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
12073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int width;
12093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int height;
12103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} sizes2D[] =
12113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{   4,	  8 },
12133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{  32,	 64 },
12143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ 128,	128	},
12153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{   3,	  7 },
12163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{  31,	 55 },
12173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ 127,	 99 }
12183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
12193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
12213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int width;
12233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int height;
12243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} sizesCube[] =
12253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{   8,   8 },
12273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{  64,  64 },
12283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ 128, 128 },
12293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{   7,   7 },
12303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{  63,  63 }
12313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
12323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
12343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int width;
12363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int height;
12373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int numLayers;
12383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} sizes2DArray[] =
12393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{   4,   8,   8 },
12413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{  32,  64,  16 },
12423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ 128,  32,  64 },
12433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{   3,   7,   5 },
12443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{  63,  63,  63 }
12453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
12463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
12483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int width;
12503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int height;
12513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int depth;
12523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} sizes3D[] =
12533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{   4,   8,   8 },
12553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{  32,  64,  16 },
12563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ 128,  32,  64 },
12573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{   3,   7,   5 },
12583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{  63,  63,  63 }
12593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
12603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
12623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		name;
12643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32		format;
12653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} filterableFormatsByType[] =
12663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "rgba16f",		GL_RGBA16F			},
12683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "r11f_g11f_b10f",	GL_R11F_G11F_B10F	},
12693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "rgb9_e5",		GL_RGB9_E5			},
12703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "rgba8",			GL_RGBA8			},
12713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "rgba8_snorm",	GL_RGBA8_SNORM		},
12723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "rgb565",			GL_RGB565			},
12733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "rgba4",			GL_RGBA4			},
12743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "rgb5_a1",		GL_RGB5_A1			},
12753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "srgb8_alpha8",	GL_SRGB8_ALPHA8		},
12763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "rgb10_a2",		GL_RGB10_A2			}
12773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
12783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// 2D texture filtering.
12803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* group2D = new tcu::TestCaseGroup(m_testCtx, "2d", "2D Texture Filtering");
12823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(group2D);
12833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Formats.
12853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* formatsGroup = new tcu::TestCaseGroup(m_testCtx, "formats", "2D Texture Formats");
12863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		group2D->addChild(formatsGroup);
12873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(filterableFormatsByType); fmtNdx++)
12883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); filterNdx++)
12903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
12913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		minFilter	= minFilterModes[filterNdx].mode;
12923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const char*		filterName	= minFilterModes[filterNdx].name;
12933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		format		= filterableFormatsByType[fmtNdx].format;
12943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const char*		formatName	= filterableFormatsByType[fmtNdx].name;
12953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				bool			isMipmap	= minFilter != GL_NEAREST && minFilter != GL_LINEAR;
12963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		magFilter	= isMipmap ? GL_LINEAR : minFilter;
12973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				string			name		= string(formatName) + "_" + filterName;
12983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		wrapS		= GL_REPEAT;
12993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		wrapT		= GL_REPEAT;
13003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int				width		= 64;
13013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int				height		= 64;
13023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				formatsGroup->addChild(new Texture2DFilteringCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
13043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																  name.c_str(), "",
13053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																  minFilter, magFilter,
13063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																  wrapS, wrapT,
13073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																  format,
13083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																  width, height));
13093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
13103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// ETC1 format.
13133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			std::vector<std::string> filenames;
13153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i <= 7; i++)
13163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				filenames.push_back(string("data/etc1/photo_helsinki_mip_") + de::toString(i) + ".pkm");
13173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); filterNdx++)
13193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
13203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		minFilter	= minFilterModes[filterNdx].mode;
13213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const char*		filterName	= minFilterModes[filterNdx].name;
13223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				bool			isMipmap	= minFilter != GL_NEAREST && minFilter != GL_LINEAR;
13233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		magFilter	= isMipmap ? GL_LINEAR : minFilter;
13243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				string			name		= string("etc1_rgb8_") + filterName;
13253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		wrapS		= GL_REPEAT;
13263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		wrapT		= GL_REPEAT;
13273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				formatsGroup->addChild(new Texture2DFilteringCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
13293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																  name.c_str(), "",
13303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																  minFilter, magFilter,
13313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																  wrapS, wrapT,
13323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																  filenames));
13333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
13343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Sizes.
13373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* sizesGroup = new tcu::TestCaseGroup(m_testCtx, "sizes", "Texture Sizes");
13383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		group2D->addChild(sizesGroup);
13393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(sizes2D); sizeNdx++)
13403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); filterNdx++)
13423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
13433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		minFilter	= minFilterModes[filterNdx].mode;
13443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const char*		filterName	= minFilterModes[filterNdx].name;
13453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		format		= GL_RGBA8;
13463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				bool			isMipmap	= minFilter != GL_NEAREST && minFilter != GL_LINEAR;
13473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		magFilter	= isMipmap ? GL_LINEAR : minFilter;
13483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		wrapS		= GL_REPEAT;
13493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		wrapT		= GL_REPEAT;
13503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int				width		= sizes2D[sizeNdx].width;
13513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int				height		= sizes2D[sizeNdx].height;
13523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				string			name		= de::toString(width) + "x" + de::toString(height) + "_" + filterName;
13533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				sizesGroup->addChild(new Texture2DFilteringCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
13553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																name.c_str(), "",
13563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																minFilter, magFilter,
13573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																wrapS, wrapT,
13583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																format,
13593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																width, height));
13603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
13613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Wrap modes.
13643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* combinationsGroup = new tcu::TestCaseGroup(m_testCtx, "combinations", "Filter and wrap mode combinations");
13653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		group2D->addChild(combinationsGroup);
13663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int minFilterNdx = 0; minFilterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); minFilterNdx++)
13673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int magFilterNdx = 0; magFilterNdx < DE_LENGTH_OF_ARRAY(magFilterModes); magFilterNdx++)
13693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
13703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int wrapSNdx = 0; wrapSNdx < DE_LENGTH_OF_ARRAY(wrapModes); wrapSNdx++)
13713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
13723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int wrapTNdx = 0; wrapTNdx < DE_LENGTH_OF_ARRAY(wrapModes); wrapTNdx++)
13733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
13743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						deUint32		minFilter	= minFilterModes[minFilterNdx].mode;
13753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						deUint32		magFilter	= magFilterModes[magFilterNdx].mode;
13763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						deUint32		format		= GL_RGBA8;
13773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						deUint32		wrapS		= wrapModes[wrapSNdx].mode;
13783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						deUint32		wrapT		= wrapModes[wrapTNdx].mode;
13793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						int				width		= 63;
13803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						int				height		= 57;
13813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						string			name		= string(minFilterModes[minFilterNdx].name) + "_" + magFilterModes[magFilterNdx].name + "_" + wrapModes[wrapSNdx].name + "_" + wrapModes[wrapTNdx].name;
13823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						combinationsGroup->addChild(new Texture2DFilteringCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
13843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																			   name.c_str(), "",
13853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																			   minFilter, magFilter,
13863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																			   wrapS, wrapT,
13873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																			   format,
13883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																			   width, height));
13893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
13903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
13913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
13923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Cube map texture filtering.
13963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* groupCube = new tcu::TestCaseGroup(m_testCtx, "cube", "Cube Map Texture Filtering");
13983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(groupCube);
13993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Formats.
14013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* formatsGroup = new tcu::TestCaseGroup(m_testCtx, "formats", "2D Texture Formats");
14023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		groupCube->addChild(formatsGroup);
14033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(filterableFormatsByType); fmtNdx++)
14043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); filterNdx++)
14063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
14073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		minFilter	= minFilterModes[filterNdx].mode;
14083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const char*		filterName	= minFilterModes[filterNdx].name;
14093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		format		= filterableFormatsByType[fmtNdx].format;
14103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const char*		formatName	= filterableFormatsByType[fmtNdx].name;
14113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				bool			isMipmap	= minFilter != GL_NEAREST && minFilter != GL_LINEAR;
14123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		magFilter	= isMipmap ? GL_LINEAR : minFilter;
14133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				string			name		= string(formatName) + "_" + filterName;
14143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		wrapS		= GL_REPEAT;
14153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		wrapT		= GL_REPEAT;
14163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int				width		= 64;
14173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int				height		= 64;
14183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				formatsGroup->addChild(new TextureCubeFilteringCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
14203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	name.c_str(), "",
14213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	minFilter, magFilter,
14223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	wrapS, wrapT,
14233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	false /* always sample exterior as well */,
14243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	format,
14253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	width, height));
14263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
14273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// ETC1 format.
14303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			static const char* faceExt[] = { "neg_x", "pos_x", "neg_y", "pos_y", "neg_z", "pos_z" };
14323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int		numLevels	= 7;
14343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			vector<string>	filenames;
14353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int level = 0; level < numLevels; level++)
14363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
14373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					filenames.push_back(string("data/etc1/skybox_") + faceExt[face] + "_mip_" + de::toString(level) + ".pkm");
14383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); filterNdx++)
14403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
14413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		minFilter	= minFilterModes[filterNdx].mode;
14423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const char*		filterName	= minFilterModes[filterNdx].name;
14433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				bool			isMipmap	= minFilter != GL_NEAREST && minFilter != GL_LINEAR;
14443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		magFilter	= isMipmap ? GL_LINEAR : minFilter;
14453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				string			name		= string("etc1_rgb8_") + filterName;
14463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		wrapS		= GL_REPEAT;
14473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		wrapT		= GL_REPEAT;
14483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				formatsGroup->addChild(new TextureCubeFilteringCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
14503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	name.c_str(), "",
14513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	minFilter, magFilter,
14523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	wrapS, wrapT,
14533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	false /* always sample exterior as well */,
14543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	filenames));
14553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
14563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Sizes.
14593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* sizesGroup = new tcu::TestCaseGroup(m_testCtx, "sizes", "Texture Sizes");
14603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		groupCube->addChild(sizesGroup);
14613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(sizesCube); sizeNdx++)
14623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); filterNdx++)
14643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
14653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		minFilter	= minFilterModes[filterNdx].mode;
14663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const char*		filterName	= minFilterModes[filterNdx].name;
14673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		format		= GL_RGBA8;
14683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				bool			isMipmap	= minFilter != GL_NEAREST && minFilter != GL_LINEAR;
14693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		magFilter	= isMipmap ? GL_LINEAR : minFilter;
14703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		wrapS		= GL_REPEAT;
14713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		wrapT		= GL_REPEAT;
14723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int				width		= sizesCube[sizeNdx].width;
14733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int				height		= sizesCube[sizeNdx].height;
14743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				string			name		= de::toString(width) + "x" + de::toString(height) + "_" + filterName;
14753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				sizesGroup->addChild(new TextureCubeFilteringCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
14773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																  name.c_str(), "",
14783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																  minFilter, magFilter,
14793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																  wrapS, wrapT,
14803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																  false,
14813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																  format,
14823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																  width, height));
14833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
14843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Filter/wrap mode combinations.
14873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* combinationsGroup = new tcu::TestCaseGroup(m_testCtx, "combinations", "Filter and wrap mode combinations");
14883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		groupCube->addChild(combinationsGroup);
14893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int minFilterNdx = 0; minFilterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); minFilterNdx++)
14903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int magFilterNdx = 0; magFilterNdx < DE_LENGTH_OF_ARRAY(magFilterModes); magFilterNdx++)
14923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
14933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int wrapSNdx = 0; wrapSNdx < DE_LENGTH_OF_ARRAY(wrapModes); wrapSNdx++)
14943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
14953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int wrapTNdx = 0; wrapTNdx < DE_LENGTH_OF_ARRAY(wrapModes); wrapTNdx++)
14963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
14973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						deUint32		minFilter	= minFilterModes[minFilterNdx].mode;
14983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						deUint32		magFilter	= magFilterModes[magFilterNdx].mode;
14993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						deUint32		format		= GL_RGBA8;
15003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						deUint32		wrapS		= wrapModes[wrapSNdx].mode;
15013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						deUint32		wrapT		= wrapModes[wrapTNdx].mode;
15023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						int				width		= 63;
15033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						int				height		= 63;
15043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						string			name		= string(minFilterModes[minFilterNdx].name) + "_" + magFilterModes[magFilterNdx].name + "_" + wrapModes[wrapSNdx].name + "_" + wrapModes[wrapTNdx].name;
15053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						combinationsGroup->addChild(new TextureCubeFilteringCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
15073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				 name.c_str(), "",
15083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				 minFilter, magFilter,
15093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				 wrapS, wrapT,
15103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				 false,
15113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				 format,
15123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				 width, height));
15133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
15143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
15153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
15163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Cases with no visible cube edges.
15193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* onlyFaceInteriorGroup = new tcu::TestCaseGroup(m_testCtx, "no_edges_visible", "Don't sample anywhere near a face's edges");
15203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		groupCube->addChild(onlyFaceInteriorGroup);
15213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int isLinearI = 0; isLinearI <= 1; isLinearI++)
15233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
15243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bool		isLinear	= isLinearI != 0;
15253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deUint32	filter		= isLinear ? GL_LINEAR : GL_NEAREST;
15263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			onlyFaceInteriorGroup->addChild(new TextureCubeFilteringCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
15283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 isLinear ? "linear" : "nearest", "",
15293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 filter, filter,
15303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 GL_REPEAT, GL_REPEAT,
15313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 true,
15323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 GL_RGBA8,
15333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 63, 63));
15343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// 2D array texture filtering.
15383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* const group2DArray = new tcu::TestCaseGroup(m_testCtx, "2d_array", "2D Array Texture Filtering");
15403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(group2DArray);
15413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Formats.
15433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* const formatsGroup = new tcu::TestCaseGroup(m_testCtx, "formats", "2D Array Texture Formats");
15443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		group2DArray->addChild(formatsGroup);
15453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(filterableFormatsByType); fmtNdx++)
15463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
15473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); filterNdx++)
15483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
15493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		minFilter	= minFilterModes[filterNdx].mode;
15503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const char*		filterName	= minFilterModes[filterNdx].name;
15513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		format		= filterableFormatsByType[fmtNdx].format;
15523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const char*		formatName	= filterableFormatsByType[fmtNdx].name;
15533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				bool			isMipmap	= minFilter != GL_NEAREST && minFilter != GL_LINEAR;
15543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		magFilter	= isMipmap ? GL_LINEAR : minFilter;
15553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				string			name		= string(formatName) + "_" + filterName;
15563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		wrapS		= GL_REPEAT;
15573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		wrapT		= GL_REPEAT;
15583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int				width		= 128;
15593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int				height		= 128;
15603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int				numLayers	= 8;
15613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				formatsGroup->addChild(new Texture2DArrayFilteringCase(m_context,
15633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	   name.c_str(), "",
15643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	   minFilter, magFilter,
15653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	   wrapS, wrapT,
15663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	   format,
15673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	   width, height, numLayers));
15683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
15693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Sizes.
15723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* sizesGroup = new tcu::TestCaseGroup(m_testCtx, "sizes", "Texture Sizes");
15733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		group2DArray->addChild(sizesGroup);
15743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(sizes2DArray); sizeNdx++)
15753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
15763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); filterNdx++)
15773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
15783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		minFilter	= minFilterModes[filterNdx].mode;
15793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const char*		filterName	= minFilterModes[filterNdx].name;
15803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		format		= GL_RGBA8;
15813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				bool			isMipmap	= minFilter != GL_NEAREST && minFilter != GL_LINEAR;
15823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		magFilter	= isMipmap ? GL_LINEAR : minFilter;
15833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		wrapS		= GL_REPEAT;
15843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		wrapT		= GL_REPEAT;
15853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int				width		= sizes2DArray[sizeNdx].width;
15863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int				height		= sizes2DArray[sizeNdx].height;
15873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int				numLayers	= sizes2DArray[sizeNdx].numLayers;
15883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				string			name		= de::toString(width) + "x" + de::toString(height) + "x" + de::toString(numLayers) + "_" + filterName;
15893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				sizesGroup->addChild(new Texture2DArrayFilteringCase(m_context,
15913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	 name.c_str(), "",
15923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	 minFilter, magFilter,
15933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	 wrapS, wrapT,
15943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	 format,
15953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	 width, height, numLayers));
15963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
15973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Wrap modes.
16003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* const combinationsGroup = new tcu::TestCaseGroup(m_testCtx, "combinations", "Filter and wrap mode combinations");
16013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		group2DArray->addChild(combinationsGroup);
16023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int minFilterNdx = 0; minFilterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); minFilterNdx++)
16033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
16043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int magFilterNdx = 0; magFilterNdx < DE_LENGTH_OF_ARRAY(magFilterModes); magFilterNdx++)
16053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
16063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int wrapSNdx = 0; wrapSNdx < DE_LENGTH_OF_ARRAY(wrapModes); wrapSNdx++)
16073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
16083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int wrapTNdx = 0; wrapTNdx < DE_LENGTH_OF_ARRAY(wrapModes); wrapTNdx++)
16093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
16103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						deUint32		minFilter	= minFilterModes[minFilterNdx].mode;
16113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						deUint32		magFilter	= magFilterModes[magFilterNdx].mode;
16123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						deUint32		format		= GL_RGBA8;
16133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						deUint32		wrapS		= wrapModes[wrapSNdx].mode;
16143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						deUint32		wrapT		= wrapModes[wrapTNdx].mode;
16153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						int				width		= 123;
16163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						int				height		= 107;
16173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						int				numLayers	= 7;
16183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						string			name		= string(minFilterModes[minFilterNdx].name) + "_" + magFilterModes[magFilterNdx].name + "_" + wrapModes[wrapSNdx].name + "_" + wrapModes[wrapTNdx].name;
16193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						combinationsGroup->addChild(new Texture2DArrayFilteringCase(m_context,
16213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																					name.c_str(), "",
16223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																					minFilter, magFilter,
16233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																					wrapS, wrapT,
16243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																					format,
16253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																					width, height, numLayers));
16263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
16273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
16283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
16293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
16303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// 3D texture filtering.
16333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* group3D = new tcu::TestCaseGroup(m_testCtx, "3d", "3D Texture Filtering");
16353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(group3D);
16363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Formats.
16383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* formatsGroup = new tcu::TestCaseGroup(m_testCtx, "formats", "3D Texture Formats");
16393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		group3D->addChild(formatsGroup);
16403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(filterableFormatsByType); fmtNdx++)
16413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
16423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); filterNdx++)
16433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
16443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		minFilter	= minFilterModes[filterNdx].mode;
16453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const char*		filterName	= minFilterModes[filterNdx].name;
16463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		format		= filterableFormatsByType[fmtNdx].format;
16473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const char*		formatName	= filterableFormatsByType[fmtNdx].name;
16483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				bool			isMipmap	= minFilter != GL_NEAREST && minFilter != GL_LINEAR;
16493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		magFilter	= isMipmap ? GL_LINEAR : minFilter;
16503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				string			name		= string(formatName) + "_" + filterName;
16513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		wrapS		= GL_REPEAT;
16523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		wrapT		= GL_REPEAT;
16533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		wrapR		= GL_REPEAT;
16543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int				width		= 64;
16553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int				height		= 64;
16563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int				depth		= 64;
16573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				formatsGroup->addChild(new Texture3DFilteringCase(m_context,
16593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																  name.c_str(), "",
16603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																  minFilter, magFilter,
16613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																  wrapS, wrapT, wrapR,
16623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																  format,
16633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																  width, height, depth));
16643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
16653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
16663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Sizes.
16683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* sizesGroup = new tcu::TestCaseGroup(m_testCtx, "sizes", "Texture Sizes");
16693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		group3D->addChild(sizesGroup);
16703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(sizes3D); sizeNdx++)
16713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
16723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); filterNdx++)
16733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
16743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		minFilter	= minFilterModes[filterNdx].mode;
16753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const char*		filterName	= minFilterModes[filterNdx].name;
16763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		format		= GL_RGBA8;
16773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				bool			isMipmap	= minFilter != GL_NEAREST && minFilter != GL_LINEAR;
16783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		magFilter	= isMipmap ? GL_LINEAR : minFilter;
16793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		wrapS		= GL_REPEAT;
16803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		wrapT		= GL_REPEAT;
16813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32		wrapR		= GL_REPEAT;
16823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int				width		= sizes3D[sizeNdx].width;
16833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int				height		= sizes3D[sizeNdx].height;
16843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int				depth		= sizes3D[sizeNdx].depth;
16853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				string			name		= de::toString(width) + "x" + de::toString(height) + "x" + de::toString(depth) + "_" + filterName;
16863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				sizesGroup->addChild(new Texture3DFilteringCase(m_context,
16883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																name.c_str(), "",
16893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																minFilter, magFilter,
16903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																wrapS, wrapT, wrapR,
16913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																format,
16923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																width, height, depth));
16933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
16943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
16953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Wrap modes.
16973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* combinationsGroup = new tcu::TestCaseGroup(m_testCtx, "combinations", "Filter and wrap mode combinations");
16983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		group3D->addChild(combinationsGroup);
16993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int minFilterNdx = 0; minFilterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); minFilterNdx++)
17003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int magFilterNdx = 0; magFilterNdx < DE_LENGTH_OF_ARRAY(magFilterModes); magFilterNdx++)
17023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
17033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int wrapSNdx = 0; wrapSNdx < DE_LENGTH_OF_ARRAY(wrapModes); wrapSNdx++)
17043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
17053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int wrapTNdx = 0; wrapTNdx < DE_LENGTH_OF_ARRAY(wrapModes); wrapTNdx++)
17063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
17073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						for (int wrapRNdx = 0; wrapRNdx < DE_LENGTH_OF_ARRAY(wrapModes); wrapRNdx++)
17083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						{
17093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							deUint32		minFilter	= minFilterModes[minFilterNdx].mode;
17103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							deUint32		magFilter	= magFilterModes[magFilterNdx].mode;
17113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							deUint32		format		= GL_RGBA8;
17123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							deUint32		wrapS		= wrapModes[wrapSNdx].mode;
17133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							deUint32		wrapT		= wrapModes[wrapTNdx].mode;
17143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							deUint32		wrapR		= wrapModes[wrapRNdx].mode;
17153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							int				width		= 63;
17163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							int				height		= 57;
17173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							int				depth		= 67;
17183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							string			name		= string(minFilterModes[minFilterNdx].name) + "_" + magFilterModes[magFilterNdx].name + "_" + wrapModes[wrapSNdx].name + "_" + wrapModes[wrapTNdx].name + "_" + wrapModes[wrapRNdx].name;
17193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							combinationsGroup->addChild(new Texture3DFilteringCase(m_context,
17213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				   name.c_str(), "",
17223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				   minFilter, magFilter,
17233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				   wrapS, wrapT, wrapR,
17243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				   format,
17253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				   width, height, depth));
17263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						}
17273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
17283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
17293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
17303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
17313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Functional
17353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles3
17363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp
1737