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 accuracy tests.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es2aTextureFilteringTests.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 "deStringUtil.hpp"
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwFunctions.hpp"
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwEnums.hpp"
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string;
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gles2
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace Accuracy
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::TestLog;
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector;
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string;
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Sampler;
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace glu;
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace gls::TextureTestUtil;
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Texture2DFilteringCase : public tcu::TestCase
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
563c827367444ee418f129b2c238299f49d3264554Jarkko 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);
573c827367444ee418f129b2c238299f49d3264554Jarkko 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);
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								~Texture2DFilteringCase		(void);
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						init						(void);
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						deinit						(void);
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult				iterate						(void);
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								Texture2DFilteringCase		(const Texture2DFilteringCase& other);
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Texture2DFilteringCase&		operator=					(const Texture2DFilteringCase& other);
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::RenderContext&			m_renderCtx;
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::ContextInfo&		m_renderCtxInfo;
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32					m_minFilter;
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32					m_magFilter;
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32					m_wrapS;
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32					m_wrapT;
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32					m_format;
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32					m_dataType;
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int							m_width;
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int							m_height;
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<std::string>	m_filenames;
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<glu::Texture2D*>	m_textures;
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureRenderer					m_renderer;
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
883c827367444ee418f129b2c238299f49d3264554Jarkko 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)
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase			(testCtx, tcu::NODETYPE_ACCURACY, name, desc)
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderCtx		(renderCtx)
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderCtxInfo	(ctxInfo)
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_minFilter		(minFilter)
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_magFilter		(magFilter)
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapS			(wrapS)
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapT			(wrapT)
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_format			(format)
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_dataType		(dataType)
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width			(width)
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height			(height)
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderer		(renderCtx, testCtx, glu::GLSL_VERSION_100_ES, glu::PRECISION_MEDIUMP)
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1043c827367444ee418f129b2c238299f49d3264554Jarkko 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)
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase			(testCtx, tcu::NODETYPE_ACCURACY, name, desc)
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderCtx		(renderCtx)
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderCtxInfo	(ctxInfo)
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_minFilter		(minFilter)
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_magFilter		(magFilter)
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapS			(wrapS)
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapT			(wrapT)
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_format			(GL_NONE)
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_dataType		(GL_NONE)
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width			(0)
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height			(0)
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_filenames		(filenames)
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderer		(renderCtx, testCtx, glu::GLSL_VERSION_100_ES, glu::PRECISION_MEDIUMP)
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1213c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DFilteringCase::~Texture2DFilteringCase (void)
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deinit();
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture2DFilteringCase::init (void)
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	try
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!m_filenames.empty())
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_textures.reserve(1);
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_textures.push_back(glu::Texture2D::create(m_renderCtx, m_renderCtxInfo, m_testCtx.getArchive(), (int)m_filenames.size(), m_filenames));
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Create 2 textures.
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_textures.reserve(2);
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int ndx = 0; ndx < 2; ndx++)
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_textures.push_back(new glu::Texture2D(m_renderCtx, m_format, m_dataType, m_width, m_height));
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool				mipmaps		= deIsPowerOfTwo32(m_width) && deIsPowerOfTwo32(m_height);
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				numLevels	= mipmaps ? deLog2Floor32(de::max(m_width, m_height))+1 : 1;
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::TextureFormatInfo	fmtInfo		= tcu::getTextureFormatInfo(m_textures[0]->getRefTexture().getFormat());
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4				cBias		= fmtInfo.valueMin;
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4				cScale		= fmtInfo.valueMax-fmtInfo.valueMin;
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Fill first gradient texture.
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::Vec4 gMin = tcu::Vec4(-0.5f, -0.5f, -0.5f, 2.0f)*cScale + cBias;
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::Vec4 gMax = tcu::Vec4( 1.0f,  1.0f,  1.0f, 0.0f)*cScale + cBias;
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_textures[0]->getRefTexture().allocLevel(levelNdx);
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::fillWithComponentGradients(m_textures[0]->getRefTexture().getLevel(levelNdx), gMin, gMax);
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Fill second with grid texture.
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32	step	= 0x00ffffff / numLevels;
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32	rgb		= step*levelNdx;
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32	colorA	= 0xff000000 | rgb;
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32	colorB	= 0xff000000 | ~rgb;
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_textures[1]->getRefTexture().allocLevel(levelNdx);
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::fillWithGrid(m_textures[1]->getRefTexture().getLevel(levelNdx), 4, toVec4(tcu::RGBA(colorA))*cScale + cBias, toVec4(tcu::RGBA(colorB))*cScale + cBias);
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Upload.
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (std::vector<glu::Texture2D*>::iterator i = m_textures.begin(); i != m_textures.end(); i++)
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				(*i)->upload();
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	catch (...)
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Clean up to save memory.
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Texture2DFilteringCase::deinit();
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw;
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture2DFilteringCase::deinit (void)
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (std::vector<glu::Texture2D*>::iterator i = m_textures.begin(); i != m_textures.end(); i++)
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete *i;
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_textures.clear();
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderer.clear();
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1923c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DFilteringCase::IterateResult Texture2DFilteringCase::iterate (void)
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&		gl					= m_renderCtx.getFunctions();
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&					log					= m_testCtx.getLog();
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					defViewportWidth	= 256;
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					defViewportHeight	= 256;
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RandomViewport				viewport			(m_renderCtx.getRenderTarget(), defViewportWidth, defViewportHeight, deStringHash(getName()));
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface				renderedFrame		(viewport.width, viewport.height);
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface				referenceFrame		(viewport.width, viewport.height);
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::TextureFormat&	texFmt				= m_textures[0]->getRefTexture().getFormat();
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TextureFormatInfo		fmtInfo				= tcu::getTextureFormatInfo(texFmt);
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ReferenceParams				refParams			(TEXTURETYPE_2D);
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<float>				texCoord;
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Accuracy measurements are off unless viewport size is 256x256
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (viewport.width < defViewportWidth || viewport.height < defViewportHeight)
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::NotSupportedError("Too small viewport", "", __FILE__, __LINE__);
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Viewport is divided into 4 sections.
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				leftWidth			= viewport.width / 2;
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				rightWidth			= viewport.width - leftWidth;
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				bottomHeight		= viewport.height / 2;
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				topHeight			= viewport.height - bottomHeight;
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				curTexNdx			= 0;
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Use unit 0.
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.activeTexture(GL_TEXTURE0);
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Bind gradient texture and setup sampler parameters.
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindTexture(GL_TEXTURE_2D, m_textures[curTexNdx]->getGLTexture());
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		m_wrapS);
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		m_wrapT);
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	m_minFilter);
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	m_magFilter);
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Setup params for reference.
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	refParams.sampler		= mapGLSampler(m_wrapS, m_wrapT, m_minFilter, m_magFilter);
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	refParams.samplerType	= getSamplerType(texFmt);
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	refParams.lodMode		= LODMODE_EXACT;
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	refParams.colorBias		= fmtInfo.lookupBias;
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	refParams.colorScale	= fmtInfo.lookupScale;
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Bottom left: Minification
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.viewport(viewport.x, viewport.y, leftWidth, bottomHeight);
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		computeQuadTexCoord2D(texCoord, tcu::Vec2(-4.0f, -4.5f), tcu::Vec2(4.0f, 2.5f));
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_renderer.renderQuad(0, &texCoord[0], refParams);
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		sampleTexture(SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat(), 0, 0, leftWidth, bottomHeight),
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  m_textures[curTexNdx]->getRefTexture(), &texCoord[0], refParams);
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Bottom right: Magnification
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.viewport(viewport.x+leftWidth, viewport.y, rightWidth, bottomHeight);
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		computeQuadTexCoord2D(texCoord, tcu::Vec2(-0.5f, 0.75f), tcu::Vec2(0.25f, 1.25f));
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_renderer.renderQuad(0, &texCoord[0], refParams);
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		sampleTexture(SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat(), leftWidth, 0, rightWidth, bottomHeight),
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  m_textures[curTexNdx]->getRefTexture(), &texCoord[0], refParams);
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_textures.size() >= 2)
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		curTexNdx += 1;
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Setup second texture.
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindTexture(GL_TEXTURE_2D, m_textures[curTexNdx]->getGLTexture());
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		m_wrapS);
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		m_wrapT);
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	m_minFilter);
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	m_magFilter);
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Top left: Minification
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note Minification is chosen so that 0.0 < lod <= 0.5. This way special minification threshold rule will be triggered.
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.viewport(viewport.x, viewport.y+bottomHeight, leftWidth, topHeight);
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float	sMin		= -0.5f;
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float	tMin		= -0.2f;
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float	sRange		= ((float)leftWidth * 1.2f) / (float)m_textures[curTexNdx]->getRefTexture().getWidth();
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float	tRange		= ((float)topHeight * 1.1f) / (float)m_textures[curTexNdx]->getRefTexture().getHeight();
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		computeQuadTexCoord2D(texCoord, tcu::Vec2(sMin, tMin), tcu::Vec2(sMin+sRange, tMin+tRange));
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_renderer.renderQuad(0, &texCoord[0], refParams);
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		sampleTexture(SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat(), 0, bottomHeight, leftWidth, topHeight),
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  m_textures[curTexNdx]->getRefTexture(), &texCoord[0], refParams);
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Top right: Magnification
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.viewport(viewport.x+leftWidth, viewport.y+bottomHeight, rightWidth, topHeight);
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		computeQuadTexCoord2D(texCoord, tcu::Vec2(-0.5f, 0.75f), tcu::Vec2(0.25f, 1.25f));
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_renderer.renderQuad(0, &texCoord[0], refParams);
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		sampleTexture(SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat(), leftWidth, bottomHeight, rightWidth, topHeight),
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  m_textures[curTexNdx]->getRefTexture(), &texCoord[0], refParams);
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Read result.
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compare and log.
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(getNodeType() == tcu::NODETYPE_ACCURACY);
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	bestScoreDiff	= 16;
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	worstScoreDiff	= 3200;
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int score = measureAccuracy(log, referenceFrame, renderedFrame, bestScoreDiff, worstScoreDiff);
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, de::toString(score).c_str());
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass TextureCubeFilteringCase : public tcu::TestCase
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
3173c827367444ee418f129b2c238299f49d3264554Jarkko 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);
3183c827367444ee418f129b2c238299f49d3264554Jarkko 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);
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								~TextureCubeFilteringCase	(void);
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						init						(void);
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						deinit						(void);
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult				iterate						(void);
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								TextureCubeFilteringCase	(const TextureCubeFilteringCase& other);
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureCubeFilteringCase&	operator=					(const TextureCubeFilteringCase& other);
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::RenderContext&			m_renderCtx;
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::ContextInfo&		m_renderCtxInfo;
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32					m_minFilter;
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32					m_magFilter;
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32					m_wrapS;
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32					m_wrapT;
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32					m_format;
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32					m_dataType;
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int							m_width;
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int							m_height;
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<std::string>	m_filenames;
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<glu::TextureCube*>	m_textures;
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureRenderer					m_renderer;
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3493c827367444ee418f129b2c238299f49d3264554Jarkko 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)
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase					(testCtx, tcu::NODETYPE_ACCURACY, name, desc)
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderCtx				(renderCtx)
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderCtxInfo			(ctxInfo)
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_minFilter				(minFilter)
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_magFilter				(magFilter)
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapS					(wrapS)
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapT					(wrapT)
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_format					(format)
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_dataType				(dataType)
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width					(width)
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height					(height)
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderer				(renderCtx, testCtx, glu::GLSL_VERSION_100_ES, glu::PRECISION_MEDIUMP)
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3653c827367444ee418f129b2c238299f49d3264554Jarkko 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)
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase					(testCtx, tcu::NODETYPE_ACCURACY, name, desc)
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderCtx				(renderCtx)
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderCtxInfo			(ctxInfo)
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_minFilter				(minFilter)
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_magFilter				(magFilter)
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapS					(wrapS)
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapT					(wrapT)
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_format					(GL_NONE)
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_dataType				(GL_NONE)
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width					(0)
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height					(0)
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_filenames				(filenames)
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderer				(renderCtx, testCtx, glu::GLSL_VERSION_100_ES, glu::PRECISION_MEDIUMP)
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3823c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeFilteringCase::~TextureCubeFilteringCase (void)
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deinit();
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCubeFilteringCase::init (void)
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	try
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!m_filenames.empty())
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_textures.reserve(1);
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_textures.push_back(glu::TextureCube::create(m_renderCtx, m_renderCtxInfo, m_testCtx.getArchive(), (int)m_filenames.size() / 6, m_filenames));
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_textures.reserve(2);
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(m_width == m_height);
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int ndx = 0; ndx < 2; ndx++)
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_textures.push_back(new glu::TextureCube(m_renderCtx, m_format, m_dataType, m_width));
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool				mipmaps		= deIsPowerOfTwo32(m_width) && deIsPowerOfTwo32(m_height);
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				numLevels	= mipmaps ? deLog2Floor32(de::max(m_width, m_height))+1 : 1;
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::TextureFormatInfo	fmtInfo		= tcu::getTextureFormatInfo(m_textures[0]->getRefTexture().getFormat());
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4				cBias		= fmtInfo.valueMin;
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4				cScale		= fmtInfo.valueMax-fmtInfo.valueMin;
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Fill first with gradient texture.
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			static const tcu::Vec4 gradients[tcu::CUBEFACE_LAST][2] =
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{ tcu::Vec4(-1.0f, -1.0f, -1.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // negative x
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{ tcu::Vec4( 0.0f, -1.0f, -1.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // positive x
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{ tcu::Vec4(-1.0f,  0.0f, -1.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // negative y
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{ tcu::Vec4(-1.0f, -1.0f,  0.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // positive y
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{ tcu::Vec4(-1.0f, -1.0f, -1.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f) }, // negative z
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{ tcu::Vec4( 0.0f,  0.0f,  0.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }  // positive z
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			};
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_textures[0]->getRefTexture().allocLevel((tcu::CubeFace)face, levelNdx);
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					tcu::fillWithComponentGradients(m_textures[0]->getRefTexture().getLevelFace(levelNdx, (tcu::CubeFace)face), gradients[face][0]*cScale + cBias, gradients[face][1]*cScale + cBias);
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Fill second with grid texture.
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					deUint32	step	= 0x00ffffff / (numLevels*tcu::CUBEFACE_LAST);
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					deUint32	rgb		= step*levelNdx*face;
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					deUint32	colorA	= 0xff000000 | rgb;
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					deUint32	colorB	= 0xff000000 | ~rgb;
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_textures[1]->getRefTexture().allocLevel((tcu::CubeFace)face, levelNdx);
4393c827367444ee418f129b2c238299f49d3264554Jarkko 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);
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Upload.
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (std::vector<glu::TextureCube*>::iterator i = m_textures.begin(); i != m_textures.end(); i++)
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				(*i)->upload();
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	catch (const std::exception&)
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Clean up to save memory.
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TextureCubeFilteringCase::deinit();
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw;
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCubeFilteringCase::deinit (void)
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (std::vector<glu::TextureCube*>::iterator i = m_textures.begin(); i != m_textures.end(); i++)
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete *i;
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_textures.clear();
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderer.clear();
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void renderFaces (
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&		gl,
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const SurfaceAccess&		dstRef,
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::TextureCube&		refTexture,
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ReferenceParams&		params,
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureRenderer&			renderer,
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int							x,
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int							y,
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int							width,
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int							height,
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec2&			bottomLeft,
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec2&			topRight,
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec2&			texCoordTopRightFactor)
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(width == dstRef.getWidth() && height == dstRef.getHeight());
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<float> texCoord;
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_STATIC_ASSERT(tcu::CUBEFACE_LAST == 6);
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool	isRightmost		= (face == 2) || (face == 5);
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool	isTop			= face >= 3;
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int		curX			= (face % 3) * (width  / 3);
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int		curY			= (face / 3) * (height / 2);
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int		curW			= isRightmost	? (width-curX)	: (width	/ 3);
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int		curH			= isTop			? (height-curY)	: (height	/ 2);
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		computeQuadTexCoordCube(texCoord, (tcu::CubeFace)face, bottomLeft, topRight);
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Move the top and right edges of the texture coord quad. This is useful when we want a cube edge visible.
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int texCoordSRow = face == tcu::CUBEFACE_NEGATIVE_X || face == tcu::CUBEFACE_POSITIVE_X ? 2 : 0;
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int texCoordTRow = face == tcu::CUBEFACE_NEGATIVE_Y || face == tcu::CUBEFACE_POSITIVE_Y ? 2 : 1;
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texCoord[6 + texCoordSRow] *= texCoordTopRightFactor.x();
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texCoord[9 + texCoordSRow] *= texCoordTopRightFactor.x();
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texCoord[3 + texCoordTRow] *= texCoordTopRightFactor.y();
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texCoord[9 + texCoordTRow] *= texCoordTopRightFactor.y();
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.viewport(x+curX, y+curY, curW, curH);
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		renderer.renderQuad(0, &texCoord[0], params);
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		sampleTexture(SurfaceAccess(dstRef, curX, curY, curW, curH), refTexture, &texCoord[0], params);
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "Post render");
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5153c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeFilteringCase::IterateResult TextureCubeFilteringCase::iterate (void)
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&		gl					= m_renderCtx.getFunctions();
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&					log					= m_testCtx.getLog();
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					cellSize			= 28;
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					defViewportWidth	= cellSize*6;
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					defViewportHeight	= cellSize*4;
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RandomViewport				viewport			(m_renderCtx.getRenderTarget(), cellSize*6, cellSize*4, deStringHash(getName()));
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface				renderedFrame		(viewport.width, viewport.height);
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface				referenceFrame		(viewport.width, viewport.height);
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ReferenceParams				sampleParams		(TEXTURETYPE_CUBE);
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::TextureFormat&	texFmt				= m_textures[0]->getRefTexture().getFormat();
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TextureFormatInfo		fmtInfo				= tcu::getTextureFormatInfo(texFmt);
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Accuracy measurements are off unless viewport size is exactly as expected.
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (viewport.width < defViewportWidth || viewport.height < defViewportHeight)
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::NotSupportedError("Too small viewport", "", __FILE__, __LINE__);
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Viewport is divided into 4 sections.
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				leftWidth			= viewport.width / 2;
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				rightWidth			= viewport.width - leftWidth;
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				bottomHeight		= viewport.height / 2;
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				topHeight			= viewport.height - bottomHeight;
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				curTexNdx			= 0;
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Sampling parameters.
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleParams.sampler					= mapGLSampler(m_wrapS, m_wrapT, m_minFilter, m_magFilter);
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleParams.sampler.seamlessCubeMap	= false;
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleParams.samplerType				= getSamplerType(texFmt);
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleParams.colorBias					= fmtInfo.lookupBias;
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleParams.colorScale					= fmtInfo.lookupScale;
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleParams.lodMode					= LODMODE_EXACT;
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Use unit 0.
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.activeTexture(GL_TEXTURE0);
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Setup gradient texture.
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindTexture(GL_TEXTURE_CUBE_MAP, m_textures[curTexNdx]->getGLTexture());
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,		m_wrapS);
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,		m_wrapT);
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,	m_minFilter);
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER,	m_magFilter);
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Bottom left: Minification
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	renderFaces(gl,
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat(), 0, 0, leftWidth, bottomHeight),
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_textures[curTexNdx]->getRefTexture(), sampleParams,
5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_renderer,
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				viewport.x, viewport.y, leftWidth, bottomHeight,
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::Vec2(-0.81f, -0.81f),
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::Vec2( 0.8f,  0.8f),
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::Vec2(1.0f, 1.0f));
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Bottom right: Magnification
5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	renderFaces(gl,
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat(), leftWidth, 0, rightWidth, bottomHeight),
5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_textures[curTexNdx]->getRefTexture(), sampleParams,
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_renderer,
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				viewport.x+leftWidth, viewport.y, rightWidth, bottomHeight,
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::Vec2(0.5f, 0.65f), tcu::Vec2(0.8f, 0.8f),
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::Vec2(1.0f, 1.0f));
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_textures.size() >= 2)
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		curTexNdx += 1;
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Setup second texture.
5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindTexture(GL_TEXTURE_CUBE_MAP, m_textures[curTexNdx]->getGLTexture());
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,		m_wrapS);
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,		m_wrapT);
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,	m_minFilter);
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER,	m_magFilter);
5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Top left: Minification
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	renderFaces(gl,
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat(), 0, bottomHeight, leftWidth, topHeight),
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_textures[curTexNdx]->getRefTexture(), sampleParams,
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_renderer,
5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				viewport.x, viewport.y+bottomHeight, leftWidth, topHeight,
5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::Vec2(-0.81f, -0.81f),
5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::Vec2( 0.8f,  0.8f),
5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::Vec2(1.0f, 1.0f));
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Top right: Magnification
6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	renderFaces(gl,
6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat(), leftWidth, bottomHeight, rightWidth, topHeight),
6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_textures[curTexNdx]->getRefTexture(), sampleParams,
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_renderer,
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				viewport.x+leftWidth, viewport.y+bottomHeight, rightWidth, topHeight,
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::Vec2(0.5f, -0.65f), tcu::Vec2(0.8f, -0.8f),
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::Vec2(1.0f, 1.0f));
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Read result.
6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());
6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compare and log.
6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(getNodeType() == tcu::NODETYPE_ACCURACY);
6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	bestScoreDiff	= 16;
6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	worstScoreDiff	= 10000;
6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int score = measureAccuracy(log, referenceFrame, renderedFrame, bestScoreDiff, worstScoreDiff);
6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, de::toString(score).c_str());
6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6263c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureFilteringTests::TextureFilteringTests (Context& context)
6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCaseGroup(context, "filter", "Texture Filtering Accuracy Tests")
6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6313c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureFilteringTests::~TextureFilteringTests (void)
6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureFilteringTests::init (void)
6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestCaseGroup* group2D		= new tcu::TestCaseGroup(m_testCtx, "2d",	"2D Texture Filtering");
6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestCaseGroup*	groupCube	= new tcu::TestCaseGroup(m_testCtx, "cube",	"Cube Map Filtering");
6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(group2D);
6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(groupCube);
6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		name;
6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32		mode;
6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} wrapModes[] =
6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "clamp",		GL_CLAMP_TO_EDGE },
6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "repeat",		GL_REPEAT },
6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "mirror",		GL_MIRRORED_REPEAT }
6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		name;
6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32		mode;
6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} minFilterModes[] =
6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "nearest",				GL_NEAREST					},
6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "linear",					GL_LINEAR					},
6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "nearest_mipmap_nearest",	GL_NEAREST_MIPMAP_NEAREST	},
6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "linear_mipmap_nearest",	GL_LINEAR_MIPMAP_NEAREST	},
6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "nearest_mipmap_linear",	GL_NEAREST_MIPMAP_LINEAR	},
6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "linear_mipmap_linear",	GL_LINEAR_MIPMAP_LINEAR		}
6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		name;
6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32		mode;
6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} magFilterModes[] =
6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "nearest",	GL_NEAREST },
6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "linear",		GL_LINEAR }
6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		name;
6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				width;
6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				height;
6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} sizes2D[] =
6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "pot",		32, 64 },
6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "npot",		31, 55 }
6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		name;
6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				width;
6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				height;
6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} sizesCube[] =
6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "pot",		64, 64 },
6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "npot",		63, 63 }
6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		name;
7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32		format;
7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32		dataType;
7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} formats[] =
7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "rgba8888",	GL_RGBA,			GL_UNSIGNED_BYTE			},
7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "rgba4444",	GL_RGBA,			GL_UNSIGNED_SHORT_4_4_4_4	}
7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define FOR_EACH(ITERATOR, ARRAY, BODY)	\
7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ITERATOR = 0; ITERATOR < DE_LENGTH_OF_ARRAY(ARRAY); ITERATOR++)	\
7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		BODY
7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// 2D cases.
7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FOR_EACH(minFilter,		minFilterModes,
7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FOR_EACH(magFilter,		magFilterModes,
7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FOR_EACH(wrapMode,		wrapModes,
7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FOR_EACH(format,		formats,
7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FOR_EACH(size,			sizes2D,
7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bool isMipmap		= minFilterModes[minFilter].mode != GL_NEAREST && minFilterModes[minFilter].mode != GL_LINEAR;
7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bool isClamp		= wrapModes[wrapMode].mode == GL_CLAMP_TO_EDGE;
7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bool isRepeat		= wrapModes[wrapMode].mode == GL_REPEAT;
7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bool isMagNearest	= magFilterModes[magFilter].mode == GL_NEAREST;
7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bool isPotSize		= deIsPowerOfTwo32(sizes2D[size].width) && deIsPowerOfTwo32(sizes2D[size].height);
7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if ((isMipmap || !isClamp) && !isPotSize)
7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				continue; // Not supported.
7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if ((format != 0) && !(!isMipmap || (isRepeat && isMagNearest)))
7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				continue; // Skip.
7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			string name = string("") + minFilterModes[minFilter].name + "_" + magFilterModes[magFilter].name + "_" + wrapModes[wrapMode].name + "_" + formats[format].name;
7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!isMipmap)
7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				name += string("_") + sizes2D[size].name;
7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			group2D->addChild(new Texture2DFilteringCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														 name.c_str(), "",
7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														 minFilterModes[minFilter].mode,
7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														 magFilterModes[magFilter].mode,
7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														 wrapModes[wrapMode].mode,
7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														 wrapModes[wrapMode].mode,
7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														 formats[format].format, formats[format].dataType,
7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														 sizes2D[size].width, sizes2D[size].height));
7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		})))));
7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Cubemap cases.
7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FOR_EACH(minFilter,		minFilterModes,
7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FOR_EACH(magFilter,		magFilterModes,
7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FOR_EACH(wrapMode,		wrapModes,
7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FOR_EACH(format,		formats,
7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FOR_EACH(size,			sizesCube,
7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bool isMipmap		= minFilterModes[minFilter].mode != GL_NEAREST && minFilterModes[minFilter].mode != GL_LINEAR;
7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bool isClamp		= wrapModes[wrapMode].mode == GL_CLAMP_TO_EDGE;
7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bool isRepeat		= wrapModes[wrapMode].mode == GL_REPEAT;
7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bool isMagNearest	= magFilterModes[magFilter].mode == GL_NEAREST;
7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bool isPotSize		= deIsPowerOfTwo32(sizesCube[size].width) && deIsPowerOfTwo32(sizesCube[size].height);
7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if ((isMipmap || !isClamp) && !isPotSize)
7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				continue; // Not supported.
7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (format != 0 && !(!isMipmap || (isRepeat && isMagNearest)))
7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				continue; // Skip.
7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			string name = string("") + minFilterModes[minFilter].name + "_" + magFilterModes[magFilter].name + "_" + wrapModes[wrapMode].name + "_" + formats[format].name;
7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!isMipmap)
7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				name += string("_") + sizesCube[size].name;
7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			groupCube->addChild(new TextureCubeFilteringCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 name.c_str(), "",
7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 minFilterModes[minFilter].mode,
7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 magFilterModes[magFilter].mode,
7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 wrapModes[wrapMode].mode,
7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 wrapModes[wrapMode].mode,
7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 formats[format].format, formats[format].dataType,
7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 sizesCube[size].width, sizesCube[size].height));
7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		})))));
7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Accuracy
7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles2
7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp
786