181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org/*-------------------------------------------------------------------------
281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org * drawElements Quality Program OpenGL ES 3.0 Module
381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org * -------------------------------------------------
481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org *
581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org * Copyright 2014 The Android Open Source Project
681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org *
781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org * Licensed under the Apache License, Version 2.0 (the "License");
881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org * you may not use this file except in compliance with the License.
981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org * You may obtain a copy of the License at
1081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org *
1181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org *      http://www.apache.org/licenses/LICENSE-2.0
1281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org *
1381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org * Unless required by applicable law or agreed to in writing, software
1481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org * distributed under the License is distributed on an "AS IS" BASIS,
1581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org * See the License for the specific language governing permissions and
1781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org * limitations under the License.
1881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org *
1981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org *//*!
2081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org * \file
2181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org * \brief Texture filtering accuracy tests.
2281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org *//*--------------------------------------------------------------------*/
2381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
2481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org#include "es3aTextureFilteringTests.hpp"
2581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org#include "glsTextureTestUtil.hpp"
2681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org#include "gluPixelTransfer.hpp"
2781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org#include "gluTexture.hpp"
2881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org#include "gluTextureUtil.hpp"
2981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org#include "tcuTextureUtil.hpp"
3081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org#include "tcuImageCompare.hpp"
3181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org#include "deStringUtil.hpp"
3281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org#include "deString.h"
3381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
3481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org#include "glwFunctions.hpp"
3581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org#include "glwEnums.hpp"
3681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
3781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgnamespace deqp
3881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org{
3981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgnamespace gles3
4081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org{
4181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgnamespace Accuracy
4281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org{
4381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
4481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgusing std::vector;
4581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgusing std::string;
4681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgusing tcu::TestLog;
4781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgusing namespace gls::TextureTestUtil;
4881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
49c3836fd58fdfa6f8bb2c70e40e6aaf11dfaa76d5sgk@chromium.orgclass Texture2DFilteringCase : public tcu::TestCase
50c3836fd58fdfa6f8bb2c70e40e6aaf11dfaa76d5sgk@chromium.org{
5181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgpublic:
5281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org								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 internalFormat, int width, int height);
5381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org								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);
5481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org								~Texture2DFilteringCase		(void);
5581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
5681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	void						init						(void);
5781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	void						deinit						(void);
5881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	IterateResult				iterate						(void);
5981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
6081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgprivate:
6181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org								Texture2DFilteringCase		(const Texture2DFilteringCase& other);
6281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	Texture2DFilteringCase&		operator=					(const Texture2DFilteringCase& other);
6381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
6481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	glu::RenderContext&			m_renderCtx;
6581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	const glu::ContextInfo&		m_renderCtxInfo;
6681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
6781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	deUint32					m_minFilter;
6881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	deUint32					m_magFilter;
6981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	deUint32					m_wrapS;
7081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	deUint32					m_wrapT;
7181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
7281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	deUint32					m_internalFormat;
7381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	int							m_width;
7481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	int							m_height;
75c3836fd58fdfa6f8bb2c70e40e6aaf11dfaa76d5sgk@chromium.org
7681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	std::vector<std::string>	m_filenames;
7781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
7881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	std::vector<glu::Texture2D*>	m_textures;
7981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	TextureRenderer					m_renderer;
8081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org};
8181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
8281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgTexture2DFilteringCase::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 internalFormat, int width, int height)
8381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	: TestCase			(testCtx, tcu::NODETYPE_ACCURACY, name, desc)
8481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	, m_renderCtx		(renderCtx)
8581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	, m_renderCtxInfo	(ctxInfo)
8681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	, m_minFilter		(minFilter)
8781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	, m_magFilter		(magFilter)
8881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	, m_wrapS			(wrapS)
8981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	, m_wrapT			(wrapT)
9081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	, m_internalFormat	(internalFormat)
9181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	, m_width			(width)
92c3836fd58fdfa6f8bb2c70e40e6aaf11dfaa76d5sgk@chromium.org	, m_height			(height)
93c3836fd58fdfa6f8bb2c70e40e6aaf11dfaa76d5sgk@chromium.org	, m_renderer		(renderCtx, testCtx, glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
9481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org{
9581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org}
9681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
9781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgTexture2DFilteringCase::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)
9881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	: TestCase			(testCtx, tcu::NODETYPE_ACCURACY, name, desc)
9981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	, m_renderCtx		(renderCtx)
10081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	, m_renderCtxInfo	(ctxInfo)
10181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	, m_minFilter		(minFilter)
10281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	, m_magFilter		(magFilter)
10381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	, m_wrapS			(wrapS)
10481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	, m_wrapT			(wrapT)
10581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	, m_internalFormat	(GL_NONE)
10681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	, m_width			(0)
10781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	, m_height			(0)
10881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	, m_filenames		(filenames)
10981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	, m_renderer		(renderCtx, testCtx, glu::GLSL_VERSION_100_ES, glu::PRECISION_HIGHP)
11081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org{
11181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org}
11281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
11381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgTexture2DFilteringCase::~Texture2DFilteringCase (void)
11481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org{
11581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	deinit();
11681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org}
11781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
11881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgvoid Texture2DFilteringCase::init (void)
11981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org{
12081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	try
12181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	{
12281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		if (!m_filenames.empty())
12381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		{
12481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			m_textures.reserve(1);
12581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			m_textures.push_back(glu::Texture2D::create(m_renderCtx, m_renderCtxInfo, m_testCtx.getArchive(), (int)m_filenames.size(), m_filenames));
12681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		}
12781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		else
12881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		{
12981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			// Create 2 textures.
13081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			m_textures.reserve(2);
13181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			for (int ndx = 0; ndx < 2; ndx++)
13281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org				m_textures.push_back(new glu::Texture2D(m_renderCtx, m_internalFormat, m_width, m_height));
13381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
13481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			const int				numLevels	= deLog2Floor32(de::max(m_width, m_height))+1;
13581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			tcu::TextureFormatInfo	fmtInfo		= tcu::getTextureFormatInfo(m_textures[0]->getRefTexture().getFormat());
13681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			tcu::Vec4				cBias		= fmtInfo.valueMin;
13781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			tcu::Vec4				cScale		= fmtInfo.valueMax-fmtInfo.valueMin;
13881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
13981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			// Fill first gradient texture.
14081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
14181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			{
14281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org				tcu::Vec4 gMin = tcu::Vec4(-0.5f, -0.5f, -0.5f, 2.0f)*cScale + cBias;
14381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org				tcu::Vec4 gMax = tcu::Vec4( 1.0f,  1.0f,  1.0f, 0.0f)*cScale + cBias;
14481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
14581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org				m_textures[0]->getRefTexture().allocLevel(levelNdx);
14681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org				tcu::fillWithComponentGradients(m_textures[0]->getRefTexture().getLevel(levelNdx), gMin, gMax);
14781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			}
14881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
14981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			// Fill second with grid texture.
15081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
15181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			{
15281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org				deUint32	step	= 0x00ffffff / numLevels;
15381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org				deUint32	rgb		= step*levelNdx;
15481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org				deUint32	colorA	= 0xff000000 | rgb;
15581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org				deUint32	colorB	= 0xff000000 | ~rgb;
15681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
15781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org				m_textures[1]->getRefTexture().allocLevel(levelNdx);
15881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org				tcu::fillWithGrid(m_textures[1]->getRefTexture().getLevel(levelNdx), 4, toVec4(tcu::RGBA(colorA))*cScale + cBias, toVec4(tcu::RGBA(colorB))*cScale + cBias);
15981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			}
16081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
16181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			// Upload.
16281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			for (std::vector<glu::Texture2D*>::iterator i = m_textures.begin(); i != m_textures.end(); i++)
16381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org				(*i)->upload();
16481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		}
16581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	}
16681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	catch (...)
16781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	{
16881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		// Clean up to save memory.
16981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		Texture2DFilteringCase::deinit();
17081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		throw;
17181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	}
17281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org}
17381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
17481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgvoid Texture2DFilteringCase::deinit (void)
17581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org{
17681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	for (std::vector<glu::Texture2D*>::iterator i = m_textures.begin(); i != m_textures.end(); i++)
17781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		delete *i;
17881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	m_textures.clear();
17981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
18081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	m_renderer.clear();
18181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org}
18281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
18381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgTexture2DFilteringCase::IterateResult Texture2DFilteringCase::iterate (void)
18481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org{
18581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	const glw::Functions&		gl					= m_renderCtx.getFunctions();
18681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	TestLog&					log					= m_testCtx.getLog();
18781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	const int					defViewportWidth	= 256;
18881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	const int					defViewportHeight	= 256;
18981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	RandomViewport				viewport			(m_renderCtx.getRenderTarget(), defViewportWidth, defViewportHeight, deStringHash(getName()));
19081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	tcu::Surface				renderedFrame		(viewport.width, viewport.height);
19181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	tcu::Surface				referenceFrame		(viewport.width, viewport.height);
192ca50e4158e519b054520ed2a897503a991889a94thakis@chromium.org	const tcu::TextureFormat&	texFmt				= m_textures[0]->getRefTexture().getFormat();
193ca50e4158e519b054520ed2a897503a991889a94thakis@chromium.org	tcu::TextureFormatInfo		fmtInfo				= tcu::getTextureFormatInfo(texFmt);
194ca50e4158e519b054520ed2a897503a991889a94thakis@chromium.org	ReferenceParams				refParams			(TEXTURETYPE_2D);
195ca50e4158e519b054520ed2a897503a991889a94thakis@chromium.org	vector<float>				texCoord;
196ca50e4158e519b054520ed2a897503a991889a94thakis@chromium.org
197ca50e4158e519b054520ed2a897503a991889a94thakis@chromium.org	// Accuracy measurements are off unless viewport size is 256x256
198ca50e4158e519b054520ed2a897503a991889a94thakis@chromium.org	if (viewport.width < defViewportWidth || viewport.height < defViewportHeight)
19981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		throw tcu::NotSupportedError("Too small viewport", "", __FILE__, __LINE__);
20054d2f6fe6d8a7b9d9786bd1f8540df6b4f46b83fsbc@chromium.org
201ca50e4158e519b054520ed2a897503a991889a94thakis@chromium.org	// Viewport is divided into 4 sections.
202ca50e4158e519b054520ed2a897503a991889a94thakis@chromium.org	int				leftWidth			= viewport.width / 2;
20381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	int				rightWidth			= viewport.width - leftWidth;
20481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	int				bottomHeight		= viewport.height / 2;
20581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	int				topHeight			= viewport.height - bottomHeight;
20681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
20781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	int				curTexNdx			= 0;
20881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
20981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	// Use unit 0.
21081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	gl.activeTexture(GL_TEXTURE0);
21181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
21281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	// Bind gradient texture and setup sampler parameters.
21381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	gl.bindTexture(GL_TEXTURE_2D, m_textures[curTexNdx]->getGLTexture());
21481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		m_wrapS);
21581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		m_wrapT);
21681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	m_minFilter);
21781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	m_magFilter);
21881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
21981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	// Setup params for reference.
22081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	refParams.sampler		= glu::mapGLSampler(m_wrapS, m_wrapT, m_minFilter, m_magFilter);
22181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	refParams.samplerType	= getSamplerType(texFmt);
22281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	refParams.lodMode		= LODMODE_EXACT;
22381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	refParams.colorBias		= fmtInfo.lookupBias;
22481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	refParams.colorScale	= fmtInfo.lookupScale;
22581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
22681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	// Bottom left: Minification
22781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	{
22881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		gl.viewport(viewport.x, viewport.y, leftWidth, bottomHeight);
22981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
23081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		computeQuadTexCoord2D(texCoord, tcu::Vec2(-4.0f, -4.5f), tcu::Vec2(4.0f, 2.5f));
23181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
23281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		m_renderer.renderQuad(0, &texCoord[0], refParams);
23381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		sampleTexture(SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat(), 0, 0, leftWidth, bottomHeight),
23481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org					  m_textures[curTexNdx]->getRefTexture(), &texCoord[0], refParams);
23581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	}
23681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
23781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	// Bottom right: Magnification
23881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	{
23981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		gl.viewport(viewport.x+leftWidth, viewport.y, rightWidth, bottomHeight);
24081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
24181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		computeQuadTexCoord2D(texCoord, tcu::Vec2(-0.5f, 0.75f), tcu::Vec2(0.25f, 1.25f));
24281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
24381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		m_renderer.renderQuad(0, &texCoord[0], refParams);
24481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		sampleTexture(SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat(), leftWidth, 0, rightWidth, bottomHeight),
24581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org					  m_textures[curTexNdx]->getRefTexture(), &texCoord[0], refParams);
24681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	}
24781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
24881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	if (m_textures.size() >= 2)
24981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	{
25081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		curTexNdx += 1;
25181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
25281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		// Setup second texture.
25381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		gl.bindTexture(GL_TEXTURE_2D, m_textures[curTexNdx]->getGLTexture());
25481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		m_wrapS);
25581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		m_wrapT);
25681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	m_minFilter);
25781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	m_magFilter);
25881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	}
25981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
26081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	// Top left: Minification
26181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	// \note Minification is chosen so that 0.0 < lod <= 0.5. This way special minification threshold rule will be triggered.
26281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	{
26381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		gl.viewport(viewport.x, viewport.y+bottomHeight, leftWidth, topHeight);
26481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
26581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		float	sMin		= -0.5f;
26681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		float	tMin		= -0.2f;
26781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		float	sRange		= ((float)leftWidth * 1.2f) / (float)m_textures[curTexNdx]->getRefTexture().getWidth();
26881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		float	tRange		= ((float)topHeight * 1.1f) / (float)m_textures[curTexNdx]->getRefTexture().getHeight();
26981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
27081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		computeQuadTexCoord2D(texCoord, tcu::Vec2(sMin, tMin), tcu::Vec2(sMin+sRange, tMin+tRange));
27181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
27281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		m_renderer.renderQuad(0, &texCoord[0], refParams);
27381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		sampleTexture(SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat(), 0, bottomHeight, leftWidth, topHeight),
27481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org					  m_textures[curTexNdx]->getRefTexture(), &texCoord[0], refParams);
27581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	}
27681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
27781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	// Top right: Magnification
27881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	{
27981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		gl.viewport(viewport.x+leftWidth, viewport.y+bottomHeight, rightWidth, topHeight);
28081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
28181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		computeQuadTexCoord2D(texCoord, tcu::Vec2(-0.5f, 0.75f), tcu::Vec2(0.25f, 1.25f));
28281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
28381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		m_renderer.renderQuad(0, &texCoord[0], refParams);
28481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		sampleTexture(SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat(), leftWidth, bottomHeight, rightWidth, topHeight),
28581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org					  m_textures[curTexNdx]->getRefTexture(), &texCoord[0], refParams);
28681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	}
28781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
28881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	// Read result.
28981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());
29081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
29181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	// Compare and log.
29281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	{
29381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		const int	bestScoreDiff	= 16;
29481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		const int	worstScoreDiff	= 3200;
29581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
29681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		int score = measureAccuracy(log, referenceFrame, renderedFrame, bestScoreDiff, worstScoreDiff);
29781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, de::toString(score).c_str());
29881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	}
29981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
30081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	return STOP;
30181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org}
30281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
30381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgclass TextureCubeFilteringCase : public tcu::TestCase
30481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org{
30581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgpublic:
30681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org								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, bool onlySampleFaceInterior, deUint32 internalFormat, int width, int height);
30781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org								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, bool onlySampleFaceInterior, const std::vector<std::string>& filenames);
30881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org								~TextureCubeFilteringCase	(void);
30981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
31081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	void						init						(void);
31181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	void						deinit						(void);
31281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	IterateResult				iterate						(void);
31381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
31481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgprivate:
31581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org								TextureCubeFilteringCase	(const TextureCubeFilteringCase& other);
31681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	TextureCubeFilteringCase&	operator=					(const TextureCubeFilteringCase& other);
31781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
31881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	glu::RenderContext&			m_renderCtx;
31981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	const glu::ContextInfo&		m_renderCtxInfo;
32081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
32181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	deUint32					m_minFilter;
32281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	deUint32					m_magFilter;
32381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	deUint32					m_wrapS;
32481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	deUint32					m_wrapT;
32581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	bool						m_onlySampleFaceInterior; //!< If true, we avoid sampling anywhere near a face's edges.
32681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
32781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	deUint32					m_internalFormat;
32881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	int							m_width;
32981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	int							m_height;
33081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
33181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	std::vector<std::string>	m_filenames;
33281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
33381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	std::vector<glu::TextureCube*>	m_textures;
33481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	TextureRenderer					m_renderer;
33581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org};
33684f26de1771168933a19776955b0713d3b5892b1bradnelson@google.com
33784f26de1771168933a19776955b0713d3b5892b1bradnelson@google.comTextureCubeFilteringCase::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, bool onlySampleFaceInterior, deUint32 internalFormat, int width, int height)
33884f26de1771168933a19776955b0713d3b5892b1bradnelson@google.com	: TestCase					(testCtx, tcu::NODETYPE_ACCURACY, name, desc)
33984f26de1771168933a19776955b0713d3b5892b1bradnelson@google.com	, m_renderCtx				(renderCtx)
34084f26de1771168933a19776955b0713d3b5892b1bradnelson@google.com	, m_renderCtxInfo			(ctxInfo)
34184f26de1771168933a19776955b0713d3b5892b1bradnelson@google.com	, m_minFilter				(minFilter)
34284f26de1771168933a19776955b0713d3b5892b1bradnelson@google.com	, m_magFilter				(magFilter)
34384f26de1771168933a19776955b0713d3b5892b1bradnelson@google.com	, m_wrapS					(wrapS)
34484f26de1771168933a19776955b0713d3b5892b1bradnelson@google.com	, m_wrapT					(wrapT)
34584f26de1771168933a19776955b0713d3b5892b1bradnelson@google.com	, m_onlySampleFaceInterior	(onlySampleFaceInterior)
34684f26de1771168933a19776955b0713d3b5892b1bradnelson@google.com	, m_internalFormat			(internalFormat)
347c3836fd58fdfa6f8bb2c70e40e6aaf11dfaa76d5sgk@chromium.org	, m_width					(width)
34884f26de1771168933a19776955b0713d3b5892b1bradnelson@google.com	, m_height					(height)
34981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	, m_renderer				(renderCtx, testCtx, glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
35081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org{
35181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org}
35281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
35381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgTextureCubeFilteringCase::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, bool onlySampleFaceInterior, const std::vector<std::string>& filenames)
35481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	: TestCase					(testCtx, tcu::NODETYPE_ACCURACY, name, desc)
35581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	, m_renderCtx				(renderCtx)
35681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	, m_renderCtxInfo			(ctxInfo)
35781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	, m_minFilter				(minFilter)
35881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	, m_magFilter				(magFilter)
35981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	, m_wrapS					(wrapS)
36081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	, m_wrapT					(wrapT)
36181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	, m_onlySampleFaceInterior	(onlySampleFaceInterior)
36281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	, m_internalFormat			(GL_NONE)
36381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	, m_width					(0)
36481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	, m_height					(0)
36581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	, m_filenames				(filenames)
36681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	, m_renderer				(renderCtx, testCtx, glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
36781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org{
36881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org}
36981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
37081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgTextureCubeFilteringCase::~TextureCubeFilteringCase (void)
37181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org{
37281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	deinit();
37381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org}
37481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
37581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgvoid TextureCubeFilteringCase::init (void)
37681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org{
37781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	try
37881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	{
37981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		if (!m_filenames.empty())
38081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		{
38181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			m_textures.reserve(1);
38281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			m_textures.push_back(glu::TextureCube::create(m_renderCtx, m_renderCtxInfo, m_testCtx.getArchive(), (int)m_filenames.size() / 6, m_filenames));
38381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		}
38481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		else
38581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		{
38681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			m_textures.reserve(2);
38781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			DE_ASSERT(m_width == m_height);
38881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			for (int ndx = 0; ndx < 2; ndx++)
38981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org				m_textures.push_back(new glu::TextureCube(m_renderCtx, m_internalFormat, m_width));
39081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
39181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			const int				numLevels	= deLog2Floor32(de::max(m_width, m_height))+1;
39281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			tcu::TextureFormatInfo	fmtInfo		= tcu::getTextureFormatInfo(m_textures[0]->getRefTexture().getFormat());
39381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			tcu::Vec4				cBias		= fmtInfo.valueMin;
39481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			tcu::Vec4				cScale		= fmtInfo.valueMax-fmtInfo.valueMin;
39581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
39681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			// Fill first with gradient texture.
39781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			static const tcu::Vec4 gradients[tcu::CUBEFACE_LAST][2] =
39881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			{
39981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org				{ tcu::Vec4(-1.0f, -1.0f, -1.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // negative x
40081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org				{ tcu::Vec4( 0.0f, -1.0f, -1.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // positive x
40181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org				{ tcu::Vec4(-1.0f,  0.0f, -1.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // negative y
40281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org				{ tcu::Vec4(-1.0f, -1.0f,  0.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // positive y
40381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org				{ tcu::Vec4(-1.0f, -1.0f, -1.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f) }, // negative z
40481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org				{ tcu::Vec4( 0.0f,  0.0f,  0.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }  // positive z
40581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			};
40681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
40781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			{
40881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org				for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
40981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org				{
41081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org					m_textures[0]->getRefTexture().allocLevel((tcu::CubeFace)face, levelNdx);
41181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org					tcu::fillWithComponentGradients(m_textures[0]->getRefTexture().getLevelFace(levelNdx, (tcu::CubeFace)face), gradients[face][0]*cScale + cBias, gradients[face][1]*cScale + cBias);
41281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org				}
41381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			}
41481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
41581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			// Fill second with grid texture.
41681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
41781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			{
41881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org				for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
41981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org				{
42081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org					deUint32	step	= 0x00ffffff / (numLevels*tcu::CUBEFACE_LAST);
42181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org					deUint32	rgb		= step*levelNdx*face;
42281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org					deUint32	colorA	= 0xff000000 | rgb;
42381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org					deUint32	colorB	= 0xff000000 | ~rgb;
42481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
42581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org					m_textures[1]->getRefTexture().allocLevel((tcu::CubeFace)face, levelNdx);
42681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org					tcu::fillWithGrid(m_textures[1]->getRefTexture().getLevelFace(levelNdx, (tcu::CubeFace)face), 4, toVec4(tcu::RGBA(colorA))*cScale + cBias, toVec4(tcu::RGBA(colorB))*cScale + cBias);
42781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org				}
42881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			}
42981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
43081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			if (m_magFilter == GL_LINEAR || m_minFilter == GL_LINEAR || m_minFilter == GL_LINEAR_MIPMAP_NEAREST || m_minFilter == GL_LINEAR_MIPMAP_LINEAR)
43181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			{
43281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org				// Using seamless linear cube map filtering - set all corner texels to the same color, because cube corner sampling in this case is not very well defined by the spec.
43381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org				// \todo Probably should also do this for cases where textures are loaded from files.
43481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
43581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org				for (int texNdx = 0; texNdx < (int)m_textures.size(); texNdx++)
43681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org				{
43781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org					for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
43881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org					{
43981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org						for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
44081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org						{
44181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org							static const tcu::Vec4 color(0.0f, 0.0f, 0.0f, 1.0f);
44281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org							tcu::PixelBufferAccess access = m_textures[texNdx]->getRefTexture().getLevelFace(levelNdx, (tcu::CubeFace)face);
44381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
44481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org							access.setPixel(color, 0,					0);
44581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org							access.setPixel(color, access.getWidth()-1,	0);
4463afe3277af466c60b6d35a56f578c09a4c5f4c98sbc@chromium.org							access.setPixel(color, 0,					access.getHeight()-1);
4473afe3277af466c60b6d35a56f578c09a4c5f4c98sbc@chromium.org							access.setPixel(color, access.getWidth()-1,	access.getHeight()-1);
4483afe3277af466c60b6d35a56f578c09a4c5f4c98sbc@chromium.org						}
4493afe3277af466c60b6d35a56f578c09a4c5f4c98sbc@chromium.org					}
4503afe3277af466c60b6d35a56f578c09a4c5f4c98sbc@chromium.org				}
4513afe3277af466c60b6d35a56f578c09a4c5f4c98sbc@chromium.org			}
4523afe3277af466c60b6d35a56f578c09a4c5f4c98sbc@chromium.org
45381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			// Upload.
45481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			for (std::vector<glu::TextureCube*>::iterator i = m_textures.begin(); i != m_textures.end(); i++)
45581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org				(*i)->upload();
45681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		}
45781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	}
45881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	catch (const std::exception&)
45981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	{
46081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		// Clean up to save memory.
46181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		TextureCubeFilteringCase::deinit();
46281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		throw;
46381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	}
46481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org}
46581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
46681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgvoid TextureCubeFilteringCase::deinit (void)
46781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org{
46881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	for (std::vector<glu::TextureCube*>::iterator i = m_textures.begin(); i != m_textures.end(); i++)
46981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		delete *i;
47081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	m_textures.clear();
47181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
47281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	m_renderer.clear();
47381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org}
47481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
47581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgstatic void renderFaces (
47681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	const glw::Functions&		gl,
47781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	const SurfaceAccess&		dstRef,
47881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	const tcu::TextureCube&		refTexture,
47981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	const ReferenceParams&			params,
48081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	TextureRenderer&			renderer,
48181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	int							x,
48281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	int							y,
48381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	int							width,
48481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	int							height,
48581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	const tcu::Vec2&			bottomLeft,
48681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	const tcu::Vec2&			topRight,
48781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	const tcu::Vec2&			texCoordTopRightFactor,
48881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	bool						multiFace)
48981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org{
49081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	DE_ASSERT(width == dstRef.getWidth() && height == dstRef.getHeight());
49181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
49281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	vector<float> texCoord;
49381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
49481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	DE_STATIC_ASSERT(tcu::CUBEFACE_LAST == 6);
49581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
49681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	{
49781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		bool	isRightmost		= (face == 2) || (face == 5);
49881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		bool	isTop			= face >= 3;
49981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		int		curX			= (face % 3) * (width  / 3);
50081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		int		curY			= (face / 3) * (height / 2);
50181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		int		curW			= isRightmost	? (width-curX)	: (width	/ 3);
50281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		int		curH			= isTop			? (height-curY)	: (height	/ 2);
50381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
50481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		computeQuadTexCoordCube(texCoord, (tcu::CubeFace)face, bottomLeft, topRight);
50581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
50681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		{
50781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			// Move the top and right edges of the texture coord quad. This is useful when we want a cube edge visible.
50881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			int texCoordSRow = face == tcu::CUBEFACE_NEGATIVE_X || face == tcu::CUBEFACE_POSITIVE_X ? 2 : 0;
50981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			int texCoordTRow = face == tcu::CUBEFACE_NEGATIVE_Y || face == tcu::CUBEFACE_POSITIVE_Y ? 2 : 1;
51081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			texCoord[6 + texCoordSRow] *= texCoordTopRightFactor.x();
51181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			texCoord[9 + texCoordSRow] *= texCoordTopRightFactor.x();
51281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			texCoord[3 + texCoordTRow] *= texCoordTopRightFactor.y();
51381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			texCoord[9 + texCoordTRow] *= texCoordTopRightFactor.y();
51481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		}
51581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
51681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		gl.viewport(x+curX, y+curY, curW, curH);
51781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
51881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		renderer.renderQuad(0, &texCoord[0], params);
51981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
52081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		if (multiFace)
52181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			sampleTextureMultiFace(SurfaceAccess(dstRef, curX, curY, curW, curH), refTexture, &texCoord[0], params);
52281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		else
52381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org			sampleTexture(SurfaceAccess(dstRef, curX, curY, curW, curH), refTexture, &texCoord[0], params);
52481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	}
52581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
52681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	GLU_EXPECT_NO_ERROR(gl.getError(), "Post render");
52781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org}
52881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
5293afe3277af466c60b6d35a56f578c09a4c5f4c98sbc@chromium.orgTextureCubeFilteringCase::IterateResult TextureCubeFilteringCase::iterate (void)
53081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org{
53181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	const glw::Functions&		gl					= m_renderCtx.getFunctions();
53281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	TestLog&					log					= m_testCtx.getLog();
53381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	const int					cellSize			= 28;
53481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	const int					defViewportWidth	= cellSize*6;
53581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	const int					defViewportHeight	= cellSize*4;
53681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	RandomViewport				viewport			(m_renderCtx.getRenderTarget(), cellSize*6, cellSize*4, deStringHash(getName()));
53781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	tcu::Surface				renderedFrame		(viewport.width, viewport.height);
53881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	tcu::Surface				referenceFrame		(viewport.width, viewport.height);
53981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	ReferenceParams				sampleParams		(TEXTURETYPE_CUBE);
54081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	const tcu::TextureFormat&	texFmt				= m_textures[0]->getRefTexture().getFormat();
54181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	tcu::TextureFormatInfo		fmtInfo				= tcu::getTextureFormatInfo(texFmt);
54281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
54381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	// Accuracy measurements are off unless viewport size is exactly as expected.
54481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	if (m_nodeType == tcu::NODETYPE_ACCURACY && (viewport.width < defViewportWidth || viewport.height < defViewportHeight))
54581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org		throw tcu::NotSupportedError("Too small viewport", "", __FILE__, __LINE__);
54681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
54781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	// Viewport is divided into 4 sections.
54881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	int				leftWidth			= viewport.width / 2;
54981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	int				rightWidth			= viewport.width - leftWidth;
55081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	int				bottomHeight		= viewport.height / 2;
55181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	int				topHeight			= viewport.height - bottomHeight;
55281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
55381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	int				curTexNdx			= 0;
55481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
55581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	// Sampling parameters.
55681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	sampleParams.sampler					= glu::mapGLSampler(m_wrapS, m_wrapT, m_minFilter, m_magFilter);
55781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	sampleParams.sampler.seamlessCubeMap	= true;
55881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	sampleParams.samplerType				= getSamplerType(texFmt);
55981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	sampleParams.colorBias					= fmtInfo.lookupBias;
56081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	sampleParams.colorScale					= fmtInfo.lookupScale;
56181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	sampleParams.lodMode					= LODMODE_EXACT;
56281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
56381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	// Use unit 0.
56481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	gl.activeTexture(GL_TEXTURE0);
56581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org
56681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	// Setup gradient texture.
56781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	gl.bindTexture(GL_TEXTURE_CUBE_MAP, m_textures[curTexNdx]->getGLTexture());
56881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,		m_wrapS);
56981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,		m_wrapT);
57081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,	m_minFilter);
571	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER,	m_magFilter);
572
573	// Bottom left: Minification
574	renderFaces(gl,
575				SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat(), 0, 0, leftWidth, bottomHeight),
576				m_textures[curTexNdx]->getRefTexture(), sampleParams,
577				m_renderer,
578				viewport.x, viewport.y, leftWidth, bottomHeight,
579				m_onlySampleFaceInterior ? tcu::Vec2(-0.81f, -0.81f) : tcu::Vec2(-0.975f, -0.975f),
580				m_onlySampleFaceInterior ? tcu::Vec2( 0.8f,  0.8f) : tcu::Vec2( 0.975f,  0.975f),
581				!m_onlySampleFaceInterior ? tcu::Vec2(1.3f, 1.25f) : tcu::Vec2(1.0f, 1.0f),
582				!m_onlySampleFaceInterior);
583
584	// Bottom right: Magnification
585	renderFaces(gl,
586				SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat(), leftWidth, 0, rightWidth, bottomHeight),
587				m_textures[curTexNdx]->getRefTexture(), sampleParams,
588				m_renderer,
589				viewport.x+leftWidth, viewport.y, rightWidth, bottomHeight,
590				tcu::Vec2(0.5f, 0.65f), m_onlySampleFaceInterior ? tcu::Vec2(0.8f, 0.8f) : tcu::Vec2(0.975f, 0.975f),
591				!m_onlySampleFaceInterior ? tcu::Vec2(1.1f, 1.06f) : tcu::Vec2(1.0f, 1.0f),
592				!m_onlySampleFaceInterior);
593
594	if (m_textures.size() >= 2)
595	{
596		curTexNdx += 1;
597
598		// Setup second texture.
599		gl.bindTexture(GL_TEXTURE_CUBE_MAP, m_textures[curTexNdx]->getGLTexture());
600		gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,		m_wrapS);
601		gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,		m_wrapT);
602		gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,	m_minFilter);
603		gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER,	m_magFilter);
604	}
605
606	// Top left: Minification
607	renderFaces(gl,
608				SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat(), 0, bottomHeight, leftWidth, topHeight),
609				m_textures[curTexNdx]->getRefTexture(), sampleParams,
610				m_renderer,
611				viewport.x, viewport.y+bottomHeight, leftWidth, topHeight,
612				m_onlySampleFaceInterior ? tcu::Vec2(-0.81f, -0.81f) : tcu::Vec2(-0.975f, -0.975f),
613				m_onlySampleFaceInterior ? tcu::Vec2( 0.8f,  0.8f) : tcu::Vec2( 0.975f,  0.975f),
614				!m_onlySampleFaceInterior ? tcu::Vec2(1.3f, 1.25f) : tcu::Vec2(1.0f, 1.0f),
615				!m_onlySampleFaceInterior);
616
617	// Top right: Magnification
618	renderFaces(gl,
619				SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat(), leftWidth, bottomHeight, rightWidth, topHeight),
620				m_textures[curTexNdx]->getRefTexture(), sampleParams,
621				m_renderer,
622				viewport.x+leftWidth, viewport.y+bottomHeight, rightWidth, topHeight,
623				tcu::Vec2(0.5f, -0.65f), m_onlySampleFaceInterior ? tcu::Vec2(0.8f, -0.8f) : tcu::Vec2(0.975f, -0.975f),
624				!m_onlySampleFaceInterior ? tcu::Vec2(1.1f, 1.06f) : tcu::Vec2(1.0f, 1.0f),
625				!m_onlySampleFaceInterior);
626
627	// Read result.
628	glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());
629
630	// Compare and log.
631	{
632		const int	bestScoreDiff	= 16;
633		const int	worstScoreDiff	= 10000;
634
635		int score = measureAccuracy(log, referenceFrame, renderedFrame, bestScoreDiff, worstScoreDiff);
636		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, de::toString(score).c_str());
637	}
638
639	return STOP;
640}
641
642TextureFilteringTests::TextureFilteringTests (Context& context)
643	: TestCaseGroup(context, "filter", "Texture Filtering Accuracy Tests")
644{
645}
646
647TextureFilteringTests::~TextureFilteringTests (void)
648{
649}
650
651void TextureFilteringTests::init (void)
652{
653	tcu::TestCaseGroup* group2D		= new tcu::TestCaseGroup(m_testCtx, "2d",	"2D Texture Filtering");
654	tcu::TestCaseGroup*	groupCube	= new tcu::TestCaseGroup(m_testCtx, "cube",	"Cube Map Filtering");
655	addChild(group2D);
656	addChild(groupCube);
657
658	static const struct
659	{
660		const char*		name;
661		deUint32		mode;
662	} wrapModes[] =
663	{
664		{ "clamp",		GL_CLAMP_TO_EDGE },
665		{ "repeat",		GL_REPEAT },
666		{ "mirror",		GL_MIRRORED_REPEAT }
667	};
668
669	static const struct
670	{
671		const char*		name;
672		deUint32		mode;
673	} minFilterModes[] =
674	{
675		{ "nearest",				GL_NEAREST					},
676		{ "linear",					GL_LINEAR					},
677		{ "nearest_mipmap_nearest",	GL_NEAREST_MIPMAP_NEAREST	},
678		{ "linear_mipmap_nearest",	GL_LINEAR_MIPMAP_NEAREST	},
679		{ "nearest_mipmap_linear",	GL_NEAREST_MIPMAP_LINEAR	},
680		{ "linear_mipmap_linear",	GL_LINEAR_MIPMAP_LINEAR		}
681	};
682
683	static const struct
684	{
685		const char*		name;
686		deUint32		mode;
687	} magFilterModes[] =
688	{
689		{ "nearest",	GL_NEAREST },
690		{ "linear",		GL_LINEAR }
691	};
692
693	static const struct
694	{
695		const char*		name;
696		int				width;
697		int				height;
698	} sizes2D[] =
699	{
700		{ "pot",		32, 64 },
701		{ "npot",		31, 55 }
702	};
703
704	static const struct
705	{
706		const char*		name;
707		int				width;
708		int				height;
709	} sizesCube[] =
710	{
711		{ "pot",		64, 64 },
712		{ "npot",		63, 63 }
713	};
714
715	static const struct
716	{
717		const char*		name;
718		deUint32		format;
719	} formats[] =
720	{
721		{ "rgba8",		GL_RGBA8 }
722	};
723
724#define FOR_EACH(ITERATOR, ARRAY, BODY)	\
725	for (int ITERATOR = 0; ITERATOR < DE_LENGTH_OF_ARRAY(ARRAY); ITERATOR++)	\
726		BODY
727
728	// 2D cases.
729	FOR_EACH(minFilter,		minFilterModes,
730	FOR_EACH(magFilter,		magFilterModes,
731	FOR_EACH(wrapMode,		wrapModes,
732	FOR_EACH(format,		formats,
733	FOR_EACH(size,			sizes2D,
734		{
735			string name = string("") + minFilterModes[minFilter].name + "_" + magFilterModes[magFilter].name + "_" + wrapModes[wrapMode].name + "_" + formats[format].name + string("_") + sizes2D[size].name;
736
737			group2D->addChild(new Texture2DFilteringCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
738														 name.c_str(), "",
739														 minFilterModes[minFilter].mode,
740														 magFilterModes[magFilter].mode,
741														 wrapModes[wrapMode].mode,
742														 wrapModes[wrapMode].mode,
743														 formats[format].format,
744														 sizes2D[size].width, sizes2D[size].height));
745		})))));
746
747	// Cubemap cases.
748	FOR_EACH(minFilter,		minFilterModes,
749	FOR_EACH(magFilter,		magFilterModes,
750	FOR_EACH(wrapMode,		wrapModes,
751	FOR_EACH(format,		formats,
752	FOR_EACH(size,			sizesCube,
753		{
754			string name = string("") + minFilterModes[minFilter].name + "_" + magFilterModes[magFilter].name + "_" + wrapModes[wrapMode].name + "_" + formats[format].name + string("_") + sizesCube[size].name;
755
756			groupCube->addChild(new TextureCubeFilteringCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
757															 name.c_str(), "",
758															 minFilterModes[minFilter].mode,
759															 magFilterModes[magFilter].mode,
760															 wrapModes[wrapMode].mode,
761															 wrapModes[wrapMode].mode,
762															 false,
763															 formats[format].format,
764															 sizesCube[size].width, sizesCube[size].height));
765		})))));
766}
767
768} // Accuracy
769} // gles3
770} // deqp
771