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