13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program OpenGL ES 3.0 Module
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * -------------------------------------------------
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License.
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License.
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*!
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Mipmapping tests.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es3fTextureMipmapTests.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glsTextureTestUtil.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluTexture.hpp"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluTextureUtil.hpp"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluPixelTransfer.hpp"
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTextureUtil.hpp"
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuMatrix.hpp"
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuMatrixUtil.hpp"
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTexLookupVerifier.hpp"
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuVectorUtil.hpp"
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp"
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deRandom.hpp"
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deString.h"
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwFunctions.hpp"
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwEnums.hpp"
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector;
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string;
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace deqp::gls;
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gles3
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace Functional
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string;
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector;
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::TestLog;
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Vec2;
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Vec3;
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Vec4;
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::IVec4;
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace gls::TextureTestUtil;
60c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketusing namespace glu::TextureTestUtil;
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float getMinLodForCell (int cellNdx)
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const float s_values[] =
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		1.0f,
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		3.5f,
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		2.0f,
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		-2.0f,
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		0.0f,
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		3.0f,
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		10.0f,
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		4.8f,
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		5.8f,
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		5.7f,
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		-1.9f,
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		4.0f,
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		6.5f,
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		7.1f,
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		-1e10,
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		1000.f
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return s_values[cellNdx % DE_LENGTH_OF_ARRAY(s_values)];
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float getMaxLodForCell (int cellNdx)
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const float s_values[] =
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		0.0f,
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		0.2f,
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		0.7f,
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		0.4f,
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		1.3f,
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		0.0f,
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		0.5f,
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		1.2f,
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		-2.0f,
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		1.0f,
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		0.1f,
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		0.3f,
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		2.7f,
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		1.2f,
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		10.0f,
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		-1000.f,
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		1e10f
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return s_values[cellNdx % DE_LENGTH_OF_ARRAY(s_values)];
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum CoordType
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	COORDTYPE_BASIC,		//!< texCoord = translateScale(position).
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	COORDTYPE_BASIC_BIAS,	//!< Like basic, but with bias values.
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	COORDTYPE_AFFINE,		//!< texCoord = translateScaleRotateShear(position).
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	COORDTYPE_PROJECTED,	//!< Projected coordinates, w != 1
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	COORDTYPE_LAST
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture2DMipmapCase
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Texture2DMipmapCase : public tcu::TestCase
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								Texture2DMipmapCase			(tcu::TestContext&			testCtx,
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 glu::RenderContext&		renderCtx,
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 const glu::ContextInfo&	renderCtxInfo,
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 const char*				name,
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 const char*				desc,
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 CoordType					coordType,
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 deUint32					minFilter,
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 deUint32					wrapS,
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 deUint32					wrapT,
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 deUint32					format,
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 deUint32					dataType,
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 int						width,
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 int						height);
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								~Texture2DMipmapCase		(void);
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						init						(void);
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						deinit						(void);
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult				iterate						(void);
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								Texture2DMipmapCase			(const Texture2DMipmapCase& other);
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Texture2DMipmapCase&		operator=					(const Texture2DMipmapCase& other);
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::RenderContext&			m_renderCtx;
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::ContextInfo&		m_renderCtxInfo;
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CoordType					m_coordType;
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32					m_minFilter;
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32					m_wrapS;
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32					m_wrapT;
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32					m_format;
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32					m_dataType;
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int							m_width;
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int							m_height;
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::Texture2D*				m_texture;
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureRenderer				m_renderer;
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1663c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DMipmapCase::Texture2DMipmapCase (tcu::TestContext&			testCtx,
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										  glu::RenderContext&		renderCtx,
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										  const glu::ContextInfo&	renderCtxInfo,
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										  const char*				name,
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										  const char*				desc,
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										  CoordType					coordType,
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										  deUint32					minFilter,
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										  deUint32					wrapS,
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										  deUint32					wrapT,
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										  deUint32					format,
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										  deUint32					dataType,
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										  int						width,
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										  int						height)
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase			(testCtx, name, desc)
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderCtx		(renderCtx)
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderCtxInfo	(renderCtxInfo)
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_coordType		(coordType)
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_minFilter		(minFilter)
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapS			(wrapS)
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapT			(wrapT)
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_format			(format)
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_dataType		(dataType)
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width			(width)
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height			(height)
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_texture			(DE_NULL)
191469002caa1ccd58f59f53a1bf3dbac4cf6a5d817Jarkko Pöyry	, m_renderer		(renderCtx, testCtx.getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1953c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DMipmapCase::~Texture2DMipmapCase (void)
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deinit();
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture2DMipmapCase::init (void)
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_coordType == COORDTYPE_PROJECTED && m_renderCtx.getRenderTarget().getNumSamples() > 0)
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::NotSupportedError("Projected lookup validation not supported in multisample config");
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_texture = new glu::Texture2D(m_renderCtx, m_format, m_dataType, m_width, m_height);
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int numLevels = deLog2Floor32(de::max(m_width, m_height))+1;
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Fill texture with colored grid.
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32	step		= 0xff / (numLevels-1);
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32	inc			= deClamp32(step*levelNdx, 0x00, 0xff);
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32	dec			= 0xff - inc;
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32	rgb			= (inc << 16) | (dec << 8) | 0xff;
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32	color		= 0xff000000 | rgb;
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_texture->getRefTexture().allocLevel(levelNdx);
219c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket		tcu::clear(m_texture->getRefTexture().getLevel(levelNdx), tcu::RGBA(color).toVec());
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture2DMipmapCase::deinit (void)
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_texture;
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_texture = DE_NULL;
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderer.clear();
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void getBasicTexCoord2D (std::vector<float>& dst, int cellNdx)
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Vec2 bottomLeft;
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Vec2 topRight;
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} s_basicCoords[] =
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ Vec2(-0.1f,  0.1f), Vec2( 0.8f,  1.0f) },
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ Vec2(-0.3f, -0.6f), Vec2( 0.7f,  0.4f) },
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ Vec2(-0.3f,  0.6f), Vec2( 0.7f, -0.9f) },
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ Vec2(-0.8f,  0.6f), Vec2( 0.7f, -0.9f) },
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ Vec2(-0.5f, -0.5f), Vec2( 1.5f,  1.5f) },
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ Vec2( 1.0f, -1.0f), Vec2(-1.3f,  1.0f) },
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ Vec2( 1.2f, -1.0f), Vec2(-1.3f,  1.6f) },
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ Vec2( 2.2f, -1.1f), Vec2(-1.3f,  0.8f) },
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ Vec2(-1.5f,  1.6f), Vec2( 1.7f, -1.4f) },
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ Vec2( 2.0f,  1.6f), Vec2( 2.3f, -1.4f) },
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ Vec2( 1.3f, -2.6f), Vec2(-2.7f,  2.9f) },
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ Vec2(-0.8f, -6.6f), Vec2( 6.0f, -0.9f) },
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ Vec2( -8.0f,   9.0f), Vec2(  8.3f,  -7.0f) },
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ Vec2(-16.0f,  10.0f), Vec2( 18.3f,  24.0f) },
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ Vec2( 30.2f,  55.0f), Vec2(-24.3f,  -1.6f) },
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ Vec2(-33.2f,  64.1f), Vec2( 32.1f, -64.1f) },
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(cellNdx, 0, DE_LENGTH_OF_ARRAY(s_basicCoords)));
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec2& bottomLeft	= s_basicCoords[cellNdx].bottomLeft;
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec2& topRight	= s_basicCoords[cellNdx].topRight;
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	computeQuadTexCoord2D(dst, bottomLeft, topRight);
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void getAffineTexCoord2D (std::vector<float>& dst, int cellNdx)
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Use basic coords as base.
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	getBasicTexCoord2D(dst, cellNdx);
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Rotate based on cell index.
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		angle		= 2.0f*DE_PI * ((float)cellNdx / 16.0f);
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Mat2	rotMatrix	= tcu::rotationMatrix(angle);
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Second and third row are sheared.
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		shearX		= de::inRange(cellNdx, 4, 11) ? (float)(15-cellNdx) / 16.0f : 0.0f;
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Mat2	shearMatrix	= tcu::shearMatrix(tcu::Vec2(shearX, 0.0f));
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Mat2	transform	= rotMatrix * shearMatrix;
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec2		p0			= transform * Vec2(dst[0], dst[1]);
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec2		p1			= transform * Vec2(dst[2], dst[3]);
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec2		p2			= transform * Vec2(dst[4], dst[5]);
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec2		p3			= transform * Vec2(dst[6], dst[7]);
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	dst[0] = p0.x();	dst[1] = p0.y();
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	dst[2] = p1.x();	dst[3] = p1.y();
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	dst[4] = p2.x();	dst[5] = p2.y();
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	dst[6] = p3.x();	dst[7] = p3.y();
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2933c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DMipmapCase::IterateResult Texture2DMipmapCase::iterate (void)
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&		gl					= m_renderCtx.getFunctions();
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Texture2D&		refTexture			= m_texture->getRefTexture();
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32				magFilter			= GL_NEAREST;
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					texWidth			= refTexture.getWidth();
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					texHeight			= refTexture.getHeight();
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					defViewportWidth	= texWidth*4;
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					defViewportHeight	= texHeight*4;
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const RandomViewport		viewport			(m_renderCtx.getRenderTarget(), defViewportWidth, defViewportHeight, deStringHash(getName()));
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ReferenceParams				sampleParams		(TEXTURETYPE_2D);
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<float>				texCoord;
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool					isProjected			= m_coordType == COORDTYPE_PROJECTED;
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool					useLodBias			= m_coordType == COORDTYPE_BASIC_BIAS;
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface				renderedFrame		(viewport.width, viewport.height);
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Viewport is divided into 4x4 grid.
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int							gridWidth			= 4;
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int							gridHeight			= 4;
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int							cellWidth			= viewport.width / gridWidth;
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int							cellHeight			= viewport.height / gridHeight;
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Bail out if rendertarget is too small.
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (viewport.width < defViewportWidth/2 || viewport.height < defViewportHeight/2)
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::NotSupportedError("Too small viewport", "", __FILE__, __LINE__);
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Sampling parameters.
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleParams.sampler		= glu::mapGLSampler(m_wrapS, m_wrapT, m_minFilter, magFilter);
326c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket	sampleParams.samplerType	= glu::TextureTestUtil::getSamplerType(m_texture->getRefTexture().getFormat());
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleParams.flags			= (isProjected ? ReferenceParams::PROJECTED : 0) | (useLodBias ? ReferenceParams::USE_BIAS : 0);
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleParams.lodMode		= LODMODE_EXACT; // Use ideal lod.
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Upload texture data.
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_texture->upload();
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Bind gradient texture and setup sampler parameters.
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindTexture	(GL_TEXTURE_2D, m_texture->getGLTexture());
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		m_wrapS);
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		m_wrapT);
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	m_minFilter);
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	magFilter);
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "After texture setup");
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Bias values.
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const float s_bias[] = { 1.0f, -2.0f, 0.8f, -0.5f, 1.5f, 0.9f, 2.0f, 4.0f };
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Projection values.
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const Vec4 s_projections[] =
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Vec4(1.2f, 1.0f, 0.7f, 1.0f),
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Vec4(1.3f, 0.8f, 0.6f, 2.0f),
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Vec4(0.8f, 1.0f, 1.7f, 0.6f),
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Vec4(1.2f, 1.0f, 1.7f, 1.5f)
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Render cells.
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int gridY = 0; gridY < gridHeight; gridY++)
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int gridX = 0; gridX < gridWidth; gridX++)
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int		curX		= cellWidth*gridX;
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int		curY		= cellHeight*gridY;
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int		curW		= gridX+1 == gridWidth ? (viewport.width-curX) : cellWidth;
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int		curH		= gridY+1 == gridHeight ? (viewport.height-curY) : cellHeight;
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int		cellNdx		= gridY*gridWidth + gridX;
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Compute texcoord.
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (m_coordType)
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case COORDTYPE_BASIC_BIAS:	// Fall-through.
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case COORDTYPE_PROJECTED:
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case COORDTYPE_BASIC:		getBasicTexCoord2D	(texCoord, cellNdx);	break;
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case COORDTYPE_AFFINE:		getAffineTexCoord2D	(texCoord, cellNdx);	break;
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				default:					DE_ASSERT(DE_FALSE);
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (isProjected)
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				sampleParams.w = s_projections[cellNdx % DE_LENGTH_OF_ARRAY(s_projections)];
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (useLodBias)
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				sampleParams.bias = s_bias[cellNdx % DE_LENGTH_OF_ARRAY(s_bias)];
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Render with GL.
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.viewport(viewport.x+curX, viewport.y+curY, curW, curH);
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_renderer.renderQuad(0, &texCoord[0], sampleParams);
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Read result.
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compare and log.
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::PixelFormat&	pixelFormat		= m_renderCtx.getRenderTarget().getPixelFormat();
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool				isTrilinear		= m_minFilter == GL_NEAREST_MIPMAP_LINEAR || m_minFilter == GL_LINEAR_MIPMAP_LINEAR;
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Surface			referenceFrame	(viewport.width, viewport.height);
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Surface			errorMask		(viewport.width, viewport.height);
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::LookupPrecision	lookupPrec;
3970b6dbeb93e83dcf3b55d2eccce7cb1517c2caee5Pyry Haulos		tcu::LodPrecision		lodPrec;
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int						numFailedPixels	= 0;
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lookupPrec.coordBits		= tcu::IVec3(20, 20, 0);
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lookupPrec.uvwBits			= tcu::IVec3(16, 16, 0); // Doesn't really matter since pixels are unicolored.
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lookupPrec.colorThreshold	= tcu::computeFixedPointThreshold(max(getBitsVec(pixelFormat) - (isTrilinear ? 2 : 1), tcu::IVec4(0)));
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lookupPrec.colorMask		= getCompareMask(pixelFormat);
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lodPrec.derivateBits		= 10;
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lodPrec.lodBits				= isProjected ? 6 : 8;
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int gridY = 0; gridY < gridHeight; gridY++)
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int gridX = 0; gridX < gridWidth; gridX++)
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int		curX		= cellWidth*gridX;
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int		curY		= cellHeight*gridY;
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int		curW		= gridX+1 == gridWidth ? (viewport.width-curX) : cellWidth;
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int		curH		= gridY+1 == gridHeight ? (viewport.height-curY) : cellHeight;
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int		cellNdx		= gridY*gridWidth + gridX;
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// Compute texcoord.
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				switch (m_coordType)
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case COORDTYPE_BASIC_BIAS:	// Fall-through.
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case COORDTYPE_PROJECTED:
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case COORDTYPE_BASIC:		getBasicTexCoord2D	(texCoord, cellNdx);	break;
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case COORDTYPE_AFFINE:		getAffineTexCoord2D	(texCoord, cellNdx);	break;
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					default:					DE_ASSERT(DE_FALSE);
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (isProjected)
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					sampleParams.w = s_projections[cellNdx % DE_LENGTH_OF_ARRAY(s_projections)];
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (useLodBias)
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					sampleParams.bias = s_bias[cellNdx % DE_LENGTH_OF_ARRAY(s_bias)];
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// Render ideal result
434c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket				sampleTexture(tcu::SurfaceAccess(referenceFrame, pixelFormat, curX, curY, curW, curH),
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							  refTexture, &texCoord[0], sampleParams);
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// Compare this cell
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numFailedPixels += computeTextureLookupDiff(tcu::getSubregion(renderedFrame.getAccess(), curX, curY, curW, curH),
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															tcu::getSubregion(referenceFrame.getAccess(), curX, curY, curW, curH),
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															tcu::getSubregion(errorMask.getAccess(), curX, curY, curW, curH),
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															m_texture->getRefTexture(), &texCoord[0], sampleParams,
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															lookupPrec, lodPrec, m_testCtx.getWatchDog());
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (numFailedPixels > 0)
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog() << TestLog::Message << "ERROR: Image verification failed, found " << numFailedPixels << " invalid pixels!" << TestLog::EndMessage;
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << TestLog::ImageSet("Result", "Verification result")
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							<< TestLog::Image("Rendered", "Rendered image", renderedFrame);
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (numFailedPixels > 0)
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog() << TestLog::Image("Reference", "Ideal reference", referenceFrame)
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								<< TestLog::Image("ErrorMask", "Error mask", errorMask);
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << TestLog::EndImageSet;
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool isOk = numFailedPixels == 0;
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									isOk ? "Pass"				: "Image verification failed");
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// TextureCubeMipmapCase
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass TextureCubeMipmapCase : public tcu::TestCase
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								TextureCubeMipmapCase		(tcu::TestContext&			testCtx,
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 glu::RenderContext&		renderCtx,
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 const glu::ContextInfo&	renderCtxInfo,
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 const char*				name,
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 const char*				desc,
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 CoordType					coordType,
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 deUint32					minFilter,
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 deUint32					wrapS,
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 deUint32					wrapT,
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 deUint32					format,
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 deUint32					dataType,
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 int						size);
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								~TextureCubeMipmapCase		(void);
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						init						(void);
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						deinit						(void);
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult				iterate						(void);
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								TextureCubeMipmapCase		(const TextureCubeMipmapCase& other);
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureCubeMipmapCase&		operator=					(const TextureCubeMipmapCase& other);
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::RenderContext&			m_renderCtx;
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::ContextInfo&		m_renderCtxInfo;
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CoordType					m_coordType;
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32					m_minFilter;
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32					m_wrapS;
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32					m_wrapT;
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32					m_format;
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32					m_dataType;
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int							m_size;
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TextureCube*			m_texture;
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureRenderer				m_renderer;
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5133c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeMipmapCase::TextureCubeMipmapCase (tcu::TestContext&			testCtx,
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											  glu::RenderContext&		renderCtx,
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											  const glu::ContextInfo&	renderCtxInfo,
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											  const char*				name,
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											  const char*				desc,
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											  CoordType					coordType,
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											  deUint32					minFilter,
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											  deUint32					wrapS,
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											  deUint32					wrapT,
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											  deUint32					format,
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											  deUint32					dataType,
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											  int						size)
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase			(testCtx, name, desc)
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderCtx		(renderCtx)
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderCtxInfo	(renderCtxInfo)
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_coordType		(coordType)
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_minFilter		(minFilter)
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapS			(wrapS)
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapT			(wrapT)
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_format			(format)
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_dataType		(dataType)
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_size			(size)
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_texture			(DE_NULL)
536469002caa1ccd58f59f53a1bf3dbac4cf6a5d817Jarkko Pöyry	, m_renderer		(renderCtx, testCtx.getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5403c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeMipmapCase::~TextureCubeMipmapCase (void)
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deinit();
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCubeMipmapCase::init (void)
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_coordType == COORDTYPE_PROJECTED && m_renderCtx.getRenderTarget().getNumSamples() > 0)
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::NotSupportedError("Projected lookup validation not supported in multisample config");
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_texture = new glu::TextureCube(m_renderCtx, m_format, m_dataType, m_size);
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int numLevels = deLog2Floor32(m_size)+1;
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Fill texture with colored grid.
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deUint32	step		= 0xff / (numLevels-1);
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deUint32	inc			= deClamp32(step*levelNdx, 0x00, 0xff);
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deUint32	dec			= 0xff - inc;
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deUint32	rgb			= 0;
5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (faceNdx)
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case 0: rgb = (inc << 16) | (dec << 8) | 255; break;
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case 1: rgb = (255 << 16) | (inc << 8) | dec; break;
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case 2: rgb = (dec << 16) | (255 << 8) | inc; break;
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case 3: rgb = (dec << 16) | (inc << 8) | 255; break;
5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case 4: rgb = (255 << 16) | (dec << 8) | inc; break;
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case 5: rgb = (inc << 16) | (255 << 8) | dec; break;
5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deUint32	color		= 0xff000000 | rgb;
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_texture->getRefTexture().allocLevel((tcu::CubeFace)faceNdx, levelNdx);
577c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket			tcu::clear(m_texture->getRefTexture().getLevelFace(levelNdx, (tcu::CubeFace)faceNdx), tcu::RGBA(color).toVec());
5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCubeMipmapCase::deinit (void)
5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_texture;
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_texture = DE_NULL;
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderer.clear();
5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void randomPartition (vector<IVec4>& dst, de::Random& rnd, int x, int y, int width, int height)
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int minWidth	= 8;
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int minHeight	= 8;
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool	partition		= rnd.getFloat() > 0.4f;
5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool	partitionX		= partition && width > minWidth && rnd.getBool();
5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool	partitionY		= partition && height > minHeight && !partitionX;
5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (partitionX)
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int split = width/2 + rnd.getInt(-width/4, +width/4);
6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		randomPartition(dst, rnd, x, y, split, height);
6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		randomPartition(dst, rnd, x+split, y, width-split, height);
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (partitionY)
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int split = height/2 + rnd.getInt(-height/4, +height/4);
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		randomPartition(dst, rnd, x, y, width, split);
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		randomPartition(dst, rnd, x, y+split, width, height-split);
6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		dst.push_back(IVec4(x, y, width, height));
6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void computeGridLayout (vector<IVec4>& dst, int width, int height)
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::Random rnd(7);
6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	randomPartition(dst, rnd, 0, 0, width, height);
6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6213c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeMipmapCase::IterateResult TextureCubeMipmapCase::iterate (void)
6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32			magFilter			= GL_NEAREST;
6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				texWidth			= m_texture->getRefTexture().getSize();
6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				texHeight			= m_texture->getRefTexture().getSize();
6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				defViewportWidth	= texWidth*2;
6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				defViewportHeight	= texHeight*2;
6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl					= m_renderCtx.getFunctions();
6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const RandomViewport	viewport			(m_renderCtx.getRenderTarget(), defViewportWidth, defViewportHeight, deStringHash(getName()));
6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool				isProjected			= m_coordType == COORDTYPE_PROJECTED;
6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool				useLodBias			= m_coordType == COORDTYPE_BASIC_BIAS;
6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<float>			texCoord;
6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface			renderedFrame		(viewport.width, viewport.height);
6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Bail out if rendertarget is too small.
6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (viewport.width < defViewportWidth/2 || viewport.height < defViewportHeight/2)
6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::NotSupportedError("Too small viewport", "", __FILE__, __LINE__);
6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Upload texture data.
6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_texture->upload();
6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Bind gradient texture and setup sampler parameters.
6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindTexture	(GL_TEXTURE_CUBE_MAP, m_texture->getGLTexture());
6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,		m_wrapS);
6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,		m_wrapT);
6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,	m_minFilter);
6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER,	magFilter);
6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "After texture setup");
6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compute grid.
6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<IVec4> gridLayout;
6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	computeGridLayout(gridLayout, viewport.width, viewport.height);
6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Bias values.
6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const float s_bias[] = { 1.0f, -2.0f, 0.8f, -0.5f, 1.5f, 0.9f, 2.0f, 4.0f };
6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Projection values \note Less agressive than in 2D case due to smaller quads.
6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const Vec4 s_projections[] =
6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Vec4(1.2f, 1.0f, 0.7f, 1.0f),
6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Vec4(1.3f, 0.8f, 0.6f, 1.1f),
6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Vec4(0.8f, 1.0f, 1.2f, 0.8f),
6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Vec4(1.2f, 1.0f, 1.3f, 0.9f)
6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Render with GL
6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int cellNdx = 0; cellNdx < (int)gridLayout.size(); cellNdx++)
6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int			curX		= gridLayout[cellNdx].x();
6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int			curY		= gridLayout[cellNdx].y();
6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int			curW		= gridLayout[cellNdx].z();
6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int			curH		= gridLayout[cellNdx].w();
6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::CubeFace	cubeFace	= (tcu::CubeFace)(cellNdx % tcu::CUBEFACE_LAST);
6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RenderParams		params		(TEXTURETYPE_CUBE);
6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(m_coordType != COORDTYPE_AFFINE); // Not supported.
6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		computeQuadTexCoordCube(texCoord, cubeFace);
6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (isProjected)
6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			params.flags	|= ReferenceParams::PROJECTED;
6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			params.w		 = s_projections[cellNdx % DE_LENGTH_OF_ARRAY(s_projections)];
6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (useLodBias)
6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			params.flags	|= ReferenceParams::USE_BIAS;
6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			params.bias		 = s_bias[cellNdx % DE_LENGTH_OF_ARRAY(s_bias)];
6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Render with GL.
6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.viewport(viewport.x+curX, viewport.y+curY, curW, curH);
6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_renderer.renderQuad(0, &texCoord[0], params);
6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "Draw");
7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Read result.
7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());
7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "Read pixels");
7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Render reference and compare
7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Surface			referenceFrame		(viewport.width, viewport.height);
7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Surface			errorMask			(viewport.width, viewport.height);
7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int						numFailedPixels		= 0;
7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ReferenceParams			params				(TEXTURETYPE_CUBE);
7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::LookupPrecision	lookupPrec;
7120b6dbeb93e83dcf3b55d2eccce7cb1517c2caee5Pyry Haulos		tcu::LodPrecision		lodPrec;
7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Params for rendering reference
7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		params.sampler					= glu::mapGLSampler(m_wrapS, m_wrapT, m_minFilter, magFilter);
7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		params.sampler.seamlessCubeMap	= true;
7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		params.lodMode					= LODMODE_EXACT;
7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Comparison parameters
7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lookupPrec.colorMask			= getCompareMask(m_renderCtx.getRenderTarget().getPixelFormat());
7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lookupPrec.colorThreshold		= tcu::computeFixedPointThreshold(max(getBitsVec(m_renderCtx.getRenderTarget().getPixelFormat())-2, IVec4(0)));
7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lookupPrec.coordBits			= isProjected ? tcu::IVec3(8) : tcu::IVec3(10);
7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lookupPrec.uvwBits				= tcu::IVec3(5,5,0);
7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lodPrec.derivateBits			= 10;
725e8ef296162c99669d786b805a148b9a3e8ae5831Pyry Haulos		lodPrec.lodBits					= isProjected ? 3 : 6;
7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int cellNdx = 0; cellNdx < (int)gridLayout.size(); cellNdx++)
7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				curX		= gridLayout[cellNdx].x();
7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				curY		= gridLayout[cellNdx].y();
7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				curW		= gridLayout[cellNdx].z();
7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				curH		= gridLayout[cellNdx].w();
7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const tcu::CubeFace		cubeFace	= (tcu::CubeFace)(cellNdx % tcu::CUBEFACE_LAST);
7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(m_coordType != COORDTYPE_AFFINE); // Not supported.
7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			computeQuadTexCoordCube(texCoord, cubeFace);
7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (isProjected)
7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				params.flags	|= ReferenceParams::PROJECTED;
7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				params.w		 = s_projections[cellNdx % DE_LENGTH_OF_ARRAY(s_projections)];
7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (useLodBias)
7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				params.flags	|= ReferenceParams::USE_BIAS;
7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				params.bias		 = s_bias[cellNdx % DE_LENGTH_OF_ARRAY(s_bias)];
7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Render ideal reference.
7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
752c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket				tcu::SurfaceAccess idealDst(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat(), curX, curY, curW, curH);
7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				sampleTexture(idealDst, m_texture->getRefTexture(), &texCoord[0], params);
7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Compare this cell
7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			numFailedPixels += computeTextureLookupDiff(tcu::getSubregion(renderedFrame.getAccess(), curX, curY, curW, curH),
7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														tcu::getSubregion(referenceFrame.getAccess(), curX, curY, curW, curH),
7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														tcu::getSubregion(errorMask.getAccess(), curX, curY, curW, curH),
7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														m_texture->getRefTexture(), &texCoord[0], params,
7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														lookupPrec, lodPrec, m_testCtx.getWatchDog());
7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (numFailedPixels > 0)
7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog() << TestLog::Message << "ERROR: Image verification failed, found " << numFailedPixels << " invalid pixels!" << TestLog::EndMessage;
7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << TestLog::ImageSet("Result", "Verification result")
7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						   << TestLog::Image("Rendered", "Rendered image", renderedFrame);
7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (numFailedPixels > 0)
7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog() << TestLog::Image("Reference", "Ideal reference", referenceFrame)
7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							   << TestLog::Image("ErrorMask", "Error mask", errorMask);
7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << TestLog::EndImageSet;
7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool isOk = numFailedPixels == 0;
7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									isOk ? "Pass"				: "Image verification failed");
7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture2DGenMipmapCase
7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Texture2DGenMipmapCase : public tcu::TestCase
7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								Texture2DGenMipmapCase		(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 hint, int width, int height);
7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								~Texture2DGenMipmapCase		(void);
7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						init						(void);
7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						deinit						(void);
7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult				iterate						(void);
8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								Texture2DGenMipmapCase		(const Texture2DGenMipmapCase& other);
8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Texture2DGenMipmapCase&		operator=					(const Texture2DGenMipmapCase& other);
8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::RenderContext&			m_renderCtx;
8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32					m_format;
8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32					m_dataType;
8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32					m_hint;
8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int							m_width;
8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int							m_height;
8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::Texture2D*				m_texture;
8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureRenderer				m_renderer;
8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8173c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DGenMipmapCase::Texture2DGenMipmapCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 hint, int width, int height)
8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase			(testCtx, name, desc)
8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderCtx		(renderCtx)
8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_format			(format)
8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_dataType		(dataType)
8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_hint			(hint)
8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width			(width)
8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height			(height)
8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_texture			(DE_NULL)
826469002caa1ccd58f59f53a1bf3dbac4cf6a5d817Jarkko Pöyry	, m_renderer		(renderCtx, testCtx.getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8303c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DGenMipmapCase::~Texture2DGenMipmapCase (void)
8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deinit();
8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture2DGenMipmapCase::init (void)
8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!m_texture);
8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_texture = new glu::Texture2D(m_renderCtx, m_format, m_dataType, m_width, m_height);
8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture2DGenMipmapCase::deinit (void)
8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_texture;
8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_texture = DE_NULL;
8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderer.clear();
8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8493c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DGenMipmapCase::IterateResult Texture2DGenMipmapCase::iterate (void)
8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl					= m_renderCtx.getFunctions();
8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32			minFilter			= GL_NEAREST_MIPMAP_NEAREST;
8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32			magFilter			= GL_NEAREST;
8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32			wrapS				= GL_CLAMP_TO_EDGE;
8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32			wrapT				= GL_CLAMP_TO_EDGE;
8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				numLevels			= deLog2Floor32(de::max(m_width, m_height))+1;
8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Texture2D			resultTexture		(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), m_texture->getRefTexture().getWidth(), m_texture->getRefTexture().getHeight());
8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<float>			texCoord;
8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Initialize texture level 0 with colored grid.
8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_texture->getRefTexture().allocLevel(0);
8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::fillWithGrid(m_texture->getRefTexture().getLevel(0), 8, tcu::Vec4(1.0f, 0.5f, 0.0f, 0.5f), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Upload data and setup params.
8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_texture->upload();
8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindTexture	(GL_TEXTURE_2D, m_texture->getGLTexture());
8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		wrapS);
8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		wrapT);
8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	minFilter);
8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	magFilter);
8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "After texture setup");
8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generate mipmap.
8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.hint(GL_GENERATE_MIPMAP_HINT, m_hint);
8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.generateMipmap(GL_TEXTURE_2D);
8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenerateMipmap()");
8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Use (0, 0) -> (1, 1) texture coordinates.
8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	computeQuadTexCoord2D(texCoord, Vec2(0.0f, 0.0f), Vec2(1.0f, 1.0f));
8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Fetch resulting texture by rendering.
8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				levelWidth		= de::max(1, m_width >> levelNdx);
8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				levelHeight		= de::max(1, m_height >> levelNdx);
8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const RandomViewport	viewport		(m_renderCtx.getRenderTarget(), levelWidth, levelHeight, deStringHash(getName()) + levelNdx);
8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_renderer.renderQuad(0, &texCoord[0], TEXTURETYPE_2D);
8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		resultTexture.allocLevel(levelNdx);
8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::readPixels(m_renderCtx, viewport.x, viewport.y, resultTexture.getLevel(levelNdx));
8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compare results
9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const IVec4			framebufferBits		= max(getBitsVec(m_renderCtx.getRenderTarget().getPixelFormat())-2, IVec4(0));
9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const IVec4			formatBits			= tcu::getTextureFormatBitDepth(glu::mapGLTransferFormat(m_format, m_dataType));
9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::BVec4	formatMask			= greaterThan(formatBits, IVec4(0));
9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const IVec4			cmpBits				= select(min(framebufferBits, formatBits), framebufferBits, formatMask);
9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GenMipmapPrecision	comparePrec;
9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		comparePrec.colorMask		= getCompareMask(m_renderCtx.getRenderTarget().getPixelFormat());
9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		comparePrec.colorThreshold	= tcu::computeFixedPointThreshold(cmpBits);
9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		comparePrec.filterBits		= tcu::IVec3(4, 4, 0);
9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const qpTestResult compareResult = compareGenMipmapResult(m_testCtx.getLog(), resultTexture, m_texture->getRefTexture(), comparePrec);
9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(compareResult, compareResult == QP_TEST_RESULT_PASS				? "Pass" :
9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											   compareResult == QP_TEST_RESULT_QUALITY_WARNING	? "Low-quality method used"	:
9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											   compareResult == QP_TEST_RESULT_FAIL				? "Image comparison failed"	: "");
9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// TextureCubeGenMipmapCase
9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass TextureCubeGenMipmapCase : public tcu::TestCase
9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								TextureCubeGenMipmapCase		(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 hint, int size);
9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								~TextureCubeGenMipmapCase		(void);
9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						init							(void);
9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						deinit							(void);
9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult				iterate							(void);
9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								TextureCubeGenMipmapCase		(const TextureCubeGenMipmapCase& other);
9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureCubeGenMipmapCase&	operator=						(const TextureCubeGenMipmapCase& other);
9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::RenderContext&			m_renderCtx;
9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32					m_format;
9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32					m_dataType;
9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32					m_hint;
9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int							m_size;
9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TextureCube*			m_texture;
9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureRenderer				m_renderer;
9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9503c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeGenMipmapCase::TextureCubeGenMipmapCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 hint, int size)
9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase			(testCtx, name, desc)
9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderCtx		(renderCtx)
9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_format			(format)
9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_dataType		(dataType)
9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_hint			(hint)
9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_size			(size)
9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_texture			(DE_NULL)
958469002caa1ccd58f59f53a1bf3dbac4cf6a5d817Jarkko Pöyry	, m_renderer		(renderCtx, testCtx.getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9623c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeGenMipmapCase::~TextureCubeGenMipmapCase (void)
9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deinit();
9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9673c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCubeGenMipmapCase::init (void)
9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_renderCtx.getRenderTarget().getWidth() < 3*m_size || m_renderCtx.getRenderTarget().getHeight() < 2*m_size)
9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::NotSupportedError("Render target size must be at least (" + de::toString(3*m_size) + ", " + de::toString(2*m_size) + ")");
9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!m_texture);
9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_texture = new glu::TextureCube(m_renderCtx, m_format, m_dataType, m_size);
9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCubeGenMipmapCase::deinit (void)
9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_texture;
9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_texture = DE_NULL;
9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderer.clear();
9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9843c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeGenMipmapCase::IterateResult TextureCubeGenMipmapCase::iterate (void)
9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl					= m_renderCtx.getFunctions();
9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32			minFilter			= GL_NEAREST_MIPMAP_NEAREST;
9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32			magFilter			= GL_NEAREST;
9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32			wrapS				= GL_CLAMP_TO_EDGE;
9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32			wrapT				= GL_CLAMP_TO_EDGE;
9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TextureCube		resultTexture		(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), m_size);
9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				numLevels			= deLog2Floor32(m_size)+1;
9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<float>			texCoord;
9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Initialize texture level 0 with colored grid.
9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Vec4 ca, cb; // Grid colors.
10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		switch (face)
10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case 0: ca = Vec4(1.0f, 0.3f, 0.0f, 0.7f); cb = Vec4(0.0f, 0.0f, 1.0f, 1.0f); break;
10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case 1: ca = Vec4(0.0f, 1.0f, 0.5f, 0.5f); cb = Vec4(1.0f, 0.0f, 0.0f, 1.0f); break;
10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case 2: ca = Vec4(0.7f, 0.0f, 1.0f, 0.3f); cb = Vec4(0.0f, 1.0f, 0.0f, 1.0f); break;
10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case 3: ca = Vec4(0.0f, 0.3f, 1.0f, 1.0f); cb = Vec4(1.0f, 0.0f, 0.0f, 0.7f); break;
10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case 4: ca = Vec4(1.0f, 0.0f, 0.5f, 1.0f); cb = Vec4(0.0f, 1.0f, 0.0f, 0.5f); break;
10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case 5: ca = Vec4(0.7f, 1.0f, 0.0f, 1.0f); cb = Vec4(0.0f, 0.0f, 1.0f, 0.3f); break;
10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_texture->getRefTexture().allocLevel((tcu::CubeFace)face, 0);
10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		fillWithGrid(m_texture->getRefTexture().getLevelFace(0, (tcu::CubeFace)face), 8, ca, cb);
10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Upload data and setup params.
10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_texture->upload();
10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindTexture	(GL_TEXTURE_CUBE_MAP, m_texture->getGLTexture());
10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,		wrapS);
10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,		wrapT);
10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,	minFilter);
10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER,	magFilter);
10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "After texture setup");
10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generate mipmap.
10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.hint(GL_GENERATE_MIPMAP_HINT, m_hint);
10293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.generateMipmap(GL_TEXTURE_CUBE_MAP);
10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenerateMipmap()");
10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Render all levels.
10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	levelWidth	= de::max(1, m_size >> levelNdx);
10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	levelHeight	= de::max(1, m_size >> levelNdx);
10373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
10393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const RandomViewport	viewport	(m_renderCtx.getRenderTarget(), levelWidth*3, levelHeight*2, deStringHash(getName()) ^ deInt32Hash(levelNdx + faceNdx));
10413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const tcu::CubeFace		face		= tcu::CubeFace(faceNdx);
10423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			computeQuadTexCoordCube(texCoord, face);
10443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.viewport(viewport.x, viewport.y, levelWidth, levelHeight);
10463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_renderer.renderQuad(0, &texCoord[0], TEXTURETYPE_CUBE);
10473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			resultTexture.allocLevel(face, levelNdx);
10493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glu::readPixels(m_renderCtx, viewport.x, viewport.y, resultTexture.getLevelFace(levelNdx, face));
10503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compare results
10543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const IVec4			framebufferBits		= max(getBitsVec(m_renderCtx.getRenderTarget().getPixelFormat())-2, IVec4(0));
10563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const IVec4			formatBits			= tcu::getTextureFormatBitDepth(glu::mapGLTransferFormat(m_format, m_dataType));
10573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::BVec4	formatMask			= greaterThan(formatBits, IVec4(0));
10583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const IVec4			cmpBits				= select(min(framebufferBits, formatBits), framebufferBits, formatMask);
10593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GenMipmapPrecision	comparePrec;
10603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		comparePrec.colorMask		= getCompareMask(m_renderCtx.getRenderTarget().getPixelFormat());
10623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		comparePrec.colorThreshold	= tcu::computeFixedPointThreshold(cmpBits);
10633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		comparePrec.filterBits		= tcu::IVec3(4, 4, 0);
10643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const qpTestResult compareResult = compareGenMipmapResult(m_testCtx.getLog(), resultTexture, m_texture->getRefTexture(), comparePrec);
10663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(compareResult, compareResult == QP_TEST_RESULT_PASS				? "Pass" :
10683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											   compareResult == QP_TEST_RESULT_QUALITY_WARNING	? "Low-quality method used"	:
10693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											   compareResult == QP_TEST_RESULT_FAIL				? "Image comparison failed"	: "");
10703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
10733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture3DMipmapCase
10763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10773c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Texture3DMipmapCase : public TestCase
10783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10793c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
10803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								Texture3DMipmapCase			(Context&					context,
10823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 const char*				name,
10833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 const char*				desc,
10843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 CoordType					coordType,
10853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 deUint32					minFilter,
10863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 deUint32					wrapS,
10873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 deUint32					wrapT,
10883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 deUint32					wrapR,
10893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 deUint32					format,
10903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 int						width,
10913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 int						height,
10923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 int						depth);
10933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								~Texture3DMipmapCase		(void);
10943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						init						(void);
10963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						deinit						(void);
10973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult				iterate						(void);
10983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10993c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
11003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								Texture3DMipmapCase			(const Texture3DMipmapCase& other);
11013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Texture3DMipmapCase&		operator=					(const Texture3DMipmapCase& other);
11023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CoordType					m_coordType;
11043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32					m_minFilter;
11053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32					m_wrapS;
11063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32					m_wrapT;
11073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32					m_wrapR;
11083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32					m_internalFormat;
11093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int							m_width;
11103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int							m_height;
11113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int							m_depth;
11123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::Texture3D*						m_texture;
11143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureTestUtil::TextureRenderer	m_renderer;
11153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
11163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11173c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture3DMipmapCase::Texture3DMipmapCase (Context& context, const char* name, const char* desc, CoordType coordType, deUint32 minFilter, deUint32 wrapS, deUint32 wrapT, deUint32 wrapR, deUint32 format, int width, int height, int depth)
11183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase			(context, name, desc)
11193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_coordType		(coordType)
11203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_minFilter		(minFilter)
11213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapS			(wrapS)
11223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapT			(wrapT)
11233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapR			(wrapR)
11243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_internalFormat	(format)
11253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width			(width)
11263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height			(height)
11273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_depth			(depth)
11283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_texture			(DE_NULL)
1129469002caa1ccd58f59f53a1bf3dbac4cf6a5d817Jarkko Pöyry	, m_renderer		(context.getRenderContext(), context.getTestContext().getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
11303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11333c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture3DMipmapCase::~Texture3DMipmapCase (void)
11343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Texture3DMipmapCase::deinit();
11363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11383c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture3DMipmapCase::init (void)
11393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::TextureFormat&		texFmt			= glu::mapGLInternalFormat(m_internalFormat);
11413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TextureFormatInfo			fmtInfo			= tcu::getTextureFormatInfo(texFmt);
11423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec4&				cScale			= fmtInfo.lookupScale;
11433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec4&				cBias			= fmtInfo.lookupBias;
11443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int								numLevels		= deLog2Floor32(de::max(de::max(m_width, m_height), m_depth))+1;
11453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_coordType == COORDTYPE_PROJECTED && m_context.getRenderTarget().getNumSamples() > 0)
11473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::NotSupportedError("Projected lookup validation not supported in multisample config");
11483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_texture = new glu::Texture3D(m_context.getRenderContext(), m_internalFormat, m_width, m_height, m_depth);
11503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Fill texture with colored grid.
11523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
11533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32	step		= 0xff / (numLevels-1);
11553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32	inc			= deClamp32(step*levelNdx, 0x00, 0xff);
11563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32	dec			= 0xff - inc;
11573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32	rgb			= (0xff << 16) | (dec << 8) | inc;
11583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32	color		= 0xff000000 | rgb;
11593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_texture->getRefTexture().allocLevel(levelNdx);
11613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::clear(m_texture->getRefTexture().getLevel(levelNdx), tcu::RGBA(color).toVec()*cScale + cBias);
11623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_texture->upload();
11653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11673c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture3DMipmapCase::deinit (void)
11683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_texture;
11703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_texture = DE_NULL;
11713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderer.clear();
11733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11753c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void getBasicTexCoord3D (std::vector<float>& dst, int cellNdx)
11763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
11783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float sScale;
11803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float sBias;
11813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float tScale;
11823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float tBias;
11833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float rScale;
11843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float rBias;
11853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} s_params[] =
11863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	//		sScale	sBias	tScale	tBias	rScale	rBias
11883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{	 0.9f,	-0.1f,	 0.7f,	 0.3f,	 0.8f,	 0.9f	},
11893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{	 1.2f,	-0.1f,	 1.1f,	 0.3f,	 1.0f,	 0.9f	},
11903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{	 1.5f,	 0.7f,	 0.9f,	-0.3f,	 1.1f,	 0.1f	},
11913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{	 1.2f,	 0.7f,	-2.3f,	-0.3f,	 1.1f,	 0.2f	},
11923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{	 1.1f,	 0.8f,	-1.3f,	-0.3f,	 2.9f,	 0.9f	},
11933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{	 3.4f,	 0.8f,	 4.0f,	 0.0f,	-3.3f,	-1.0f	},
11943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{	-3.4f,	-0.1f,	-4.0f,	 0.0f,	-5.1f,	 1.0f	},
11953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{	-4.0f,	-0.1f,	 3.4f,	 0.1f,	 5.7f,	 0.0f	},
11963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{	-5.6f,	 0.0f,	 0.5f,	 1.2f,	 3.9f,	 4.0f	},
11973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{	 5.0f,	-2.0f,	 3.1f,	 1.2f,	 5.1f,	 0.2f	},
11983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{	 2.5f,	-2.0f,	 6.3f,	 3.0f,	 5.1f,	 0.2f	},
11993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{	-8.3f,	 0.0f,	 7.1f,	 3.0f,	 2.0f,	 0.2f	},
12003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{    3.8f,	 0.0f,	 9.7f,	 1.0f,	 7.0f,	 0.7f	},
12013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{	13.3f,	 0.0f,	 7.1f,	 3.0f,	 2.0f,	 0.2f	},
12023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{   16.0f,	 8.0f,	12.7f,	 1.0f,	17.1f,	 0.7f	},
12033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{	15.3f,	 0.0f,	20.1f,	 3.0f,	33.0f,	 3.2f	}
12043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
12053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float sScale	= s_params[cellNdx%DE_LENGTH_OF_ARRAY(s_params)].sScale;
12073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float sBias		= s_params[cellNdx%DE_LENGTH_OF_ARRAY(s_params)].sBias;
12083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float tScale	= s_params[cellNdx%DE_LENGTH_OF_ARRAY(s_params)].tScale;
12093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float tBias		= s_params[cellNdx%DE_LENGTH_OF_ARRAY(s_params)].tBias;
12103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float rScale	= s_params[cellNdx%DE_LENGTH_OF_ARRAY(s_params)].rScale;
12113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float rBias		= s_params[cellNdx%DE_LENGTH_OF_ARRAY(s_params)].rBias;
12123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	dst.resize(3*4);
12143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	dst[0] = sBias;			dst[ 1] = tBias;			dst[ 2] = rBias;
12163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	dst[3] = sBias;			dst[ 4] = tBias+tScale;		dst[ 5] = rBias+rScale*0.5f;
12173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	dst[6] = sBias+sScale;	dst[ 7] = tBias;			dst[ 8] = rBias+rScale*0.5f;
12183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	dst[9] = sBias+sScale;	dst[10] = tBias+tScale;		dst[11] = rBias+rScale;
12193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12213c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void getAffineTexCoord3D (std::vector<float>& dst, int cellNdx)
12223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Use basic coords as base.
12243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	getBasicTexCoord3D(dst, cellNdx);
12253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Rotate based on cell index.
12273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		angleX		= 0.0f + 2.0f*DE_PI * ((float)cellNdx / 16.0f);
12283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		angleY		= 1.0f + 2.0f*DE_PI * ((float)cellNdx / 32.0f);
12293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Mat3	rotMatrix	= tcu::rotationMatrixX(angleX) * tcu::rotationMatrixY(angleY);
12303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec3		p0			= rotMatrix * Vec3(dst[0], dst[ 1], dst[ 2]);
12323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec3		p1			= rotMatrix * Vec3(dst[3], dst[ 4], dst[ 5]);
12333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec3		p2			= rotMatrix * Vec3(dst[6], dst[ 7], dst[ 8]);
12343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec3		p3			= rotMatrix * Vec3(dst[9], dst[10], dst[11]);
12353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	dst[0] = p0.x();	dst[ 1] = p0.y();	dst[ 2] = p0.z();
12373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	dst[3] = p1.x();	dst[ 4] = p1.y();	dst[ 5] = p1.z();
12383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	dst[6] = p2.x();	dst[ 7] = p2.y();	dst[ 8] = p2.z();
12393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	dst[9] = p3.x();	dst[10] = p3.y();	dst[11] = p3.z();
12403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12423c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture3DMipmapCase::IterateResult Texture3DMipmapCase::iterate (void)
12433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&			gl					= m_context.getRenderContext().getFunctions();
12453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Texture3D&			refTexture			= m_texture->getRefTexture();
12473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::TextureFormat&		texFmt				= refTexture.getFormat();
12483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::TextureFormatInfo	fmtInfo				= tcu::getTextureFormatInfo(texFmt);
12493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						texWidth			= refTexture.getWidth();
12503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						texHeight			= refTexture.getHeight();
12513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					magFilter			= GL_NEAREST;
12523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::RenderTarget&		renderTarget		= m_context.getRenderContext().getRenderTarget();
12543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const RandomViewport			viewport			(renderTarget, texWidth*4, texHeight*4, deStringHash(getName()));
12553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool						isProjected			= m_coordType == COORDTYPE_PROJECTED;
12573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool						useLodBias			= m_coordType == COORDTYPE_BASIC_BIAS;
12583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Viewport is divided into 4x4 grid.
12603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						gridWidth			= 4;
12613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						gridHeight			= 4;
12623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						cellWidth			= viewport.width / gridWidth;
12633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						cellHeight			= viewport.height / gridHeight;
12643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ReferenceParams					sampleParams		(TEXTURETYPE_3D);
12663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface					renderedFrame		(viewport.width, viewport.height);
12683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<float>					texCoord;
12693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Sampling parameters.
12713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleParams.sampler		= glu::mapGLSampler(m_wrapS, m_wrapT, m_wrapR, m_minFilter, magFilter);
1272c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket	sampleParams.samplerType	= getSamplerType(texFmt);
12733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleParams.colorBias		= fmtInfo.lookupBias;
12743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleParams.colorScale		= fmtInfo.lookupScale;
12753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleParams.flags			= (isProjected ? ReferenceParams::PROJECTED : 0) | (useLodBias ? ReferenceParams::USE_BIAS : 0);
12763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Bind texture and setup sampler parameters.
12783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindTexture	(GL_TEXTURE_3D, m_texture->getGLTexture());
12793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S,		m_wrapS);
12803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T,		m_wrapT);
12813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R,		m_wrapR);
12823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER,	m_minFilter);
12833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER,	magFilter);
12843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "After texture setup");
12863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Bias values.
12883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const float s_bias[] = { 1.0f, -2.0f, 0.8f, -0.5f, 1.5f, 0.9f, 2.0f, 4.0f };
12893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Projection values.
12913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const Vec4 s_projections[] =
12923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Vec4(1.2f, 1.0f, 0.7f, 1.0f),
12943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Vec4(1.3f, 0.8f, 0.6f, 2.0f),
12953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Vec4(0.8f, 1.0f, 1.7f, 0.6f),
12963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Vec4(1.2f, 1.0f, 1.7f, 1.5f)
12973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
12983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Render cells.
13003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int gridY = 0; gridY < gridHeight; gridY++)
13013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int gridX = 0; gridX < gridWidth; gridX++)
13033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int		curX		= cellWidth*gridX;
13053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int		curY		= cellHeight*gridY;
13063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int		curW		= gridX+1 == gridWidth ? (viewport.width-curX) : cellWidth;
13073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int		curH		= gridY+1 == gridHeight ? (viewport.height-curY) : cellHeight;
13083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int		cellNdx		= gridY*gridWidth + gridX;
13093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Compute texcoord.
13113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (m_coordType)
13123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
13133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case COORDTYPE_BASIC_BIAS:	// Fall-through.
13143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case COORDTYPE_PROJECTED:
13153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case COORDTYPE_BASIC:		getBasicTexCoord3D	(texCoord, cellNdx);	break;
13163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case COORDTYPE_AFFINE:		getAffineTexCoord3D	(texCoord, cellNdx);	break;
13173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				default:					DE_ASSERT(DE_FALSE);
13183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
13193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Set projection.
13213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (isProjected)
13223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				sampleParams.w = s_projections[cellNdx % DE_LENGTH_OF_ARRAY(s_projections)];
13233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Set LOD bias.
13253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (useLodBias)
13263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				sampleParams.bias = s_bias[cellNdx % DE_LENGTH_OF_ARRAY(s_bias)];
13273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Render with GL.
13293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.viewport(viewport.x+curX, viewport.y+curY, curW, curH);
13303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_renderer.renderQuad(0, &texCoord[0], sampleParams);
13313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Read result.
13353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::readPixels(m_context.getRenderContext(), viewport.x, viewport.y, renderedFrame.getAccess());
13363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compare and log
13383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::PixelFormat&	pixelFormat		= m_context.getRenderTarget().getPixelFormat();
13403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool				isTrilinear		= m_minFilter == GL_NEAREST_MIPMAP_LINEAR || m_minFilter == GL_LINEAR_MIPMAP_LINEAR;
13413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Surface			referenceFrame	(viewport.width, viewport.height);
13423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Surface			errorMask		(viewport.width, viewport.height);
13433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::LookupPrecision	lookupPrec;
13440b6dbeb93e83dcf3b55d2eccce7cb1517c2caee5Pyry Haulos		tcu::LodPrecision		lodPrec;
13453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int						numFailedPixels	= 0;
13463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lookupPrec.coordBits		= tcu::IVec3(20, 20, 20);
13483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lookupPrec.uvwBits			= tcu::IVec3(16, 16, 16); // Doesn't really matter since pixels are unicolored.
13493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lookupPrec.colorThreshold	= tcu::computeFixedPointThreshold(max(getBitsVec(pixelFormat) - (isTrilinear ? 2 : 1), tcu::IVec4(0)));
13503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lookupPrec.colorMask		= getCompareMask(pixelFormat);
13513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lodPrec.derivateBits		= 10;
13523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lodPrec.lodBits				= isProjected ? 6 : 8;
13533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int gridY = 0; gridY < gridHeight; gridY++)
13553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int gridX = 0; gridX < gridWidth; gridX++)
13573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
13583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int		curX		= cellWidth*gridX;
13593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int		curY		= cellHeight*gridY;
13603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int		curW		= gridX+1 == gridWidth ? (viewport.width-curX) : cellWidth;
13613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int		curH		= gridY+1 == gridHeight ? (viewport.height-curY) : cellHeight;
13623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int		cellNdx		= gridY*gridWidth + gridX;
13633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				switch (m_coordType)
13653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
13663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case COORDTYPE_BASIC_BIAS:	// Fall-through.
13673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case COORDTYPE_PROJECTED:
13683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case COORDTYPE_BASIC:		getBasicTexCoord3D	(texCoord, cellNdx);	break;
13693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case COORDTYPE_AFFINE:		getAffineTexCoord3D	(texCoord, cellNdx);	break;
13703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					default:					DE_ASSERT(DE_FALSE);
13713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
13723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (isProjected)
13743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					sampleParams.w = s_projections[cellNdx % DE_LENGTH_OF_ARRAY(s_projections)];
13753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (useLodBias)
13773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					sampleParams.bias = s_bias[cellNdx % DE_LENGTH_OF_ARRAY(s_bias)];
13783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// Render ideal result
1380c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket				sampleTexture(tcu::SurfaceAccess(referenceFrame, pixelFormat, curX, curY, curW, curH),
13813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							  refTexture, &texCoord[0], sampleParams);
13823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// Compare this cell
13843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numFailedPixels += computeTextureLookupDiff(tcu::getSubregion(renderedFrame.getAccess(), curX, curY, curW, curH),
13853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															tcu::getSubregion(referenceFrame.getAccess(), curX, curY, curW, curH),
13863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															tcu::getSubregion(errorMask.getAccess(), curX, curY, curW, curH),
13873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															m_texture->getRefTexture(), &texCoord[0], sampleParams,
13883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															lookupPrec, lodPrec, m_testCtx.getWatchDog());
13893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
13903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (numFailedPixels > 0)
13933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog() << TestLog::Message << "ERROR: Image verification failed, found " << numFailedPixels << " invalid pixels!" << TestLog::EndMessage;
13943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << TestLog::ImageSet("Result", "Verification result")
13963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							<< TestLog::Image("Rendered", "Rendered image", renderedFrame);
13973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (numFailedPixels > 0)
13993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog() << TestLog::Image("Reference", "Ideal reference", referenceFrame)
14013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								<< TestLog::Image("ErrorMask", "Error mask", errorMask);
14023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << TestLog::EndImageSet;
14053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool isOk = numFailedPixels == 0;
14083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
14093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									isOk ? "Pass"				: "Image verification failed");
14103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
14143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture2DLodControlCase + test cases
14173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14183c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Texture2DLodControlCase : public TestCase
14193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14203c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
14213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										Texture2DLodControlCase		(Context& context, const char* name, const char* desc, deUint32 minFilter);
14233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										~Texture2DLodControlCase	(void);
14243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void								init						(void);
14263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void								deinit						(void);
14273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult						iterate						(void);
14283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14293c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
14303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void						setTextureParams			(int cellNdx)							= DE_NULL;
14313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void						getReferenceParams			(ReferenceParams& params, int cellNdx)	= DE_NULL;
14323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int							m_texWidth;
14343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int							m_texHeight;
14353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14363c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
14373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										Texture2DLodControlCase		(const Texture2DLodControlCase& other);
14383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Texture2DLodControlCase&			operator=					(const Texture2DLodControlCase& other);
14393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32							m_minFilter;
14413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::Texture2D*						m_texture;
14433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureTestUtil::TextureRenderer	m_renderer;
14443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
14453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14463c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DLodControlCase::Texture2DLodControlCase (Context& context, const char* name, const char* desc, deUint32 minFilter)
14473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase		(context, name, desc)
14483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_texWidth	(64)
14493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_texHeight	(64)
14503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_minFilter	(minFilter)
14513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_texture		(DE_NULL)
1452469002caa1ccd58f59f53a1bf3dbac4cf6a5d817Jarkko Pöyry	, m_renderer	(context.getRenderContext(), context.getTestContext().getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
14533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14563c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DLodControlCase::~Texture2DLodControlCase (void)
14573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Texture2DLodControlCase::deinit();
14593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14613c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture2DLodControlCase::init (void)
14623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32	format		= GL_RGBA8;
14643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				numLevels	= deLog2Floor32(de::max(m_texWidth, m_texHeight))+1;
14653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_texture = new glu::Texture2D(m_context.getRenderContext(), format, m_texWidth, m_texHeight);
14673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Fill texture with colored grid.
14693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
14703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32	step		= 0xff / (numLevels-1);
14723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32	inc			= deClamp32(step*levelNdx, 0x00, 0xff);
14733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32	dec			= 0xff - inc;
14743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32	rgb			= (inc << 16) | (dec << 8) | 0xff;
14753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32	color		= 0xff000000 | rgb;
14763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_texture->getRefTexture().allocLevel(levelNdx);
14783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::clear(m_texture->getRefTexture().getLevel(levelNdx), tcu::RGBA(color).toVec());
14793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14823c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture2DLodControlCase::deinit (void)
14833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_texture;
14853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_texture = DE_NULL;
14863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderer.clear();
14883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14903c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DLodControlCase::IterateResult Texture2DLodControlCase::iterate (void)
14913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&		gl					= m_context.getRenderContext().getFunctions();
14933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32				wrapS				= GL_REPEAT;
14953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32				wrapT				= GL_REPEAT;
14963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32				magFilter			= GL_NEAREST;
14973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Texture2D&		refTexture			= m_texture->getRefTexture();
14993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					texWidth			= refTexture.getWidth();
15003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					texHeight			= refTexture.getHeight();
15013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::RenderTarget&	renderTarget		= m_context.getRenderContext().getRenderTarget();
15033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const RandomViewport		viewport			(renderTarget, texWidth*4, texHeight*4, deStringHash(getName()));
15043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1505c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket	ReferenceParams				sampleParams		(TEXTURETYPE_2D, glu::mapGLSampler(wrapS, wrapT, m_minFilter, magFilter));
15063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<float>				texCoord;
15073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface				renderedFrame		(viewport.width, viewport.height);
15083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Viewport is divided into 4x4 grid.
15103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					gridWidth			= 4;
15113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					gridHeight			= 4;
15123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					cellWidth			= viewport.width / gridWidth;
15133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					cellHeight			= viewport.height / gridHeight;
15143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Upload texture data.
15163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_texture->upload();
15173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Bind gradient texture and setup sampler parameters.
15193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindTexture	(GL_TEXTURE_2D, m_texture->getGLTexture());
15203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		wrapS);
15213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		wrapT);
15223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	m_minFilter);
15233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	magFilter);
15243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "After texture setup");
15263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Render cells.
15283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int gridY = 0; gridY < gridHeight; gridY++)
15293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int gridX = 0; gridX < gridWidth; gridX++)
15313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
15323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int				curX		= cellWidth*gridX;
15333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int				curY		= cellHeight*gridY;
15343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int				curW		= gridX+1 == gridWidth ? (viewport.width-curX) : cellWidth;
15353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int				curH		= gridY+1 == gridHeight ? (viewport.height-curY) : cellHeight;
15363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int				cellNdx		= gridY*gridWidth + gridX;
15373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Compute texcoord.
15393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			getBasicTexCoord2D(texCoord, cellNdx);
15403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Render with GL.
15423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			setTextureParams(cellNdx);
15433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.viewport(viewport.x+curX, viewport.y+curY, curW, curH);
15443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_renderer.renderQuad(0, &texCoord[0], sampleParams);
15453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::readPixels(m_context.getRenderContext(), viewport.x, viewport.y, renderedFrame.getAccess());
15493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "Read pixels");
15503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compare and log.
15523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::PixelFormat&	pixelFormat		= m_context.getRenderTarget().getPixelFormat();
15543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool				isTrilinear		= m_minFilter == GL_NEAREST_MIPMAP_LINEAR || m_minFilter == GL_LINEAR_MIPMAP_LINEAR;
15553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Surface			referenceFrame	(viewport.width, viewport.height);
15563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Surface			errorMask		(viewport.width, viewport.height);
15573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::LookupPrecision	lookupPrec;
15580b6dbeb93e83dcf3b55d2eccce7cb1517c2caee5Pyry Haulos		tcu::LodPrecision		lodPrec;
15593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int						numFailedPixels	= 0;
15603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lookupPrec.coordBits		= tcu::IVec3(20, 20, 0);
15623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lookupPrec.uvwBits			= tcu::IVec3(16, 16, 0); // Doesn't really matter since pixels are unicolored.
15633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lookupPrec.colorThreshold	= tcu::computeFixedPointThreshold(max(getBitsVec(pixelFormat) - (isTrilinear ? 2 : 1), tcu::IVec4(0)));
15643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lookupPrec.colorMask		= getCompareMask(pixelFormat);
15653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lodPrec.derivateBits		= 10;
15663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lodPrec.lodBits				= 8;
15673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int gridY = 0; gridY < gridHeight; gridY++)
15693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
15703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int gridX = 0; gridX < gridWidth; gridX++)
15713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
15723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int		curX		= cellWidth*gridX;
15733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int		curY		= cellHeight*gridY;
15743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int		curW		= gridX+1 == gridWidth ? (viewport.width-curX) : cellWidth;
15753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int		curH		= gridY+1 == gridHeight ? (viewport.height-curY) : cellHeight;
15763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int		cellNdx		= gridY*gridWidth + gridX;
15773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				getBasicTexCoord2D(texCoord, cellNdx);
15793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				getReferenceParams(sampleParams, cellNdx);
15803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// Render ideal result
1582c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket				sampleTexture(tcu::SurfaceAccess(referenceFrame, pixelFormat, curX, curY, curW, curH),
15833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							  refTexture, &texCoord[0], sampleParams);
15843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// Compare this cell
15863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numFailedPixels += computeTextureLookupDiff(tcu::getSubregion(renderedFrame.getAccess(), curX, curY, curW, curH),
15873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															tcu::getSubregion(referenceFrame.getAccess(), curX, curY, curW, curH),
15883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															tcu::getSubregion(errorMask.getAccess(), curX, curY, curW, curH),
15893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															m_texture->getRefTexture(), &texCoord[0], sampleParams,
15903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															lookupPrec, lodPrec, m_testCtx.getWatchDog());
15913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
15923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (numFailedPixels > 0)
15953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog() << TestLog::Message << "ERROR: Image verification failed, found " << numFailedPixels << " invalid pixels!" << TestLog::EndMessage;
15963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << TestLog::ImageSet("Result", "Verification result")
15983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							<< TestLog::Image("Rendered", "Rendered image", renderedFrame);
15993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (numFailedPixels > 0)
16013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
16023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog() << TestLog::Image("Reference", "Ideal reference", referenceFrame)
16033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								<< TestLog::Image("ErrorMask", "Error mask", errorMask);
16043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
16053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << TestLog::EndImageSet;
16073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
16093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool isOk = numFailedPixels == 0;
16103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
16113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									isOk ? "Pass"				: "Image verification failed");
16123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
16133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
16163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16183c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Texture2DMinLodCase : public Texture2DLodControlCase
16193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16203c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
16213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Texture2DMinLodCase (Context& context, const char* name, const char* desc, deUint32 minFilter)
16223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: Texture2DLodControlCase(context, name, desc, minFilter)
16233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16263c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
16273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void setTextureParams (int cellNdx)
16283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
16303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.texParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, getMinLodForCell(cellNdx));
16313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void getReferenceParams (ReferenceParams& params, int cellNdx)
16343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		params.minLod = getMinLodForCell(cellNdx);
16363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
16383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16393c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Texture2DMaxLodCase : public Texture2DLodControlCase
16403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16413c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
16423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Texture2DMaxLodCase (Context& context, const char* name, const char* desc, deUint32 minFilter)
16433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: Texture2DLodControlCase(context, name, desc, minFilter)
16443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16473c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
16483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void setTextureParams (int cellNdx)
16493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
16513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.texParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, getMaxLodForCell(cellNdx));
16523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void getReferenceParams (ReferenceParams& params, int cellNdx)
16553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		params.maxLod = getMaxLodForCell(cellNdx);
16573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
16593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16603c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Texture2DBaseLevelCase : public Texture2DLodControlCase
16613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16623c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
16633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Texture2DBaseLevelCase (Context& context, const char* name, const char* desc, deUint32 minFilter)
16643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: Texture2DLodControlCase(context, name, desc, minFilter)
16653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16683c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
16693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int getBaseLevel (int cellNdx) const
16703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	numLevels	= deLog2Floor32(de::max(m_texWidth, m_texHeight))+1;
16723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	baseLevel	= (deInt32Hash(cellNdx) ^ deStringHash(getName()) ^ 0xac2f274a) % numLevels;
16733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return baseLevel;
16753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void setTextureParams (int cellNdx)
16783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glw::Functions&	gl	= m_context.getRenderContext().getFunctions();
16803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, getBaseLevel(cellNdx));
16813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void getReferenceParams (ReferenceParams& params, int cellNdx)
16843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		params.baseLevel = getBaseLevel(cellNdx);
16863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
16883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16893c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Texture2DMaxLevelCase : public Texture2DLodControlCase
16903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16913c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
16923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Texture2DMaxLevelCase (Context& context, const char* name, const char* desc, deUint32 minFilter)
16933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: Texture2DLodControlCase(context, name, desc, minFilter)
16943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16973c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
16983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int getMaxLevel (int cellNdx) const
16993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int		numLevels	= deLog2Floor32(de::max(m_texWidth, m_texHeight))+1;
17013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int		maxLevel	= (deInt32Hash(cellNdx) ^ deStringHash(getName()) ^ 0x82cfa4e) % numLevels;
17023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return maxLevel;
17043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void setTextureParams (int cellNdx)
17073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glw::Functions&	gl	= m_context.getRenderContext().getFunctions();
17093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, getMaxLevel(cellNdx));
17103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void getReferenceParams (ReferenceParams& params, int cellNdx)
17133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		params.maxLevel = getMaxLevel(cellNdx);
17153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
17173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// TextureCubeLodControlCase + test cases
17193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17203c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass TextureCubeLodControlCase : public TestCase
17213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17223c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
17233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										TextureCubeLodControlCase	(Context& context, const char* name, const char* desc, deUint32 minFilter);
17253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										~TextureCubeLodControlCase	(void);
17263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void								init						(void);
17283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void								deinit						(void);
17293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult						iterate						(void);
17303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17313c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
17323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void						setTextureParams			(int cellNdx)							= DE_NULL;
17333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void						getReferenceParams			(ReferenceParams& params, int cellNdx)	= DE_NULL;
17343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int							m_texSize;
17363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
17383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										TextureCubeLodControlCase	(const TextureCubeLodControlCase& other);
17393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureCubeLodControlCase&			operator=					(const TextureCubeLodControlCase& other);
17403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32							m_minFilter;
17423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TextureCube*					m_texture;
17443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureTestUtil::TextureRenderer	m_renderer;
17453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
17463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17473c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeLodControlCase::TextureCubeLodControlCase (Context& context, const char* name, const char* desc, deUint32 minFilter)
17483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase			(context, name, desc)
17493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_texSize			(64)
17503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_minFilter		(minFilter)
17513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_texture			(DE_NULL)
1752469002caa1ccd58f59f53a1bf3dbac4cf6a5d817Jarkko Pöyry	, m_renderer		(context.getRenderContext(), context.getTestContext().getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
17533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17563c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeLodControlCase::~TextureCubeLodControlCase (void)
17573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deinit();
17593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17613c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCubeLodControlCase::init (void)
17623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32	format		= GL_RGBA8;
17643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		numLevels	= deLog2Floor32(m_texSize)+1;
17653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_texture = new glu::TextureCube(m_context.getRenderContext(), format, m_texSize);
17673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Fill texture with colored grid.
17693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
17703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
17723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deUint32	step		= 0xff / (numLevels-1);
17743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deUint32	inc			= deClamp32(step*levelNdx, 0x00, 0xff);
17753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deUint32	dec			= 0xff - inc;
17763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deUint32	rgb			= 0;
17773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (faceNdx)
17793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
17803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case 0: rgb = (inc << 16) | (dec << 8) | 255; break;
17813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case 1: rgb = (255 << 16) | (inc << 8) | dec; break;
17823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case 2: rgb = (dec << 16) | (255 << 8) | inc; break;
17833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case 3: rgb = (dec << 16) | (inc << 8) | 255; break;
17843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case 4: rgb = (255 << 16) | (dec << 8) | inc; break;
17853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case 5: rgb = (inc << 16) | (255 << 8) | dec; break;
17863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
17873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deUint32	color		= 0xff000000 | rgb;
17893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_texture->getRefTexture().allocLevel((tcu::CubeFace)faceNdx, levelNdx);
17913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::clear(m_texture->getRefTexture().getLevelFace(levelNdx, (tcu::CubeFace)faceNdx), tcu::RGBA(color).toVec());
17923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
17933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17963c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCubeLodControlCase::deinit (void)
17973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_texture;
17993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_texture = DE_NULL;
18003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderer.clear();
18023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18043c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeLodControlCase::IterateResult TextureCubeLodControlCase::iterate (void)
18053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32			wrapS				= GL_CLAMP_TO_EDGE;
18073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32			wrapT				= GL_CLAMP_TO_EDGE;
18083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32			magFilter			= GL_NEAREST;
18093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				texWidth			= m_texture->getRefTexture().getSize();
18113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				texHeight			= m_texture->getRefTexture().getSize();
18123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				defViewportWidth	= texWidth*2;
18143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				defViewportHeight	= texHeight*2;
18153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl					= m_context.getRenderContext().getFunctions();
18173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const RandomViewport	viewport			(m_context.getRenderTarget(), defViewportWidth, defViewportHeight, deStringHash(getName()));
18183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<float>			texCoord;
18203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface			renderedFrame		(viewport.width, viewport.height);
18223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Upload texture data.
18243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_texture->upload();
18253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Bind gradient texture and setup sampler parameters.
18273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindTexture	(GL_TEXTURE_CUBE_MAP, m_texture->getGLTexture());
18283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,		wrapS);
18293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,		wrapT);
18303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,	m_minFilter);
18313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER,	magFilter);
18323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "After texture setup");
18343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compute grid.
18363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<tcu::IVec4> gridLayout;
18373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	computeGridLayout(gridLayout, viewport.width, viewport.height);
18383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int cellNdx = 0; cellNdx < (int)gridLayout.size(); cellNdx++)
18403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int			curX		= gridLayout[cellNdx].x();
18423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int			curY		= gridLayout[cellNdx].y();
18433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int			curW		= gridLayout[cellNdx].z();
18443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int			curH		= gridLayout[cellNdx].w();
18453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::CubeFace	cubeFace	= (tcu::CubeFace)(cellNdx % tcu::CUBEFACE_LAST);
18463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RenderParams		params		(TEXTURETYPE_CUBE);
18473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1848c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket		computeQuadTexCoordCube(texCoord, cubeFace);
18493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		setTextureParams(cellNdx);
18513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Render with GL.
18533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.viewport(viewport.x+curX, viewport.y+curY, curW, curH);
18543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_renderer.renderQuad(0, &texCoord[0], params);
18553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "Draw");
18563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Read result.
18593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::readPixels(m_context.getRenderContext(), viewport.x, viewport.y, renderedFrame.getAccess());
18603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "Read pixels");
18613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Render reference and compare
18633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Surface			referenceFrame		(viewport.width, viewport.height);
18653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Surface			errorMask			(viewport.width, viewport.height);
18663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int						numFailedPixels		= 0;
18673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ReferenceParams			params				(TEXTURETYPE_CUBE);
18683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::LookupPrecision	lookupPrec;
18690b6dbeb93e83dcf3b55d2eccce7cb1517c2caee5Pyry Haulos		tcu::LodPrecision		lodPrec;
18703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Params for rendering reference
18723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		params.sampler					= glu::mapGLSampler(wrapS, wrapT, m_minFilter, magFilter);
18733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		params.sampler.seamlessCubeMap	= true;
18743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		params.lodMode					= LODMODE_EXACT;
18753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Comparison parameters
18773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lookupPrec.colorMask			= getCompareMask(m_context.getRenderTarget().getPixelFormat());
18783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lookupPrec.colorThreshold		= tcu::computeFixedPointThreshold(max(getBitsVec(m_context.getRenderTarget().getPixelFormat())-2, IVec4(0)));
18793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lookupPrec.coordBits			= tcu::IVec3(10);
18803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lookupPrec.uvwBits				= tcu::IVec3(5,5,0);
18813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lodPrec.derivateBits			= 10;
18823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lodPrec.lodBits					= 6;
18833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int cellNdx = 0; cellNdx < (int)gridLayout.size(); cellNdx++)
18853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
18863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				curX		= gridLayout[cellNdx].x();
18873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				curY		= gridLayout[cellNdx].y();
18883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				curW		= gridLayout[cellNdx].z();
18893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				curH		= gridLayout[cellNdx].w();
18903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const tcu::CubeFace		cubeFace	= (tcu::CubeFace)(cellNdx % tcu::CUBEFACE_LAST);
18913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			computeQuadTexCoordCube(texCoord, cubeFace);
18933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			getReferenceParams(params, cellNdx);
18943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Render ideal reference.
18963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
1897c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket				tcu::SurfaceAccess idealDst(referenceFrame, m_context.getRenderTarget().getPixelFormat(), curX, curY, curW, curH);
18983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				sampleTexture(idealDst, m_texture->getRefTexture(), &texCoord[0], params);
18993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
19003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Compare this cell
19023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			numFailedPixels += computeTextureLookupDiff(tcu::getSubregion(renderedFrame.getAccess(), curX, curY, curW, curH),
19033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														tcu::getSubregion(referenceFrame.getAccess(), curX, curY, curW, curH),
19043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														tcu::getSubregion(errorMask.getAccess(), curX, curY, curW, curH),
19053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														m_texture->getRefTexture(), &texCoord[0], params,
19063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														lookupPrec, lodPrec, m_testCtx.getWatchDog());
19073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
19083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (numFailedPixels > 0)
19103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog() << TestLog::Message << "ERROR: Image verification failed, found " << numFailedPixels << " invalid pixels!" << TestLog::EndMessage;
19113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << TestLog::ImageSet("Result", "Verification result")
19133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						   << TestLog::Image("Rendered", "Rendered image", renderedFrame);
19143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (numFailedPixels > 0)
19163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog() << TestLog::Image("Reference", "Ideal reference", referenceFrame)
19183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							   << TestLog::Image("ErrorMask", "Error mask", errorMask);
19193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
19203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << TestLog::EndImageSet;
19223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool isOk = numFailedPixels == 0;
19253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
19263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									isOk ? "Pass"				: "Image verification failed");
19273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
19283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
19313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19333c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass TextureCubeMinLodCase : public TextureCubeLodControlCase
19343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
19353c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
19363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureCubeMinLodCase (Context& context, const char* name, const char* desc, deUint32 minFilter)
19373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: TextureCubeLodControlCase(context, name, desc, minFilter)
19383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19413c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
19423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void setTextureParams (int cellNdx)
19433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
19453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.texParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_LOD, getMinLodForCell(cellNdx));
19463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void getReferenceParams (ReferenceParams& params, int cellNdx)
19493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		params.minLod = getMinLodForCell(cellNdx);
19513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
19533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19543c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass TextureCubeMaxLodCase : public TextureCubeLodControlCase
19553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
19563c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
19573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureCubeMaxLodCase (Context& context, const char* name, const char* desc, deUint32 minFilter)
19583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: TextureCubeLodControlCase(context, name, desc, minFilter)
19593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19623c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
19633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void setTextureParams (int cellNdx)
19643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
19663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.texParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LOD, getMaxLodForCell(cellNdx));
19673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void getReferenceParams (ReferenceParams& params, int cellNdx)
19703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		params.maxLod = getMaxLodForCell(cellNdx);
19723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
19743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19753c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass TextureCubeBaseLevelCase : public TextureCubeLodControlCase
19763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
19773c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
19783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureCubeBaseLevelCase (Context& context, const char* name, const char* desc, deUint32 minFilter)
19793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: TextureCubeLodControlCase(context, name, desc, minFilter)
19803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19833c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
19843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int getBaseLevel (int cellNdx) const
19853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	numLevels	= deLog2Floor32(m_texSize)+1;
19873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	baseLevel	= (deInt32Hash(cellNdx) ^ deStringHash(getName()) ^ 0x23fae13) % numLevels;
19883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return baseLevel;
19903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void setTextureParams (int cellNdx)
19933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
19953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, getBaseLevel(cellNdx));
19963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void getReferenceParams (ReferenceParams& params, int cellNdx)
19993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
20003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		params.baseLevel = getBaseLevel(cellNdx);
20013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
20033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20043c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass TextureCubeMaxLevelCase : public TextureCubeLodControlCase
20053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20063c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
20073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureCubeMaxLevelCase (Context& context, const char* name, const char* desc, deUint32 minFilter)
20083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: TextureCubeLodControlCase(context, name, desc, minFilter)
20093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
20103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20123c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
20133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int getMaxLevel (int cellNdx) const
20143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
20153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	numLevels	= deLog2Floor32(m_texSize)+1;
20163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	maxLevel	= (deInt32Hash(cellNdx) ^ deStringHash(getName()) ^ 0x974e21) % numLevels;
20173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return maxLevel;
20193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void setTextureParams (int cellNdx)
20223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
20233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
20243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, getMaxLevel(cellNdx));
20253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void getReferenceParams (ReferenceParams& params, int cellNdx)
20283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
20293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		params.maxLevel = getMaxLevel(cellNdx);
20303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
20323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture3DLodControlCase + test cases
20343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20353c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Texture3DLodControlCase : public TestCase
20363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20373c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
20383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										Texture3DLodControlCase		(Context& context, const char* name, const char* desc, deUint32 minFilter);
20403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										~Texture3DLodControlCase	(void);
20413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void								init						(void);
20433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void								deinit						(void);
20443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult						iterate						(void);
20453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20463c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
20473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void						setTextureParams			(int cellNdx)						= DE_NULL;
20483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void						getReferenceParams			(ReferenceParams& params, int cellNdx)	= DE_NULL;
20493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int							m_texWidth;
20513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int							m_texHeight;
20523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int							m_texDepth;
20533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20543c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
20553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										Texture3DLodControlCase		(const Texture3DLodControlCase& other);
20563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Texture3DLodControlCase&			operator=					(const Texture3DLodControlCase& other);
20573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32							m_minFilter;
20593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::Texture3D*						m_texture;
20613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureTestUtil::TextureRenderer	m_renderer;
20623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
20633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20643c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture3DLodControlCase::Texture3DLodControlCase (Context& context, const char* name, const char* desc, deUint32 minFilter)
20653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase			(context, name, desc)
20663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_texWidth		(32)
20673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_texHeight		(32)
20683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_texDepth		(32)
20693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_minFilter		(minFilter)
20703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_texture			(DE_NULL)
2071469002caa1ccd58f59f53a1bf3dbac4cf6a5d817Jarkko Pöyry	, m_renderer		(context.getRenderContext(), context.getTestContext().getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
20723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20753c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture3DLodControlCase::~Texture3DLodControlCase (void)
20763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Texture3DLodControlCase::deinit();
20783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20803c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture3DLodControlCase::init (void)
20813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					format			= GL_RGBA8;
20833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::TextureFormat&		texFmt			= glu::mapGLInternalFormat(format);
20843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TextureFormatInfo			fmtInfo			= tcu::getTextureFormatInfo(texFmt);
20853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec4&				cScale			= fmtInfo.lookupScale;
20863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec4&				cBias			= fmtInfo.lookupBias;
20873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int								numLevels		= deLog2Floor32(de::max(de::max(m_texWidth, m_texHeight), m_texDepth))+1;
20883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_texture = new glu::Texture3D(m_context.getRenderContext(), format, m_texWidth, m_texHeight, m_texDepth);
20903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Fill texture with colored grid.
20923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
20933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
20943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32	step		= 0xff / (numLevels-1);
20953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32	inc			= deClamp32(step*levelNdx, 0x00, 0xff);
20963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32	dec			= 0xff - inc;
20973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32	rgb			= (inc << 16) | (dec << 8) | 0xff;
20983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32	color		= 0xff000000 | rgb;
20993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_texture->getRefTexture().allocLevel(levelNdx);
21013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::clear(m_texture->getRefTexture().getLevel(levelNdx), tcu::RGBA(color).toVec()*cScale + cBias);
21023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
21033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_texture->upload();
21053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
21063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21073c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture3DLodControlCase::deinit (void)
21083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
21093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_texture;
21103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_texture = DE_NULL;
21113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderer.clear();
21133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
21143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21153c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture3DLodControlCase::IterateResult Texture3DLodControlCase::iterate (void)
21163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
21173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&			gl					= m_context.getRenderContext().getFunctions();
21183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					wrapS				= GL_CLAMP_TO_EDGE;
21203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					wrapT				= GL_CLAMP_TO_EDGE;
21213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					wrapR				= GL_CLAMP_TO_EDGE;
21223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					magFilter			= GL_NEAREST;
21233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Texture3D&			refTexture			= m_texture->getRefTexture();
21243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::TextureFormat&		texFmt				= refTexture.getFormat();
21253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::TextureFormatInfo	fmtInfo				= tcu::getTextureFormatInfo(texFmt);
21263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						texWidth			= refTexture.getWidth();
21273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						texHeight			= refTexture.getHeight();
21283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::RenderTarget&		renderTarget		= m_context.getRenderContext().getRenderTarget();
21303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const RandomViewport			viewport			(renderTarget, texWidth*4, texHeight*4, deStringHash(getName()));
21313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Viewport is divided into 4x4 grid.
21333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						gridWidth			= 4;
21343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						gridHeight			= 4;
21353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						cellWidth			= viewport.width / gridWidth;
21363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						cellHeight			= viewport.height / gridHeight;
21373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface					renderedFrame		(viewport.width, viewport.height);
21393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<float>					texCoord;
2140c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket	ReferenceParams					sampleParams		(TEXTURETYPE_3D);
21413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Sampling parameters.
21433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleParams.sampler		= glu::mapGLSampler(wrapS, wrapT, wrapR, m_minFilter, magFilter);
2144c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket	sampleParams.samplerType	= getSamplerType(texFmt);
21453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleParams.colorBias		= fmtInfo.lookupBias;
21463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleParams.colorScale		= fmtInfo.lookupScale;
21473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Bind texture and setup sampler parameters.
21493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindTexture	(GL_TEXTURE_3D, m_texture->getGLTexture());
21503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S,		wrapS);
21513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T,		wrapT);
21523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R,		wrapR);
21533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER,	m_minFilter);
21543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER,	magFilter);
21553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "After texture setup");
21573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Render cells.
21593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int gridY = 0; gridY < gridHeight; gridY++)
21603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
21613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int gridX = 0; gridX < gridWidth; gridX++)
21623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
21633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int		curX		= cellWidth*gridX;
21643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int		curY		= cellHeight*gridY;
21653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int		curW		= gridX+1 == gridWidth ? (viewport.width-curX) : cellWidth;
21663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int		curH		= gridY+1 == gridHeight ? (viewport.height-curY) : cellHeight;
21673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int		cellNdx		= gridY*gridWidth + gridX;
21683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Compute texcoord.
21703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			getBasicTexCoord3D(texCoord, cellNdx);
21713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			setTextureParams(cellNdx);
21733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Render with GL.
21753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.viewport(viewport.x+curX, viewport.y+curY, curW, curH);
21763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_renderer.renderQuad(0, &texCoord[0], sampleParams);
21773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
21783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
21793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Read result.
21813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::readPixels(m_context.getRenderContext(), viewport.x, viewport.y, renderedFrame.getAccess());
21823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compare and log
21843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
21853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::PixelFormat&	pixelFormat		= m_context.getRenderTarget().getPixelFormat();
21863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool				isTrilinear		= m_minFilter == GL_NEAREST_MIPMAP_LINEAR || m_minFilter == GL_LINEAR_MIPMAP_LINEAR;
21873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Surface			referenceFrame	(viewport.width, viewport.height);
21883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Surface			errorMask		(viewport.width, viewport.height);
21893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::LookupPrecision	lookupPrec;
21900b6dbeb93e83dcf3b55d2eccce7cb1517c2caee5Pyry Haulos		tcu::LodPrecision		lodPrec;
21913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int						numFailedPixels	= 0;
21923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lookupPrec.coordBits		= tcu::IVec3(20, 20, 20);
21943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lookupPrec.uvwBits			= tcu::IVec3(16, 16, 16); // Doesn't really matter since pixels are unicolored.
21953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lookupPrec.colorThreshold	= tcu::computeFixedPointThreshold(max(getBitsVec(pixelFormat) - (isTrilinear ? 2 : 1), tcu::IVec4(0)));
21963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lookupPrec.colorMask		= getCompareMask(pixelFormat);
21973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lodPrec.derivateBits		= 10;
21983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lodPrec.lodBits				= 8;
21993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int gridY = 0; gridY < gridHeight; gridY++)
22013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
22023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int gridX = 0; gridX < gridWidth; gridX++)
22033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
22043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int		curX		= cellWidth*gridX;
22053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int		curY		= cellHeight*gridY;
22063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int		curW		= gridX+1 == gridWidth ? (viewport.width-curX) : cellWidth;
22073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int		curH		= gridY+1 == gridHeight ? (viewport.height-curY) : cellHeight;
22083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int		cellNdx		= gridY*gridWidth + gridX;
22093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				getBasicTexCoord3D(texCoord, cellNdx);
22113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				getReferenceParams(sampleParams, cellNdx);
22123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// Render ideal result
2214c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket				sampleTexture(tcu::SurfaceAccess(referenceFrame, pixelFormat, curX, curY, curW, curH),
22153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							  refTexture, &texCoord[0], sampleParams);
22163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// Compare this cell
22183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numFailedPixels += computeTextureLookupDiff(tcu::getSubregion(renderedFrame.getAccess(), curX, curY, curW, curH),
22193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															tcu::getSubregion(referenceFrame.getAccess(), curX, curY, curW, curH),
22203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															tcu::getSubregion(errorMask.getAccess(), curX, curY, curW, curH),
22213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															m_texture->getRefTexture(), &texCoord[0], sampleParams,
22223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															lookupPrec, lodPrec, m_testCtx.getWatchDog());
22233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
22243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (numFailedPixels > 0)
22273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog() << TestLog::Message << "ERROR: Image verification failed, found " << numFailedPixels << " invalid pixels!" << TestLog::EndMessage;
22283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << TestLog::ImageSet("Result", "Verification result")
22303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							<< TestLog::Image("Rendered", "Rendered image", renderedFrame);
22313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (numFailedPixels > 0)
22333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
22343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog() << TestLog::Image("Reference", "Ideal reference", referenceFrame)
22353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								<< TestLog::Image("ErrorMask", "Error mask", errorMask);
22363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << TestLog::EndImageSet;
22393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
22413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool isOk = numFailedPixels == 0;
22423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
22433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									isOk ? "Pass"				: "Image verification failed");
22443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
22463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
22483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
22493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Texture3DMinLodCase : public Texture3DLodControlCase
22513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
22523c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
22533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Texture3DMinLodCase (Context& context, const char* name, const char* desc, deUint32 minFilter)
22543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: Texture3DLodControlCase(context, name, desc, minFilter)
22553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
22563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
22573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
22593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void setTextureParams (int cellNdx)
22603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
22613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
22623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.texParameterf(GL_TEXTURE_3D, GL_TEXTURE_MIN_LOD, getMinLodForCell(cellNdx));
22633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
22643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void getReferenceParams (ReferenceParams& params, int cellNdx)
22663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
22673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		params.minLod = getMinLodForCell(cellNdx);
22683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
22693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
22703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22713c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Texture3DMaxLodCase : public Texture3DLodControlCase
22723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
22733c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
22743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Texture3DMaxLodCase (Context& context, const char* name, const char* desc, deUint32 minFilter)
22753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: Texture3DLodControlCase(context, name, desc, minFilter)
22763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
22773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
22783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22793c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
22803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void setTextureParams (int cellNdx)
22813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
22823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
22833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.texParameterf(GL_TEXTURE_3D, GL_TEXTURE_MAX_LOD, getMaxLodForCell(cellNdx));
22843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
22853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void getReferenceParams (ReferenceParams& params, int cellNdx)
22873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
22883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		params.maxLod = getMaxLodForCell(cellNdx);
22893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
22903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
22913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22923c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Texture3DBaseLevelCase : public Texture3DLodControlCase
22933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
22943c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
22953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Texture3DBaseLevelCase (Context& context, const char* name, const char* desc, deUint32 minFilter)
22963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: Texture3DLodControlCase(context, name, desc, minFilter)
22973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
22983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
22993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23003c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
23013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int getBaseLevel (int cellNdx) const
23023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
23033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	numLevels	= deLog2Floor32(de::max(m_texWidth, de::max(m_texHeight, m_texDepth)))+1;
23043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	baseLevel	= (deInt32Hash(cellNdx) ^ deStringHash(getName()) ^ 0x7347e9) % numLevels;
23053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return baseLevel;
23073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
23083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void setTextureParams (int cellNdx)
23103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
23113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
23123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, getBaseLevel(cellNdx));
23133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
23143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void getReferenceParams (ReferenceParams& params, int cellNdx)
23163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
23173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		params.baseLevel = getBaseLevel(cellNdx);
23183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
23193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
23203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23213c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Texture3DMaxLevelCase : public Texture3DLodControlCase
23223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23233c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
23243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Texture3DMaxLevelCase (Context& context, const char* name, const char* desc, deUint32 minFilter)
23253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: Texture3DLodControlCase(context, name, desc, minFilter)
23263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
23273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
23283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23293c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
23303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int getMaxLevel (int cellNdx) const
23313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
23323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	numLevels	= deLog2Floor32(de::max(m_texWidth, de::max(m_texHeight, m_texDepth)))+1;
23333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	maxLevel	= (deInt32Hash(cellNdx) ^ deStringHash(getName()) ^ 0x9111e7) % numLevels;
23343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return maxLevel;
23363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
23373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void setTextureParams (int cellNdx)
23393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
23403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
23413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, getMaxLevel(cellNdx));
23423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
23433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void getReferenceParams (ReferenceParams& params, int cellNdx)
23453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
23463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		params.maxLevel = getMaxLevel(cellNdx);
23473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
23483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
23493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23503c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureMipmapTests::TextureMipmapTests (Context& context)
23513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCaseGroup(context, "mipmap", "Mipmapping tests")
23523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23553c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureMipmapTests::~TextureMipmapTests (void)
23563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23593c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureMipmapTests::init (void)
23603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestCaseGroup* group2D		= new tcu::TestCaseGroup(m_testCtx, "2d",	"2D Texture Mipmapping");
23623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestCaseGroup*	groupCube	= new tcu::TestCaseGroup(m_testCtx, "cube",	"Cube Map Mipmapping");
23633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestCaseGroup*	group3D		= new tcu::TestCaseGroup(m_testCtx, "3d",	"3D Texture Mipmapping");
23643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(group2D);
23653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(groupCube);
23663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(group3D);
23673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
23693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
23703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		name;
23713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32		mode;
23723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} wrapModes[] =
23733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
23743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "clamp",		GL_CLAMP_TO_EDGE },
23753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "repeat",		GL_REPEAT },
23763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "mirror",		GL_MIRRORED_REPEAT }
23773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
23783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
23803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
23813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		name;
23823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32		mode;
23833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} minFilterModes[] =
23843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
23853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "nearest_nearest",	GL_NEAREST_MIPMAP_NEAREST	},
23863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "linear_nearest",		GL_LINEAR_MIPMAP_NEAREST	},
23873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "nearest_linear",		GL_NEAREST_MIPMAP_LINEAR	},
23883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "linear_linear",		GL_LINEAR_MIPMAP_LINEAR		}
23893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
23903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
23923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
23933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CoordType		type;
23943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		name;
23953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		desc;
23963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} coordTypes[] =
23973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
23983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ COORDTYPE_BASIC,		"basic",		"Mipmapping with translated and scaled coordinates" },
23993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ COORDTYPE_AFFINE,		"affine",		"Mipmapping with affine coordinate transform"		},
24003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ COORDTYPE_PROJECTED,	"projected",	"Mipmapping with perspective projection"			}
24013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
24023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
24043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		name;
24063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32		format;
24073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32		dataType;
24083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} formats[] =
24093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "a8",			GL_ALPHA,			GL_UNSIGNED_BYTE },
24113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "l8",			GL_LUMINANCE,		GL_UNSIGNED_BYTE },
24123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "la88",		GL_LUMINANCE_ALPHA,	GL_UNSIGNED_BYTE },
24133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "rgb565",		GL_RGB,				GL_UNSIGNED_SHORT_5_6_5 },
24143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "rgb888",		GL_RGB,				GL_UNSIGNED_BYTE },
24153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "rgba4444",	GL_RGBA,			GL_UNSIGNED_SHORT_4_4_4_4 },
24163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "rgba5551",	GL_RGBA,			GL_UNSIGNED_SHORT_5_5_5_1 },
24173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "rgba8888",	GL_RGBA,			GL_UNSIGNED_BYTE }
24183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
24193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
24213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		name;
24233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32		hint;
24243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} genHints[] =
24253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "fastest",	GL_FASTEST },
24273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "nicest",		GL_NICEST }
24283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
24293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
24313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		name;
24333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				width;
24343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				height;
24353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} tex2DSizes[] =
24363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ DE_NULL,		64, 64 }, // Default.
24383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "npot",		63, 57 },
24393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "non_square",	32, 64 }
24403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
24413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
24433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		name;
24453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				width;
24463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				height;
24473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				depth;
24483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} tex3DSizes[] =
24493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ DE_NULL,		32, 32, 32 }, // Default.
24513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "npot",		33, 29, 27 }
24523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
24533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int cubeMapSize = 64;
24553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
24573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CoordType		type;
24593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		name;
24603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		desc;
24613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} cubeCoordTypes[] =
24623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ COORDTYPE_BASIC,		"basic",		"Mipmapping with translated and scaled coordinates" },
24643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ COORDTYPE_PROJECTED,	"projected",	"Mipmapping with perspective projection"			},
24653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ COORDTYPE_BASIC_BIAS,	"bias",			"User-supplied bias value"							}
24663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
24673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// 2D cases.
24693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int coordType = 0; coordType < DE_LENGTH_OF_ARRAY(coordTypes); coordType++)
24703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* coordTypeGroup = new tcu::TestCaseGroup(m_testCtx, coordTypes[coordType].name, coordTypes[coordType].desc);
24723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		group2D->addChild(coordTypeGroup);
24733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
24753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
24763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int wrapMode = 0; wrapMode < DE_LENGTH_OF_ARRAY(wrapModes); wrapMode++)
24773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
24783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// Add non_square variants to basic cases only.
24793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int sizeEnd = coordTypes[coordType].type == COORDTYPE_BASIC ? DE_LENGTH_OF_ARRAY(tex2DSizes) : 1;
24803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int size = 0; size < sizeEnd; size++)
24823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
24833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					std::ostringstream name;
24843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					name << minFilterModes[minFilter].name
24853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						 << "_" << wrapModes[wrapMode].name;
24863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (tex2DSizes[size].name)
24883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						name << "_" << tex2DSizes[size].name;
24893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					coordTypeGroup->addChild(new Texture2DMipmapCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
24913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	 name.str().c_str(), "",
24923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	 coordTypes[coordType].type,
24933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	 minFilterModes[minFilter].mode,
24943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	 wrapModes[wrapMode].mode,
24953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	 wrapModes[wrapMode].mode,
24963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	 GL_RGBA, GL_UNSIGNED_BYTE,
24973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	 tex2DSizes[size].width, tex2DSizes[size].height));
24983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
24993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
25003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
25013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
25023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// 2D bias variants.
25043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
25053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* biasGroup = new tcu::TestCaseGroup(m_testCtx, "bias", "User-supplied bias value");
25063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		group2D->addChild(biasGroup);
25073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
25093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			biasGroup->addChild(new Texture2DMipmapCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
25103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														minFilterModes[minFilter].name, "",
25113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														COORDTYPE_BASIC_BIAS,
25123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														minFilterModes[minFilter].mode,
25133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														GL_REPEAT, GL_REPEAT,
25143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														GL_RGBA, GL_UNSIGNED_BYTE,
25153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														tex2DSizes[0].width, tex2DSizes[0].height));
25163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
25173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// 2D mipmap generation variants.
25193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
25203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* genMipmapGroup = new tcu::TestCaseGroup(m_testCtx, "generate", "Mipmap generation tests");
25213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		group2D->addChild(genMipmapGroup);
25223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int format = 0; format < DE_LENGTH_OF_ARRAY(formats); format++)
25243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
25253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int size = 0; size < DE_LENGTH_OF_ARRAY(tex2DSizes); size++)
25263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
25273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int hint = 0; hint < DE_LENGTH_OF_ARRAY(genHints); hint++)
25283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
25293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					std::ostringstream name;
25303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					name << formats[format].name;
25313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (tex2DSizes[size].name)
25333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						name << "_" << tex2DSizes[size].name;
25343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					name << "_" << genHints[hint].name;
25363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					genMipmapGroup->addChild(new Texture2DGenMipmapCase(m_testCtx, m_context.getRenderContext(), name.str().c_str(), "",
25383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		formats[format].format, formats[format].dataType, genHints[hint].hint,
25393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		tex2DSizes[size].width, tex2DSizes[size].height));
25403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
25413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
25423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
25433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
25443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// 2D LOD controls.
25463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
25473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// MIN_LOD
25483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* minLodGroup = new tcu::TestCaseGroup(m_testCtx, "min_lod", "Lod control: min lod");
25493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		group2D->addChild(minLodGroup);
25503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
25523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			minLodGroup->addChild(new Texture2DMinLodCase(m_context, minFilterModes[minFilter].name, "", minFilterModes[minFilter].mode));
25533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// MAX_LOD
25553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* maxLodGroup = new tcu::TestCaseGroup(m_testCtx, "max_lod", "Lod control: max lod");
25563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		group2D->addChild(maxLodGroup);
25573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
25593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			maxLodGroup->addChild(new Texture2DMaxLodCase(m_context, minFilterModes[minFilter].name, "", minFilterModes[minFilter].mode));
25603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// BASE_LEVEL
25623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* baseLevelGroup = new tcu::TestCaseGroup(m_testCtx, "base_level", "Base level");
25633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		group2D->addChild(baseLevelGroup);
25643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
25663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			baseLevelGroup->addChild(new Texture2DBaseLevelCase(m_context, minFilterModes[minFilter].name, "", minFilterModes[minFilter].mode));
25673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// MAX_LEVEL
25693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* maxLevelGroup = new tcu::TestCaseGroup(m_testCtx, "max_level", "Max level");
25703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		group2D->addChild(maxLevelGroup);
25713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
25733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			maxLevelGroup->addChild(new Texture2DMaxLevelCase(m_context, minFilterModes[minFilter].name, "", minFilterModes[minFilter].mode));
25743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
25753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Cubemap cases.
25773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int coordType = 0; coordType < DE_LENGTH_OF_ARRAY(cubeCoordTypes); coordType++)
25783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
25793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* coordTypeGroup = new tcu::TestCaseGroup(m_testCtx, cubeCoordTypes[coordType].name, cubeCoordTypes[coordType].desc);
25803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		groupCube->addChild(coordTypeGroup);
25813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
25833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
25843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			coordTypeGroup->addChild(new TextureCubeMipmapCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
25853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															   minFilterModes[minFilter].name, "",
25863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															   cubeCoordTypes[coordType].type,
25873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															   minFilterModes[minFilter].mode,
25883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															   GL_CLAMP_TO_EDGE,
25893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															   GL_CLAMP_TO_EDGE,
25903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															   GL_RGBA, GL_UNSIGNED_BYTE, cubeMapSize));
25913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
25923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
25933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Cubemap mipmap generation variants.
25953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
25963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* genMipmapGroup = new tcu::TestCaseGroup(m_testCtx, "generate", "Mipmap generation tests");
25973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		groupCube->addChild(genMipmapGroup);
25983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int format = 0; format < DE_LENGTH_OF_ARRAY(formats); format++)
26003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
26013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int hint = 0; hint < DE_LENGTH_OF_ARRAY(genHints); hint++)
26023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
26033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				std::ostringstream name;
26043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				name << formats[format].name
26053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 << "_" << genHints[hint].name;
26063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				genMipmapGroup->addChild(new TextureCubeGenMipmapCase(m_testCtx, m_context.getRenderContext(), name.str().c_str(), "", formats[format].format, formats[format].dataType, genHints[hint].hint, cubeMapSize));
26083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
26093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
26103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
26113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Cubemap LOD controls.
26133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
26143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// MIN_LOD
26153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* minLodGroup = new tcu::TestCaseGroup(m_testCtx, "min_lod", "Lod control: min lod");
26163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		groupCube->addChild(minLodGroup);
26173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
26193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			minLodGroup->addChild(new TextureCubeMinLodCase(m_context, minFilterModes[minFilter].name, "", minFilterModes[minFilter].mode));
26203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// MAX_LOD
26223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* maxLodGroup = new tcu::TestCaseGroup(m_testCtx, "max_lod", "Lod control: max lod");
26233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		groupCube->addChild(maxLodGroup);
26243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
26263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			maxLodGroup->addChild(new TextureCubeMaxLodCase(m_context, minFilterModes[minFilter].name, "", minFilterModes[minFilter].mode));
26273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// BASE_LEVEL
26293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* baseLevelGroup = new tcu::TestCaseGroup(m_testCtx, "base_level", "Base level");
26303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		groupCube->addChild(baseLevelGroup);
26313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
26333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			baseLevelGroup->addChild(new TextureCubeBaseLevelCase(m_context, minFilterModes[minFilter].name, "", minFilterModes[minFilter].mode));
26343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// MAX_LEVEL
26363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* maxLevelGroup = new tcu::TestCaseGroup(m_testCtx, "max_level", "Max level");
26373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		groupCube->addChild(maxLevelGroup);
26383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
26403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			maxLevelGroup->addChild(new TextureCubeMaxLevelCase(m_context, minFilterModes[minFilter].name, "", minFilterModes[minFilter].mode));
26413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
26423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// 3D cases.
26443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int coordType = 0; coordType < DE_LENGTH_OF_ARRAY(coordTypes); coordType++)
26453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
26463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* coordTypeGroup = new tcu::TestCaseGroup(m_testCtx, coordTypes[coordType].name, coordTypes[coordType].desc);
26473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		group3D->addChild(coordTypeGroup);
26483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
26503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
26513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int wrapMode = 0; wrapMode < DE_LENGTH_OF_ARRAY(wrapModes); wrapMode++)
26523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
26533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// Add other size variants to basic cases only.
26543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int sizeEnd = coordTypes[coordType].type == COORDTYPE_BASIC ? DE_LENGTH_OF_ARRAY(tex3DSizes) : 1;
26553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int size = 0; size < sizeEnd; size++)
26573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
26583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					std::ostringstream name;
26593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					name << minFilterModes[minFilter].name
26603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						 << "_" << wrapModes[wrapMode].name;
26613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (tex3DSizes[size].name)
26633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						name << "_" << tex3DSizes[size].name;
26643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					coordTypeGroup->addChild(new Texture3DMipmapCase(m_context,
26663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	 name.str().c_str(), "",
26673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	 coordTypes[coordType].type,
26683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	 minFilterModes[minFilter].mode,
26693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	 wrapModes[wrapMode].mode,
26703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	 wrapModes[wrapMode].mode,
26713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	 wrapModes[wrapMode].mode,
26723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	 GL_RGBA8,
26733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	 tex3DSizes[size].width, tex3DSizes[size].height, tex3DSizes[size].depth));
26743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
26753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
26763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
26773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
26783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// 3D bias variants.
26803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
26813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* biasGroup = new tcu::TestCaseGroup(m_testCtx, "bias", "User-supplied bias value");
26823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		group3D->addChild(biasGroup);
26833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
26853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			biasGroup->addChild(new Texture3DMipmapCase(m_context,
26863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														minFilterModes[minFilter].name, "",
26873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														COORDTYPE_BASIC_BIAS,
26883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														minFilterModes[minFilter].mode,
26893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														GL_REPEAT, GL_REPEAT, GL_REPEAT,
26903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														GL_RGBA8,
26913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														tex3DSizes[0].width, tex3DSizes[0].height, tex3DSizes[0].depth));
26923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
26933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// 3D LOD controls.
26953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
26963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// MIN_LOD
26973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* minLodGroup = new tcu::TestCaseGroup(m_testCtx, "min_lod", "Lod control: min lod");
26983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		group3D->addChild(minLodGroup);
26993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
27013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			minLodGroup->addChild(new Texture3DMinLodCase(m_context, minFilterModes[minFilter].name, "", minFilterModes[minFilter].mode));
27023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// MAX_LOD
27043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* maxLodGroup = new tcu::TestCaseGroup(m_testCtx, "max_lod", "Lod control: max lod");
27053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		group3D->addChild(maxLodGroup);
27063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
27083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			maxLodGroup->addChild(new Texture3DMaxLodCase(m_context, minFilterModes[minFilter].name, "", minFilterModes[minFilter].mode));
27093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// BASE_LEVEL
27113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* baseLevelGroup = new tcu::TestCaseGroup(m_testCtx, "base_level", "Base level");
27123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		group3D->addChild(baseLevelGroup);
27133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
27153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			baseLevelGroup->addChild(new Texture3DBaseLevelCase(m_context, minFilterModes[minFilter].name, "", minFilterModes[minFilter].mode));
27163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// MAX_LEVEL
27183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* maxLevelGroup = new tcu::TestCaseGroup(m_testCtx, "max_level", "Max level");
27193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		group3D->addChild(maxLevelGroup);
27203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
27223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			maxLevelGroup->addChild(new Texture3DMaxLevelCase(m_context, minFilterModes[minFilter].name, "", minFilterModes[minFilter].mode));
27233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
27243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Functional
27273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles3
27283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp
2729