13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program OpenGL ES 2.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 "es2fTextureFilteringTests.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glsTextureTestUtil.hpp"
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluTexture.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluStrUtil.hpp"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluTextureUtil.hpp"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluPixelTransfer.hpp"
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestLog.hpp"
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTextureUtil.hpp"
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTexLookupVerifier.hpp"
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuVectorUtil.hpp"
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp"
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwFunctions.hpp"
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwEnums.hpp"
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gles2
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace Functional
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::TestLog;
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector;
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string;
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Sampler;
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace glu;
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace gls::TextureTestUtil;
51c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketusing namespace glu::TextureTestUtil;
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VIEWPORT_WIDTH		= 64,
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VIEWPORT_HEIGHT		= 64,
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MIN_VIEWPORT_WIDTH	= 64,
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MIN_VIEWPORT_HEIGHT	= 64
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Texture2DFilteringCase : public tcu::TestCase
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
643c827367444ee418f129b2c238299f49d3264554Jarkko 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 format, deUint32 dataType, int width, int height);
653c827367444ee418f129b2c238299f49d3264554Jarkko 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);
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									~Texture2DFilteringCase		(void);
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void							init						(void);
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void							deinit						(void);
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult					iterate						(void);
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									Texture2DFilteringCase		(const Texture2DFilteringCase& other);
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Texture2DFilteringCase&			operator=					(const Texture2DFilteringCase& other);
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::RenderContext&				m_renderCtx;
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::ContextInfo&			m_renderCtxInfo;
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					m_minFilter;
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					m_magFilter;
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					m_wrapS;
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					m_wrapT;
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					m_format;
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					m_dataType;
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						m_width;
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						m_height;
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const std::vector<std::string>	m_filenames;
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct FilterCase
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::Texture2D*	texture;
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec2				minCoord;
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec2				maxCoord;
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FilterCase (void)
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			: texture(DE_NULL)
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FilterCase (const glu::Texture2D* tex_, const tcu::Vec2& minCoord_, const tcu::Vec2& maxCoord_)
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			: texture	(tex_)
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			, minCoord	(minCoord_)
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			, maxCoord	(maxCoord_)
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<glu::Texture2D*>	m_textures;
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<FilterCase>			m_cases;
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureRenderer					m_renderer;
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int								m_caseNdx;
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1183c827367444ee418f129b2c238299f49d3264554Jarkko 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 format, deUint32 dataType, int width, int height)
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase			(testCtx, name, desc)
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderCtx		(renderCtx)
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderCtxInfo	(ctxInfo)
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_minFilter		(minFilter)
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_magFilter		(magFilter)
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapS			(wrapS)
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapT			(wrapT)
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_format			(format)
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_dataType		(dataType)
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width			(width)
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height			(height)
130469002caa1ccd58f59f53a1bf3dbac4cf6a5d817Jarkko Pöyry	, m_renderer		(renderCtx, testCtx.getLog(), glu::GLSL_VERSION_100_ES, glu::PRECISION_MEDIUMP)
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_format			(GL_NONE)
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_dataType		(GL_NONE)
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width			(0)
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height			(0)
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_filenames		(filenames)
148469002caa1ccd58f59f53a1bf3dbac4cf6a5d817Jarkko Pöyry	, m_renderer		(renderCtx, testCtx.getLog(), glu::GLSL_VERSION_100_ES, glu::PRECISION_MEDIUMP)
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_caseNdx			(0)
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1533c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DFilteringCase::~Texture2DFilteringCase (void)
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deinit();
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture2DFilteringCase::init (void)
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	try
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!m_filenames.empty())
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_textures.reserve(1);
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_textures.push_back(glu::Texture2D::create(m_renderCtx, m_renderCtxInfo, m_testCtx.getArchive(), (int)m_filenames.size(), m_filenames));
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Create 2 textures.
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_textures.reserve(2);
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int ndx = 0; ndx < 2; ndx++)
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_textures.push_back(new glu::Texture2D(m_renderCtx, m_format, m_dataType, m_width, m_height));
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bool					mipmaps		= deIsPowerOfTwo32(m_width) && deIsPowerOfTwo32(m_height);
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						numLevels	= mipmaps ? deLog2Floor32(de::max(m_width, m_height))+1 : 1;
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::TextureFormatInfo	fmtInfo		= tcu::getTextureFormatInfo(m_textures[0]->getRefTexture().getFormat());
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4				cBias		= fmtInfo.valueMin;
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4				cScale		= fmtInfo.valueMax-fmtInfo.valueMin;
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Fill first gradient texture.
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::Vec4 gMin = tcu::Vec4(-0.5f, -0.5f, -0.5f, 2.0f)*cScale + cBias;
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::Vec4 gMax = tcu::Vec4( 1.0f,  1.0f,  1.0f, 0.0f)*cScale + cBias;
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_textures[0]->getRefTexture().allocLevel(levelNdx);
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::fillWithComponentGradients(m_textures[0]->getRefTexture().getLevel(levelNdx), gMin, gMax);
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Fill second with grid texture.
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32	step	= 0x00ffffff / numLevels;
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32	rgb		= step*levelNdx;
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32	colorA	= 0xff000000 | rgb;
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32	colorB	= 0xff000000 | ~rgb;
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_textures[1]->getRefTexture().allocLevel(levelNdx);
199c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket				tcu::fillWithGrid(m_textures[1]->getRefTexture().getLevel(levelNdx), 4, tcu::RGBA(colorA).toVec()*cScale + cBias, tcu::RGBA(colorB).toVec()*cScale + cBias);
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Upload.
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (std::vector<glu::Texture2D*>::iterator i = m_textures.begin(); i != m_textures.end(); i++)
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				(*i)->upload();
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Compute cases.
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const struct
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int		texNdx;
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float	lodX;
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float	lodY;
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float	oX;
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float	oY;
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			} cases[] =
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{ 0,	1.6f,	2.9f,	-1.0f,	-2.7f	},
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{ 0,	-2.0f,	-1.35f,	-0.2f,	0.7f	},
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{ 1,	0.14f,	0.275f,	-1.5f,	-1.1f	},
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{ 1,	-0.92f,	-2.64f,	0.4f,	-0.1f	},
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			};
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const float	viewportW	= (float)de::min<int>(VIEWPORT_WIDTH, m_renderCtx.getRenderTarget().getWidth());
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const float	viewportH	= (float)de::min<int>(VIEWPORT_HEIGHT, m_renderCtx.getRenderTarget().getHeight());
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(cases); caseNdx++)
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int	texNdx	= de::clamp(cases[caseNdx].texNdx, 0, (int)m_textures.size()-1);
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const float	lodX	= cases[caseNdx].lodX;
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const float	lodY	= cases[caseNdx].lodY;
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const float	oX		= cases[caseNdx].oX;
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const float	oY		= cases[caseNdx].oY;
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const float	sX		= deFloatExp2(lodX)*viewportW / float(m_textures[texNdx]->getRefTexture().getWidth());
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const float	sY		= deFloatExp2(lodY)*viewportH / float(m_textures[texNdx]->getRefTexture().getHeight());
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_cases.push_back(FilterCase(m_textures[texNdx], tcu::Vec2(oX, oY), tcu::Vec2(oX+sX, oY+sY)));
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_caseNdx = 0;
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	catch (...)
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Clean up to save memory.
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Texture2DFilteringCase::deinit();
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw;
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture2DFilteringCase::deinit (void)
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (std::vector<glu::Texture2D*>::iterator i = m_textures.begin(); i != m_textures.end(); i++)
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete *i;
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_textures.clear();
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderer.clear();
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_cases.clear();
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2623c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DFilteringCase::IterateResult Texture2DFilteringCase::iterate (void)
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&			gl			= m_renderCtx.getFunctions();
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const RandomViewport			viewport	(m_renderCtx.getRenderTarget(), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, deStringHash(getName()) ^ deInt32Hash(m_caseNdx));
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::TextureFormat		texFmt		= m_textures[0]->getRefTexture().getFormat();
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::TextureFormatInfo	fmtInfo		= tcu::getTextureFormatInfo(texFmt);
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const FilterCase&				curCase		= m_cases[m_caseNdx];
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::ScopedLogSection		section		(m_testCtx.getLog(), string("Test") + de::toString(m_caseNdx), string("Test ") + de::toString(m_caseNdx));
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ReferenceParams					refParams	(TEXTURETYPE_2D);
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface					rendered	(viewport.width, viewport.height);
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<float>					texCoord;
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (viewport.width < MIN_VIEWPORT_WIDTH || viewport.height < MIN_VIEWPORT_HEIGHT)
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::NotSupportedError("Too small viewport", "", __FILE__, __LINE__);
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Setup params for reference.
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	refParams.sampler		= mapGLSampler(m_wrapS, m_wrapT, m_minFilter, m_magFilter);
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	refParams.samplerType	= getSamplerType(texFmt);
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	refParams.lodMode		= LODMODE_EXACT;
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	refParams.colorBias		= fmtInfo.lookupBias;
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	refParams.colorScale	= fmtInfo.lookupScale;
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compute texture coordinates.
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << TestLog::Message << "Texture coordinates: " << curCase.minCoord << " -> " << curCase.maxCoord << TestLog::EndMessage;
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	computeQuadTexCoord2D(texCoord, curCase.minCoord, curCase.maxCoord);
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindTexture	(GL_TEXTURE_2D, curCase.texture->getGLTexture());
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	m_minFilter);
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	m_magFilter);
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		m_wrapS);
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		m_wrapT);
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderer.renderQuad(0, &texCoord[0], refParams);
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::readPixels(m_renderCtx, viewport.x, viewport.y, rendered.getAccess());
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool				isNearestOnly	= m_minFilter == GL_NEAREST && m_magFilter == GL_NEAREST;
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::PixelFormat	pixelFormat		= m_renderCtx.getRenderTarget().getPixelFormat();
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::IVec4		colorBits		= max(getBitsVec(pixelFormat) - (isNearestOnly ? 1 : 2), tcu::IVec4(0)); // 1 inaccurate bit if nearest only, 2 otherwise
302433645782506cbdf8fa8b113ea0b5aa8ae761f0cPyry Haulos		tcu::LodPrecision		lodPrecision;
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::LookupPrecision	lookupPrecision;
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30577580092ddcda5530da88a3304fd2c467c0d5e70Pyry Haulos		lodPrecision.derivateBits		= 7;
30677580092ddcda5530da88a3304fd2c467c0d5e70Pyry Haulos		lodPrecision.lodBits			= 4;
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lookupPrecision.colorThreshold	= tcu::computeFixedPointThreshold(colorBits) / refParams.colorScale;
30877580092ddcda5530da88a3304fd2c467c0d5e70Pyry Haulos		lookupPrecision.coordBits		= tcu::IVec3(9,9,0); // mediump interpolation
30977580092ddcda5530da88a3304fd2c467c0d5e70Pyry Haulos		lookupPrecision.uvwBits			= tcu::IVec3(5,5,0);
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lookupPrecision.colorMask		= getCompareMask(pixelFormat);
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool isOk = verifyTextureResult(m_testCtx, rendered.getAccess(), curCase.texture->getRefTexture(),
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											  &texCoord[0], refParams, lookupPrecision, lodPrecision, pixelFormat);
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!isOk)
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_caseNdx += 1;
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m_caseNdx < (int)m_cases.size() ? CONTINUE : STOP;
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass TextureCubeFilteringCase : public tcu::TestCase
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
3273c827367444ee418f129b2c238299f49d3264554Jarkko 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, deUint32 format, deUint32 dataType, int width, int height);
3283c827367444ee418f129b2c238299f49d3264554Jarkko 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, const std::vector<std::string>& filenames);
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									~TextureCubeFilteringCase	(void);
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void							init						(void);
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void							deinit						(void);
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult					iterate						(void);
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									TextureCubeFilteringCase	(const TextureCubeFilteringCase& other);
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureCubeFilteringCase&		operator=					(const TextureCubeFilteringCase& other);
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::RenderContext&				m_renderCtx;
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::ContextInfo&			m_renderCtxInfo;
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					m_minFilter;
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					m_magFilter;
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					m_wrapS;
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					m_wrapT;
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					m_format;
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					m_dataType;
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						m_width;
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						m_height;
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const std::vector<std::string>	m_filenames;
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct FilterCase
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::TextureCube*	texture;
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec2				bottomLeft;
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec2				topRight;
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FilterCase (void)
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			: texture(DE_NULL)
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FilterCase (const glu::TextureCube* tex_, const tcu::Vec2& bottomLeft_, const tcu::Vec2& topRight_)
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			: texture	(tex_)
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			, bottomLeft(bottomLeft_)
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			, topRight	(topRight_)
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<glu::TextureCube*>	m_textures;
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<FilterCase>			m_cases;
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureRenderer					m_renderer;
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int								m_caseNdx;
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3813c827367444ee418f129b2c238299f49d3264554Jarkko 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, deUint32 format, deUint32 dataType, int width, int height)
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase					(testCtx, name, desc)
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderCtx				(renderCtx)
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderCtxInfo			(ctxInfo)
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_minFilter				(minFilter)
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_magFilter				(magFilter)
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapS					(wrapS)
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapT					(wrapT)
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_format					(format)
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_dataType				(dataType)
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width					(width)
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height					(height)
393469002caa1ccd58f59f53a1bf3dbac4cf6a5d817Jarkko Pöyry	, m_renderer				(renderCtx, testCtx.getLog(), glu::GLSL_VERSION_100_ES, glu::PRECISION_MEDIUMP)
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_caseNdx					(0)
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3983c827367444ee418f129b2c238299f49d3264554Jarkko 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, const std::vector<std::string>& filenames)
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase					(testCtx, name, desc)
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderCtx				(renderCtx)
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderCtxInfo			(ctxInfo)
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_minFilter				(minFilter)
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_magFilter				(magFilter)
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapS					(wrapS)
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapT					(wrapT)
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_format					(GL_NONE)
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_dataType				(GL_NONE)
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width					(0)
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height					(0)
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_filenames				(filenames)
411469002caa1ccd58f59f53a1bf3dbac4cf6a5d817Jarkko Pöyry	, m_renderer				(renderCtx, testCtx.getLog(), glu::GLSL_VERSION_100_ES, glu::PRECISION_MEDIUMP)
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_caseNdx					(0)
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4163c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeFilteringCase::~TextureCubeFilteringCase (void)
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deinit();
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCubeFilteringCase::init (void)
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	try
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!m_filenames.empty())
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_textures.reserve(1);
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_textures.push_back(glu::TextureCube::create(m_renderCtx, m_renderCtxInfo, m_testCtx.getArchive(), (int)m_filenames.size() / 6, m_filenames));
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(m_width == m_height);
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_textures.reserve(2);
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int ndx = 0; ndx < 2; ndx++)
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_textures.push_back(new glu::TextureCube(m_renderCtx, m_format, m_dataType, m_width));
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool				mipmaps		= deIsPowerOfTwo32(m_width) && deIsPowerOfTwo32(m_height);
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				numLevels	= mipmaps ? deLog2Floor32(de::max(m_width, m_height))+1 : 1;
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::TextureFormatInfo	fmtInfo		= tcu::getTextureFormatInfo(m_textures[0]->getRefTexture().getFormat());
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4				cBias		= fmtInfo.valueMin;
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4				cScale		= fmtInfo.valueMax-fmtInfo.valueMin;
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Fill first with gradient texture.
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			static const tcu::Vec4 gradients[tcu::CUBEFACE_LAST][2] =
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{ tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // negative x
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{ tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // positive x
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{ tcu::Vec4(0.0f, 0.5f, 0.0f, 1.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // negative y
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{ tcu::Vec4(0.0f, 0.0f, 0.5f, 1.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // positive y
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{ tcu::Vec4(0.0f, 0.0f, 0.0f, 0.5f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f) }, // negative z
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{ tcu::Vec4(0.5f, 0.5f, 0.5f, 1.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }  // positive z
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			};
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_textures[0]->getRefTexture().allocLevel((tcu::CubeFace)face, levelNdx);
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					tcu::fillWithComponentGradients(m_textures[0]->getRefTexture().getLevelFace(levelNdx, (tcu::CubeFace)face), gradients[face][0]*cScale + cBias, gradients[face][1]*cScale + cBias);
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Fill second with grid texture.
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					deUint32	step	= 0x00ffffff / (numLevels*tcu::CUBEFACE_LAST);
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					deUint32	rgb		= step*levelNdx*face;
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					deUint32	colorA	= 0xff000000 | rgb;
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					deUint32	colorB	= 0xff000000 | ~rgb;
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_textures[1]->getRefTexture().allocLevel((tcu::CubeFace)face, levelNdx);
473c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket					tcu::fillWithGrid(m_textures[1]->getRefTexture().getLevelFace(levelNdx, (tcu::CubeFace)face), 4, tcu::RGBA(colorA).toVec()*cScale + cBias, tcu::RGBA(colorB).toVec()*cScale + cBias);
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Upload.
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (std::vector<glu::TextureCube*>::iterator i = m_textures.begin(); i != m_textures.end(); i++)
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				(*i)->upload();
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Compute cases
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const glu::TextureCube*	tex0	= m_textures[0];
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const glu::TextureCube* tex1	= m_textures.size() > 1 ? m_textures[1] : tex0;
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// \note Coordinates are chosen so that they only sample face interior. ES3 has changed edge sampling behavior
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			//		 and hw is not expected to implement both modes.
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_cases.push_back(FilterCase(tex0, tcu::Vec2(-0.8f, -0.8f), tcu::Vec2(0.8f, 0.8f)));	// minification
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_cases.push_back(FilterCase(tex0, tcu::Vec2(0.5f, 0.65f), tcu::Vec2(0.8f, 0.8f)));		// magnification
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_cases.push_back(FilterCase(tex1, tcu::Vec2(-0.8f, -0.8f), tcu::Vec2(0.8f, 0.8f)));	// minification
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_cases.push_back(FilterCase(tex1, tcu::Vec2(0.2f, 0.2f), tcu::Vec2(0.6f, 0.5f)));		// magnification
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_caseNdx = 0;
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	catch (...)
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Clean up to save memory.
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TextureCubeFilteringCase::deinit();
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw;
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCubeFilteringCase::deinit (void)
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (std::vector<glu::TextureCube*>::iterator i = m_textures.begin(); i != m_textures.end(); i++)
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete *i;
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_textures.clear();
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderer.clear();
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_cases.clear();
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* getFaceDesc (const tcu::CubeFace face)
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (face)
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::CUBEFACE_NEGATIVE_X:	return "-X";
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::CUBEFACE_POSITIVE_X:	return "+X";
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::CUBEFACE_NEGATIVE_Y:	return "-Y";
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::CUBEFACE_POSITIVE_Y:	return "+Y";
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::CUBEFACE_NEGATIVE_Z:	return "-Z";
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::CUBEFACE_POSITIVE_Z:	return "+Z";
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return DE_NULL;
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5323c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeFilteringCase::IterateResult TextureCubeFilteringCase::iterate (void)
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&			gl				= m_renderCtx.getFunctions();
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						viewportSize	= 28;
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const RandomViewport			viewport		(m_renderCtx.getRenderTarget(), viewportSize, viewportSize, deStringHash(getName()) ^ deInt32Hash(m_caseNdx));
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::ScopedLogSection		iterSection		(m_testCtx.getLog(), string("Test") + de::toString(m_caseNdx), string("Test ") + de::toString(m_caseNdx));
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const FilterCase&				curCase			= m_cases[m_caseNdx];
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::TextureFormat&		texFmt			= curCase.texture->getRefTexture().getFormat();
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::TextureFormatInfo	fmtInfo			= tcu::getTextureFormatInfo(texFmt);
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ReferenceParams					sampleParams	(TEXTURETYPE_CUBE);
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (viewport.width < viewportSize || viewport.height < viewportSize)
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::NotSupportedError("Too small render target", DE_NULL, __FILE__, __LINE__);
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Setup texture
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindTexture	(GL_TEXTURE_CUBE_MAP, curCase.texture->getGLTexture());
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,	m_minFilter);
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER,	m_magFilter);
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,		m_wrapS);
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,		m_wrapT);
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Other state
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Params for reference computation.
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleParams.sampler					= glu::mapGLSampler(m_wrapS, m_wrapT, m_minFilter, m_magFilter);
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleParams.sampler.seamlessCubeMap	= true;
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleParams.samplerType				= getSamplerType(texFmt);
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleParams.colorBias					= fmtInfo.lookupBias;
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleParams.colorScale					= fmtInfo.lookupScale;
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleParams.lodMode					= LODMODE_EXACT;
5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << TestLog::Message << "Coordinates: " << curCase.bottomLeft << " -> " << curCase.topRight << TestLog::EndMessage;
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::CubeFace		face		= tcu::CubeFace(faceNdx);
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Surface			result		(viewport.width, viewport.height);
5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<float>			texCoord;
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		computeQuadTexCoordCube(texCoord, face, curCase.bottomLeft, curCase.topRight);
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << TestLog::Message << "Face " << getFaceDesc(face) << TestLog::EndMessage;
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// \todo Log texture coordinates.
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_renderer.renderQuad(0, &texCoord[0], sampleParams);
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "Draw");
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::readPixels(m_renderCtx, viewport.x, viewport.y, result.getAccess());
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "Read pixels");
5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool				isNearestOnly	= m_minFilter == GL_NEAREST && m_magFilter == GL_NEAREST;
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const tcu::PixelFormat	pixelFormat		= m_renderCtx.getRenderTarget().getPixelFormat();
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const tcu::IVec4		colorBits		= max(getBitsVec(pixelFormat) - (isNearestOnly ? 1 : 2), tcu::IVec4(0)); // 1 inaccurate bit if nearest only, 2 otherwise
588433645782506cbdf8fa8b113ea0b5aa8ae761f0cPyry Haulos			tcu::LodPrecision		lodPrecision;
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::LookupPrecision	lookupPrecision;
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			lodPrecision.derivateBits		= 5;
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			lodPrecision.lodBits			= 3;
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			lookupPrecision.colorThreshold	= tcu::computeFixedPointThreshold(colorBits) / sampleParams.colorScale;
59477580092ddcda5530da88a3304fd2c467c0d5e70Pyry Haulos			lookupPrecision.coordBits		= tcu::IVec3(9,9,9); // mediump interpolation
595f1c8ff1f204f50ae1c785ef361fb88cc7dc611efPyry Haulos			lookupPrecision.uvwBits			= tcu::IVec3(3,3,0);
5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			lookupPrecision.colorMask		= getCompareMask(pixelFormat);
5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool isOk = verifyTextureResult(m_testCtx, result.getAccess(), curCase.texture->getRefTexture(),
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												  &texCoord[0], sampleParams, lookupPrecision, lodPrecision, pixelFormat);
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!isOk)
6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_caseNdx += 1;
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m_caseNdx < (int)m_cases.size() ? CONTINUE : STOP;
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6103c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureFilteringTests::TextureFilteringTests (Context& context)
6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCaseGroup(context, "filtering", "Texture Filtering Tests")
6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6153c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureFilteringTests::~TextureFilteringTests (void)
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureFilteringTests::init (void)
6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestCaseGroup* group2D		= new tcu::TestCaseGroup(m_testCtx, "2d",	"2D Texture Filtering");
6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestCaseGroup*	groupCube	= new tcu::TestCaseGroup(m_testCtx, "cube",	"Cube Map Filtering");
6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(group2D);
6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(groupCube);
6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		name;
6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32		mode;
6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} wrapModes[] =
6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "clamp",		GL_CLAMP_TO_EDGE },
6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "repeat",		GL_REPEAT },
6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "mirror",		GL_MIRRORED_REPEAT }
6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		name;
6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32		mode;
6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} minFilterModes[] =
6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "nearest",				GL_NEAREST					},
6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "linear",					GL_LINEAR					},
6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "nearest_mipmap_nearest",	GL_NEAREST_MIPMAP_NEAREST	},
6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "linear_mipmap_nearest",	GL_LINEAR_MIPMAP_NEAREST	},
6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "nearest_mipmap_linear",	GL_NEAREST_MIPMAP_LINEAR	},
6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "linear_mipmap_linear",	GL_LINEAR_MIPMAP_LINEAR		}
6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		name;
6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32		mode;
6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} magFilterModes[] =
6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "nearest",	GL_NEAREST },
6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "linear",		GL_LINEAR }
6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		name;
6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				width;
6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				height;
6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} sizes2D[] =
6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "pot",		32, 64 },
6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "npot",		31, 55 }
6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		name;
6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				width;
6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				height;
6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} sizesCube[] =
6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "pot",		64, 64 },
6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "npot",		63, 63 }
6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		name;
6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32		format;
6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32		dataType;
6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} formats[] =
6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "rgba8888",	GL_RGBA,			GL_UNSIGNED_BYTE			},
6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "rgb888",		GL_RGB,				GL_UNSIGNED_BYTE			},
6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "rgba4444",	GL_RGBA,			GL_UNSIGNED_SHORT_4_4_4_4	},
6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "l8",			GL_LUMINANCE,		GL_UNSIGNED_BYTE			}
6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define FOR_EACH(ITERATOR, ARRAY, BODY)	\
697dc795cd4f3d064cbbe2bf9899bf2088d206b7434Chih-Hung Hsieh	for (int (ITERATOR) = 0; (ITERATOR) < DE_LENGTH_OF_ARRAY(ARRAY); (ITERATOR)++)	\
6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		BODY
6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// 2D cases.
7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FOR_EACH(minFilter,		minFilterModes,
7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FOR_EACH(magFilter,		magFilterModes,
7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FOR_EACH(wrapMode,		wrapModes,
7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FOR_EACH(format,		formats,
7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FOR_EACH(size,			sizes2D,
7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bool isMipmap		= minFilterModes[minFilter].mode != GL_NEAREST && minFilterModes[minFilter].mode != GL_LINEAR;
7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bool isClamp		= wrapModes[wrapMode].mode == GL_CLAMP_TO_EDGE;
7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bool isRepeat		= wrapModes[wrapMode].mode == GL_REPEAT;
7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bool isMagNearest	= magFilterModes[magFilter].mode == GL_NEAREST;
7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bool isPotSize		= deIsPowerOfTwo32(sizes2D[size].width) && deIsPowerOfTwo32(sizes2D[size].height);
7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if ((isMipmap || !isClamp) && !isPotSize)
7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				continue; // Not supported.
7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if ((format != 0) && !(!isMipmap || (isRepeat && isMagNearest)))
7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				continue; // Skip.
7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			string name = string("") + minFilterModes[minFilter].name + "_" + magFilterModes[magFilter].name + "_" + wrapModes[wrapMode].name + "_" + formats[format].name;
7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!isMipmap)
7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				name += string("_") + sizes2D[size].name;
7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			group2D->addChild(new Texture2DFilteringCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														 name.c_str(), "",
7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														 minFilterModes[minFilter].mode,
7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														 magFilterModes[magFilter].mode,
7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														 wrapModes[wrapMode].mode,
7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														 wrapModes[wrapMode].mode,
7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														 formats[format].format, formats[format].dataType,
7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														 sizes2D[size].width, sizes2D[size].height));
7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		})))));
7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// 2D ETC1 texture cases.
7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		std::vector<std::string> filenames;
7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i <= 7; i++)
7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			filenames.push_back(string("data/etc1/photo_helsinki_mip_") + de::toString(i) + ".pkm");
7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FOR_EACH(minFilter,		minFilterModes,
7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FOR_EACH(magFilter,		magFilterModes,
7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FOR_EACH(wrapMode,		wrapModes,
7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				string name = string("") + minFilterModes[minFilter].name + "_" + magFilterModes[magFilter].name + "_" + wrapModes[wrapMode].name + "_etc1";
7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				group2D->addChild(new Texture2DFilteringCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 name.c_str(), "",
7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 minFilterModes[minFilter].mode,
7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 magFilterModes[magFilter].mode,
7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 wrapModes[wrapMode].mode,
7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 wrapModes[wrapMode].mode,
7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 filenames));
7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			})));
7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Cubemap cases.
7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FOR_EACH(minFilter,		minFilterModes,
7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FOR_EACH(magFilter,		magFilterModes,
7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FOR_EACH(wrapMode,		wrapModes,
7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FOR_EACH(format,		formats,
7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FOR_EACH(size,			sizesCube,
7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bool isMipmap		= minFilterModes[minFilter].mode != GL_NEAREST && minFilterModes[minFilter].mode != GL_LINEAR;
7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bool isClamp		= wrapModes[wrapMode].mode == GL_CLAMP_TO_EDGE;
7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bool isRepeat		= wrapModes[wrapMode].mode == GL_REPEAT;
7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bool isMagNearest	= magFilterModes[magFilter].mode == GL_NEAREST;
7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bool isPotSize		= deIsPowerOfTwo32(sizesCube[size].width) && deIsPowerOfTwo32(sizesCube[size].height);
7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if ((isMipmap || !isClamp) && !isPotSize)
7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				continue; // Not supported.
7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (format != 0 && !(!isMipmap || (isRepeat && isMagNearest)))
7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				continue; // Skip.
7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			string name = string("") + minFilterModes[minFilter].name + "_" + magFilterModes[magFilter].name + "_" + wrapModes[wrapMode].name + "_" + formats[format].name;
7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!isMipmap)
7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				name += string("_") + sizesCube[size].name;
7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			groupCube->addChild(new TextureCubeFilteringCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 name.c_str(), "",
7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 minFilterModes[minFilter].mode,
7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 magFilterModes[magFilter].mode,
7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 wrapModes[wrapMode].mode,
7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 wrapModes[wrapMode].mode,
7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 formats[format].format, formats[format].dataType,
7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 sizesCube[size].width, sizesCube[size].height));
7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		})))));
7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Cubemap ETC1 cases
7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const char* faceExt[] = { "neg_x", "pos_x", "neg_y", "pos_y", "neg_z", "pos_z" };
7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int		numLevels	= 7;
7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<string>	filenames;
7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int level = 0; level < numLevels; level++)
7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				filenames.push_back(string("data/etc1/skybox_") + faceExt[face] + "_mip_" + de::toString(level) + ".pkm");
7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FOR_EACH(minFilter,		minFilterModes,
8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FOR_EACH(magFilter,		magFilterModes,
8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				string name = string("") + minFilterModes[minFilter].name + "_" + magFilterModes[magFilter].name + "_clamp_etc1";
8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				groupCube->addChild(new TextureCubeFilteringCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																 name.c_str(), "",
8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																 minFilterModes[minFilter].mode,
8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																 magFilterModes[magFilter].mode,
8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																 GL_CLAMP_TO_EDGE,
8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																 GL_CLAMP_TO_EDGE,
8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																 filenames));
8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}));
8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Functional
8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles2
8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp
819