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