13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program OpenGL ES 3.0 Module
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * -------------------------------------------------
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License.
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License.
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*!
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Shadow texture lookup tests.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es3fTextureShadowTests.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluTexture.hpp"
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluPixelTransfer.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluTextureUtil.hpp"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glsTextureTestUtil.hpp"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTextureUtil.hpp"
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuRenderTarget.hpp"
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTexCompareVerifier.hpp"
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deString.h"
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp"
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwFunctions.hpp"
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwEnums.hpp"
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gles3
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace Functional
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector;
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string;
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::TestLog;
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace deqp::gls::TextureTestUtil;
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TEX2D_VIEWPORT_WIDTH		= 64,
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TEX2D_VIEWPORT_HEIGHT		= 64,
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TEX2D_MIN_VIEWPORT_WIDTH	= 64,
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TEX2D_MIN_VIEWPORT_HEIGHT	= 64
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isFloatingPointDepthFormat (const tcu::TextureFormat& format)
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Only two depth and depth-stencil formats are floating point
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return	(format.order == tcu::TextureFormat::D && format.type == tcu::TextureFormat::FLOAT) ||
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			(format.order == tcu::TextureFormat::DS && format.type == tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV);
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void clampFloatingPointTexture (const tcu::PixelBufferAccess& access)
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(isFloatingPointDepthFormat(access.getFormat()));
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int z = 0; z < access.getDepth(); ++z)
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < access.getHeight(); ++y)
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int x = 0; x < access.getWidth(); ++x)
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		access.setPixDepth( de::clamp(access.getPixDepth(x, y, z), 0.0f, 1.0f), x, y, z);
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void clampFloatingPointTexture (tcu::Texture2D& target)
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int level = 0; level < target.getNumLevels(); ++level)
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!target.isLevelEmpty(level))
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			clampFloatingPointTexture(target.getLevel(level));
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void clampFloatingPointTexture (tcu::Texture2DArray& target)
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int level = 0; level < target.getNumLevels(); ++level)
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!target.isLevelEmpty(level))
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			clampFloatingPointTexture(target.getLevel(level));
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void clampFloatingPointTexture (tcu::TextureCube& target)
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int level = 0; level < target.getNumLevels(); ++level)
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int face = tcu::CUBEFACE_NEGATIVE_X; face < tcu::CUBEFACE_LAST; ++face)
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			clampFloatingPointTexture(target.getLevelFace(level, (tcu::CubeFace)face));
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename TextureType>
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool verifyTexCompareResult (tcu::TestContext&						testCtx,
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							 const tcu::ConstPixelBufferAccess&		result,
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							 const TextureType&						src,
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							 const float*							texCoord,
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							 const ReferenceParams&					sampleParams,
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							 const tcu::TexComparePrecision&		comparePrec,
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							 const tcu::LodPrecision&				lodPrec,
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							 const tcu::PixelFormat&				pixelFormat)
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestLog&	log					= testCtx.getLog();
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface	reference			(result.getWidth(), result.getHeight());
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface	errorMask			(result.getWidth(), result.getHeight());
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec3	nonShadowThreshold	= tcu::computeFixedPointThreshold(getBitsVec(pixelFormat)-1).swizzle(1,2,3);
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				numFailedPixels;
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// sampleTexture() expects source image to be the same state as it would be in a GL implementation, that is
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// the floating point depth values should be in [0, 1] range as data is clamped during texture upload. Since
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// we don't have a separate "uploading" phase and just reuse the buffer we used for GL-upload, do the clamping
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// here if necessary.
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isFloatingPointDepthFormat(src.getFormat()))
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TextureType clampedSource(src);
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		clampFloatingPointTexture(clampedSource);
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// sample clamped values
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		sampleTexture(SurfaceAccess(reference, pixelFormat), clampedSource, texCoord, sampleParams);
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		numFailedPixels = computeTextureCompareDiff(result, reference.getAccess(), errorMask.getAccess(), clampedSource, texCoord, sampleParams, comparePrec, lodPrec, nonShadowThreshold);
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// sample raw values (they are guaranteed to be in [0, 1] range as the format cannot represent any other values)
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		sampleTexture(SurfaceAccess(reference, pixelFormat), src, texCoord, sampleParams);
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		numFailedPixels = computeTextureCompareDiff(result, reference.getAccess(), errorMask.getAccess(), src, texCoord, sampleParams, comparePrec, lodPrec, nonShadowThreshold);
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (numFailedPixels > 0)
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << TestLog::EndMessage;
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::ImageSet("VerifyResult", "Verification result")
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< TestLog::Image("Rendered", "Rendered image", result);
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (numFailedPixels > 0)
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Image("Reference", "Ideal reference image", reference)
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< TestLog::Image("ErrorMask", "Error mask", errorMask);
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::EndImageSet;
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return numFailedPixels == 0;
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Texture2DShadowCase : public TestCase
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									Texture2DShadowCase			(Context& context, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT, deUint32 format, int width, int height, deUint32 compareFunc);
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									~Texture2DShadowCase		(void);
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void							init						(void);
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void							deinit						(void);
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult					iterate						(void);
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									Texture2DShadowCase			(const Texture2DShadowCase& other);
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Texture2DShadowCase&			operator=					(const Texture2DShadowCase& other);
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					m_minFilter;
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					m_magFilter;
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					m_wrapS;
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					m_wrapT;
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					m_format;
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						m_width;
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						m_height;
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					m_compareFunc;
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct FilterCase
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::Texture2D*	texture;
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec2				minCoord;
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec2				maxCoord;
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float					ref;
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FilterCase (void)
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			: texture	(DE_NULL)
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			, ref		(0.0f)
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FilterCase (const glu::Texture2D* tex_, const float ref_, const tcu::Vec2& minCoord_, const tcu::Vec2& maxCoord_)
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			: texture	(tex_)
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			, minCoord	(minCoord_)
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			, maxCoord	(maxCoord_)
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			, ref		(ref_)
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<glu::Texture2D*>	m_textures;
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<FilterCase>			m_cases;
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureRenderer					m_renderer;
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int								m_caseNdx;
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2053c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DShadowCase::Texture2DShadowCase (Context& context, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT, deUint32 format, int width, int height, deUint32 compareFunc)
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase			(context, name, desc)
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_minFilter		(minFilter)
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_magFilter		(magFilter)
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapS			(wrapS)
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapT			(wrapT)
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_format			(format)
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width			(width)
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height			(height)
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_compareFunc		(compareFunc)
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderer		(context.getRenderContext(), context.getTestContext(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_caseNdx			(0)
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2203c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DShadowCase::~Texture2DShadowCase (void)
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deinit();
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture2DShadowCase::init (void)
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	try
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Create 2 textures.
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_textures.reserve(2);
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_textures.push_back(new glu::Texture2D(m_context.getRenderContext(), m_format, m_width, m_height));
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_textures.push_back(new glu::Texture2D(m_context.getRenderContext(), m_format, m_width, m_height));
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int numLevels = m_textures[0]->getRefTexture().getNumLevels();
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Fill first gradient texture.
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_textures[0]->getRefTexture().allocLevel(levelNdx);
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::fillWithComponentGradients(m_textures[0]->getRefTexture().getLevel(levelNdx), tcu::Vec4(-0.5f, -0.5f, -0.5f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f));
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Fill second with grid texture.
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deUint32	step	= 0x00ffffff / numLevels;
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deUint32	rgb		= step*levelNdx;
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deUint32	colorA	= 0xff000000 | rgb;
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deUint32	colorB	= 0xff000000 | ~rgb;
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_textures[1]->getRefTexture().allocLevel(levelNdx);
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::fillWithGrid(m_textures[1]->getRefTexture().getLevel(levelNdx), 4, toVec4(tcu::RGBA(colorA)), toVec4(tcu::RGBA(colorB)));
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Upload.
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (std::vector<glu::Texture2D*>::iterator i = m_textures.begin(); i != m_textures.end(); i++)
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			(*i)->upload();
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	catch (const std::exception&)
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Clean up to save memory.
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Texture2DShadowCase::deinit();
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw;
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compute cases.
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float refInRangeUpper		= (m_compareFunc == GL_EQUAL || m_compareFunc == GL_NOTEQUAL) ? 1.0f : 0.5f;
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float refInRangeLower		= (m_compareFunc == GL_EQUAL || m_compareFunc == GL_NOTEQUAL) ? 0.0f : 0.5f;
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float refOutOfBoundsUpper	= 1.1f;		// !< lookup function should clamp values to [0, 1] range
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float refOutOfBoundsLower	= -0.1f;
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const struct
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int		texNdx;
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float	ref;
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float	lodX;
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float	lodY;
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float	oX;
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float	oY;
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		} cases[] =
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 0,	refInRangeUpper,		1.6f,	2.9f,	-1.0f,	-2.7f	},
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 0,	refInRangeLower,		-2.0f,	-1.35f,	-0.2f,	0.7f	},
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 1,	refInRangeUpper,		0.14f,	0.275f,	-1.5f,	-1.1f	},
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 1,	refInRangeLower,		-0.92f,	-2.64f,	0.4f,	-0.1f	},
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 1,	refOutOfBoundsUpper,	-0.39f,	-0.52f,	0.65f,	0.87f	},
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 1,	refOutOfBoundsLower,	-1.55f,	0.65f,	0.35f,	0.91f	},
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float	viewportW	= (float)de::min<int>(TEX2D_VIEWPORT_WIDTH, m_context.getRenderTarget().getWidth());
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float	viewportH	= (float)de::min<int>(TEX2D_VIEWPORT_HEIGHT, m_context.getRenderTarget().getHeight());
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(cases); caseNdx++)
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int	texNdx	= de::clamp(cases[caseNdx].texNdx, 0, (int)m_textures.size()-1);
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const float ref		= cases[caseNdx].ref;
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const float	lodX	= cases[caseNdx].lodX;
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const float	lodY	= cases[caseNdx].lodY;
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const float	oX		= cases[caseNdx].oX;
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const float	oY		= cases[caseNdx].oY;
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const float	sX		= deFloatExp2(lodX)*viewportW / float(m_textures[texNdx]->getRefTexture().getWidth());
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const float	sY		= deFloatExp2(lodY)*viewportH / float(m_textures[texNdx]->getRefTexture().getHeight());
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_cases.push_back(FilterCase(m_textures[texNdx], ref, tcu::Vec2(oX, oY), tcu::Vec2(oX+sX, oY+sY)));
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_caseNdx = 0;
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture2DShadowCase::deinit (void)
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (std::vector<glu::Texture2D*>::iterator i = m_textures.begin(); i != m_textures.end(); i++)
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete *i;
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_textures.clear();
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderer.clear();
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_cases.clear();
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3233c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DShadowCase::IterateResult Texture2DShadowCase::iterate (void)
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&			gl				= m_context.getRenderContext().getFunctions();
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const RandomViewport			viewport		(m_context.getRenderTarget(), TEX2D_VIEWPORT_WIDTH, TEX2D_VIEWPORT_HEIGHT, deStringHash(getName()) ^ deInt32Hash(m_caseNdx));
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const FilterCase&				curCase			= m_cases[m_caseNdx];
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::ScopedLogSection		section			(m_testCtx.getLog(), string("Test") + de::toString(m_caseNdx), string("Test ") + de::toString(m_caseNdx));
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ReferenceParams					sampleParams	(TEXTURETYPE_2D);
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface					rendered		(viewport.width, viewport.height);
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<float>					texCoord;
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (viewport.width < TEX2D_MIN_VIEWPORT_WIDTH || viewport.height < TEX2D_MIN_VIEWPORT_HEIGHT)
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::NotSupportedError("Too small render target", "", __FILE__, __LINE__);
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Setup params for reference.
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleParams.sampler			= glu::mapGLSampler(m_wrapS, m_wrapT, m_minFilter, m_magFilter);
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleParams.sampler.compare	= glu::mapGLCompareFunc(m_compareFunc);
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleParams.samplerType		= SAMPLERTYPE_SHADOW;
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleParams.lodMode			= LODMODE_EXACT;
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleParams.ref				= curCase.ref;
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << TestLog::Message << "Compare reference value =  " << sampleParams.ref << TestLog::EndMessage;
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compute texture coordinates.
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << TestLog::Message << "Texture coordinates: " << curCase.minCoord << " -> " << curCase.maxCoord << TestLog::EndMessage;
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	computeQuadTexCoord2D(texCoord, curCase.minCoord, curCase.maxCoord);
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindTexture	(GL_TEXTURE_2D, curCase.texture->getGLTexture());
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,		m_minFilter);
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,		m_magFilter);
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,			m_wrapS);
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,			m_wrapT);
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE,	GL_COMPARE_REF_TO_TEXTURE);
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC,	m_compareFunc);
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderer.renderQuad(0, &texCoord[0], sampleParams);
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::readPixels(m_context.getRenderContext(), viewport.x, viewport.y, rendered.getAccess());
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::PixelFormat		pixelFormat		= m_context.getRenderTarget().getPixelFormat();
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::LodPrecision			lodPrecision;
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TexComparePrecision	texComparePrecision;
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lodPrecision.derivateBits			= 18;
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lodPrecision.lodBits				= 6;
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		texComparePrecision.coordBits		= tcu::IVec3(20,20,0);
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		texComparePrecision.uvwBits			= tcu::IVec3(7,7,0);
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		texComparePrecision.pcfBits			= 5;
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		texComparePrecision.referenceBits	= 16;
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		texComparePrecision.resultBits		= pixelFormat.redBits-1;
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool isHighQuality = verifyTexCompareResult(m_testCtx, rendered.getAccess(), curCase.texture->getRefTexture(),
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														  &texCoord[0], sampleParams, texComparePrecision, lodPrecision, pixelFormat);
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!isHighQuality)
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog() << TestLog::Message << "Warning: Verification assuming high-quality PCF filtering failed." << TestLog::EndMessage;
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			lodPrecision.lodBits			= 4;
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texComparePrecision.uvwBits		= tcu::IVec3(4,4,0);
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texComparePrecision.pcfBits		= 0;
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool isOk = verifyTexCompareResult(m_testCtx, rendered.getAccess(), curCase.texture->getRefTexture(),
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 &texCoord[0], sampleParams, texComparePrecision, lodPrecision, pixelFormat);
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!isOk)
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_testCtx.getLog() << TestLog::Message << "ERROR: Verification against low precision requirements failed, failing test case." << TestLog::EndMessage;
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_testCtx.setTestResult(QP_TEST_RESULT_QUALITY_WARNING, "Low-quality result");
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_caseNdx += 1;
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m_caseNdx < (int)m_cases.size() ? CONTINUE : STOP;
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass TextureCubeShadowCase : public TestCase
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								TextureCubeShadowCase		(Context& context, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT, deUint32 format, int size, deUint32 compareFunc);
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								~TextureCubeShadowCase		(void);
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						init						(void);
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						deinit						(void);
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult				iterate						(void);
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								TextureCubeShadowCase		(const TextureCubeShadowCase& other);
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureCubeShadowCase&		operator=					(const TextureCubeShadowCase& other);
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32				m_minFilter;
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32				m_magFilter;
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32				m_wrapS;
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32				m_wrapT;
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32				m_format;
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					m_size;
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32				m_compareFunc;
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct FilterCase
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::TextureCube*	texture;
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec2				bottomLeft;
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec2				topRight;
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float					ref;
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FilterCase (void)
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			: texture	(DE_NULL)
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			, ref		(0.0f)
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FilterCase (const glu::TextureCube* tex_, const float ref_, const tcu::Vec2& bottomLeft_, const tcu::Vec2& topRight_)
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			: texture	(tex_)
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			, bottomLeft(bottomLeft_)
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			, topRight	(topRight_)
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			, ref		(ref_)
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TextureCube*			m_gradientTex;
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TextureCube*			m_gridTex;
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<FilterCase>		m_cases;
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureRenderer				m_renderer;
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int							m_caseNdx;
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4573c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeShadowCase::TextureCubeShadowCase (Context& context, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT, deUint32 format, int size, deUint32 compareFunc)
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase			(context, name, desc)
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_minFilter		(minFilter)
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_magFilter		(magFilter)
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapS			(wrapS)
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapT			(wrapT)
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_format			(format)
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_size			(size)
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_compareFunc		(compareFunc)
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_gradientTex		(DE_NULL)
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_gridTex			(DE_NULL)
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderer		(context.getRenderContext(), m_context.getTestContext(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_caseNdx			(0)
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4733c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeShadowCase::~TextureCubeShadowCase (void)
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureCubeShadowCase::deinit();
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCubeShadowCase::init (void)
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	try
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(!m_gradientTex && !m_gridTex);
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int						numLevels	= deLog2Floor32(m_size)+1;
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TextureFormat		texFmt		= glu::mapGLInternalFormat(m_format);
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TextureFormatInfo	fmtInfo		= tcu::getTextureFormatInfo(texFmt);
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4				cBias		= fmtInfo.valueMin;
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4				cScale		= fmtInfo.valueMax-fmtInfo.valueMin;
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Create textures.
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_gradientTex	= new glu::TextureCube(m_context.getRenderContext(), m_format, m_size);
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_gridTex		= new glu::TextureCube(m_context.getRenderContext(), m_format, m_size);
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Fill first with gradient texture.
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const tcu::Vec4 gradients[tcu::CUBEFACE_LAST][2] =
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ tcu::Vec4(-1.0f, -1.0f, -1.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // negative x
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ tcu::Vec4( 0.0f, -1.0f, -1.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // positive x
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ tcu::Vec4(-1.0f,  0.0f, -1.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // negative y
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ tcu::Vec4(-1.0f, -1.0f,  0.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // positive y
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ tcu::Vec4(-1.0f, -1.0f, -1.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f) }, // negative z
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ tcu::Vec4( 0.0f,  0.0f,  0.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }  // positive z
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_gradientTex->getRefTexture().allocLevel((tcu::CubeFace)face, levelNdx);
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::fillWithComponentGradients(m_gradientTex->getRefTexture().getLevelFace(levelNdx, (tcu::CubeFace)face), gradients[face][0]*cScale + cBias, gradients[face][1]*cScale + cBias);
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Fill second with grid texture.
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32	step	= 0x00ffffff / (numLevels*tcu::CUBEFACE_LAST);
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32	rgb		= step*levelNdx*face;
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32	colorA	= 0xff000000 | rgb;
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32	colorB	= 0xff000000 | ~rgb;
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_gridTex->getRefTexture().allocLevel((tcu::CubeFace)face, levelNdx);
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::fillWithGrid(m_gridTex->getRefTexture().getLevelFace(levelNdx, (tcu::CubeFace)face), 4, toVec4(tcu::RGBA(colorA))*cScale + cBias, toVec4(tcu::RGBA(colorB))*cScale + cBias);
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Upload.
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_gradientTex->upload();
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_gridTex->upload();
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	catch (const std::exception&)
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Clean up to save memory.
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TextureCubeShadowCase::deinit();
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw;
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compute cases
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float refInRangeUpper		= (m_compareFunc == GL_EQUAL || m_compareFunc == GL_NOTEQUAL) ? 1.0f : 0.5f;
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float refInRangeLower		= (m_compareFunc == GL_EQUAL || m_compareFunc == GL_NOTEQUAL) ? 0.0f : 0.5f;
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float refOutOfBoundsUpper	= 1.1f;
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float refOutOfBoundsLower	= -0.1f;
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool	singleSample		= m_context.getRenderTarget().getNumSamples() == 0;
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (singleSample)
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_cases.push_back(FilterCase(m_gradientTex,	refInRangeUpper, tcu::Vec2(-1.25f, -1.2f), tcu::Vec2(1.2f, 1.25f)));	// minification
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_cases.push_back(FilterCase(m_gradientTex,	refInRangeUpper, tcu::Vec2(-1.19f, -1.3f), tcu::Vec2(1.1f, 1.35f)));	// minification - w/ tuned coordinates to avoid hitting triangle edges
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_cases.push_back(FilterCase(m_gradientTex,	refInRangeLower,		tcu::Vec2(0.8f, 0.8f), tcu::Vec2(1.25f, 1.20f)));	// magnification
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_cases.push_back(FilterCase(m_gridTex,		refInRangeUpper,		tcu::Vec2(-1.19f, -1.3f), tcu::Vec2(1.1f, 1.35f)));	// minification
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_cases.push_back(FilterCase(m_gridTex,		refInRangeLower,		tcu::Vec2(-1.2f, -1.1f), tcu::Vec2(-0.8f, -0.8f)));	// magnification
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_cases.push_back(FilterCase(m_gridTex,		refOutOfBoundsUpper,	tcu::Vec2(-0.61f, -0.1f), tcu::Vec2(0.9f, 1.18f)));	// reference value clamp, upper
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (singleSample)
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_cases.push_back(FilterCase(m_gridTex,	refOutOfBoundsLower, tcu::Vec2(-0.75f, 1.0f), tcu::Vec2(0.05f, 0.75f)));	// reference value clamp, lower
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_cases.push_back(FilterCase(m_gridTex,	refOutOfBoundsLower, tcu::Vec2(-0.75f, 1.0f), tcu::Vec2(0.25f, 0.75f)));	// reference value clamp, lower
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_caseNdx = 0;
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCubeShadowCase::deinit (void)
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_gradientTex;
5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_gridTex;
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_gradientTex	= DE_NULL;
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_gridTex		= DE_NULL;
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderer.clear();
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_cases.clear();
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* getFaceDesc (const tcu::CubeFace face)
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (face)
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::CUBEFACE_NEGATIVE_X:	return "-X";
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::CUBEFACE_POSITIVE_X:	return "+X";
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::CUBEFACE_NEGATIVE_Y:	return "-Y";
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::CUBEFACE_POSITIVE_Y:	return "+Y";
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::CUBEFACE_NEGATIVE_Z:	return "-Z";
5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::CUBEFACE_POSITIVE_Z:	return "+Z";
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return DE_NULL;
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5953c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeShadowCase::IterateResult TextureCubeShadowCase::iterate (void)
5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&			gl				= m_context.getRenderContext().getFunctions();
5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						viewportSize	= 28;
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const RandomViewport			viewport		(m_context.getRenderTarget(), viewportSize, viewportSize, deStringHash(getName()) ^ deInt32Hash(m_caseNdx));
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::ScopedLogSection		iterSection		(m_testCtx.getLog(), string("Test") + de::toString(m_caseNdx), string("Test ") + de::toString(m_caseNdx));
6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const FilterCase&				curCase			= m_cases[m_caseNdx];
6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ReferenceParams					sampleParams	(TEXTURETYPE_CUBE);
6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (viewport.width < viewportSize || viewport.height < viewportSize)
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::NotSupportedError("Too small render target", DE_NULL, __FILE__, __LINE__);
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Setup texture
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindTexture	(GL_TEXTURE_CUBE_MAP, curCase.texture->getGLTexture());
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,	m_minFilter);
6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER,	m_magFilter);
6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,		m_wrapS);
6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,		m_wrapT);
6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE,	GL_COMPARE_REF_TO_TEXTURE);
6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC,	m_compareFunc);
6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Other state
6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Params for reference computation.
6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleParams.sampler					= glu::mapGLSampler(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, m_minFilter, m_magFilter);
6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleParams.sampler.seamlessCubeMap	= true;
6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleParams.sampler.compare			= glu::mapGLCompareFunc(m_compareFunc);
6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleParams.samplerType				= SAMPLERTYPE_SHADOW;
6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleParams.lodMode					= LODMODE_EXACT;
6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleParams.ref						= curCase.ref;
6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog()
6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< TestLog::Message
6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< "Compare reference value =  " << sampleParams.ref << "\n"
6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< "Coordinates: " << curCase.bottomLeft << " -> " << curCase.topRight
6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< TestLog::EndMessage;
6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::CubeFace		face		= tcu::CubeFace(faceNdx);
6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Surface			result		(viewport.width, viewport.height);
6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<float>			texCoord;
6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		computeQuadTexCoordCube(texCoord, face, curCase.bottomLeft, curCase.topRight);
6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << TestLog::Message << "Face " << getFaceDesc(face) << TestLog::EndMessage;
6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// \todo Log texture coordinates.
6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_renderer.renderQuad(0, &texCoord[0], sampleParams);
6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "Draw");
6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::readPixels(m_context.getRenderContext(), viewport.x, viewport.y, result.getAccess());
6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "Read pixels");
6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const tcu::PixelFormat		pixelFormat		= m_context.getRenderTarget().getPixelFormat();
6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::LodPrecision			lodPrecision;
6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::TexComparePrecision	texComparePrecision;
6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			lodPrecision.derivateBits			= 10;
6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			lodPrecision.lodBits				= 5;
6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texComparePrecision.coordBits		= tcu::IVec3(10,10,10);
6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texComparePrecision.uvwBits			= tcu::IVec3(6,6,0);
6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texComparePrecision.pcfBits			= 5;
6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texComparePrecision.referenceBits	= 16;
6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texComparePrecision.resultBits		= pixelFormat.redBits-1;
6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool isHighQuality = verifyTexCompareResult(m_testCtx, result.getAccess(), curCase.texture->getRefTexture(),
6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															  &texCoord[0], sampleParams, texComparePrecision, lodPrecision, pixelFormat);
6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!isHighQuality)
6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_testCtx.getLog() << TestLog::Message << "Warning: Verification assuming high-quality PCF filtering failed." << TestLog::EndMessage;
6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				lodPrecision.lodBits			= 4;
6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				texComparePrecision.uvwBits		= tcu::IVec3(4,4,0);
6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				texComparePrecision.pcfBits		= 0;
6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const bool isOk = verifyTexCompareResult(m_testCtx, result.getAccess(), curCase.texture->getRefTexture(),
6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														 &texCoord[0], sampleParams, texComparePrecision, lodPrecision, pixelFormat);
6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (!isOk)
6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_testCtx.getLog() << TestLog::Message << "ERROR: Verification against low precision requirements failed, failing test case." << TestLog::EndMessage;
6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_testCtx.setTestResult(QP_TEST_RESULT_QUALITY_WARNING, "Low-quality result");
6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_caseNdx += 1;
6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m_caseNdx < (int)m_cases.size() ? CONTINUE : STOP;
6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Texture2DArrayShadowCase : public TestCase
6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								Texture2DArrayShadowCase	(Context& context, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT, deUint32 format, int width, int height, int numLayers, deUint32 compareFunc);
6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								~Texture2DArrayShadowCase	(void);
6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						init						(void);
7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						deinit						(void);
7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult				iterate						(void);
7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								Texture2DArrayShadowCase	(const Texture2DArrayShadowCase& other);
7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Texture2DArrayShadowCase&	operator=					(const Texture2DArrayShadowCase& other);
7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32				m_minFilter;
7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32				m_magFilter;
7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32				m_wrapS;
7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32				m_wrapT;
7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32				m_format;
7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					m_width;
7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					m_height;
7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					m_numLayers;
7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32				m_compareFunc;
7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct FilterCase
7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::Texture2DArray*	texture;
7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec3					minCoord;
7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec3					maxCoord;
7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float						ref;
7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FilterCase (void)
7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			: texture	(DE_NULL)
7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			, ref		(0.0f)
7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FilterCase (const glu::Texture2DArray* tex_, float ref_, const tcu::Vec3& minCoord_, const tcu::Vec3& maxCoord_)
7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			: texture	(tex_)
7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			, minCoord	(minCoord_)
7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			, maxCoord	(maxCoord_)
7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			, ref		(ref_)
7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::Texture2DArray*		m_gradientTex;
7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::Texture2DArray*		m_gridTex;
7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<FilterCase>		m_cases;
7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureRenderer				m_renderer;
7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int							m_caseNdx;
7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7503c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DArrayShadowCase::Texture2DArrayShadowCase (Context& context, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT, deUint32 format, int width, int height, int numLayers, deUint32 compareFunc)
7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase			(context, name, desc)
7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_minFilter		(minFilter)
7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_magFilter		(magFilter)
7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapS			(wrapS)
7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapT			(wrapT)
7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_format			(format)
7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width			(width)
7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height			(height)
7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numLayers		(numLayers)
7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_compareFunc		(compareFunc)
7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_gradientTex		(DE_NULL)
7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_gridTex			(DE_NULL)
7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderer		(context.getRenderContext(), context.getTestContext(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_caseNdx			(0)
7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7683c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DArrayShadowCase::~Texture2DArrayShadowCase (void)
7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Texture2DArrayShadowCase::deinit();
7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture2DArrayShadowCase::init (void)
7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	try
7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TextureFormat		texFmt		= glu::mapGLInternalFormat(m_format);
7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TextureFormatInfo	fmtInfo		= tcu::getTextureFormatInfo(texFmt);
7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4				cScale		= fmtInfo.valueMax-fmtInfo.valueMin;
7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4				cBias		= fmtInfo.valueMin;
7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int						numLevels	= deLog2Floor32(de::max(m_width, m_height)) + 1;
7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Create textures.
7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_gradientTex	= new glu::Texture2DArray(m_context.getRenderContext(), m_format, m_width, m_height, m_numLayers);
7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_gridTex		= new glu::Texture2DArray(m_context.getRenderContext(), m_format, m_width, m_height, m_numLayers);
7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Fill first gradient texture.
7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4 gMin = tcu::Vec4(-0.5f, -0.5f, -0.5f, 2.0f)*cScale + cBias;
7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4 gMax = tcu::Vec4( 1.0f,  1.0f,  1.0f, 0.0f)*cScale + cBias;
7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_gradientTex->getRefTexture().allocLevel(levelNdx);
7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::fillWithComponentGradients(m_gradientTex->getRefTexture().getLevel(levelNdx), gMin, gMax);
7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Fill second with grid texture.
7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deUint32	step	= 0x00ffffff / numLevels;
8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deUint32	rgb		= step*levelNdx;
8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deUint32	colorA	= 0xff000000 | rgb;
8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deUint32	colorB	= 0xff000000 | ~rgb;
8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_gridTex->getRefTexture().allocLevel(levelNdx);
8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::fillWithGrid(m_gridTex->getRefTexture().getLevel(levelNdx), 4, tcu::RGBA(colorA).toVec()*cScale + cBias, tcu::RGBA(colorB).toVec()*cScale + cBias);
8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Upload.
8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_gradientTex->upload();
8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_gridTex->upload();
8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	catch (...)
8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Clean up to save memory.
8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Texture2DArrayShadowCase::deinit();
8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw;
8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compute cases.
8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float refInRangeUpper		= (m_compareFunc == GL_EQUAL || m_compareFunc == GL_NOTEQUAL) ? 1.0f : 0.5f;
8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float refInRangeLower		= (m_compareFunc == GL_EQUAL || m_compareFunc == GL_NOTEQUAL) ? 0.0f : 0.5f;
8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float refOutOfBoundsUpper	= 1.1f;		// !< lookup function should clamp values to [0, 1] range
8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float refOutOfBoundsLower	= -0.1f;
8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const struct
8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int		texNdx;
8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float	ref;
8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float	lodX;
8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float	lodY;
8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float	oX;
8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float	oY;
8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		} cases[] =
8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 0,	refInRangeUpper,		1.6f,	2.9f,	-1.0f,	-2.7f	},
8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 0,	refInRangeLower,		-2.0f,	-1.35f,	-0.2f,	0.7f	},
8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 1,	refInRangeUpper,		0.14f,	0.275f,	-1.5f,	-1.1f	},
8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 1,	refInRangeLower,		-0.92f,	-2.64f,	0.4f,	-0.1f	},
8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 1,	refOutOfBoundsUpper,	-0.49f,	-0.22f,	0.45f,	0.97f	},
8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 1,	refOutOfBoundsLower,	-0.85f,	0.75f,	0.25f,	0.61f	},
8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float	viewportW	= (float)de::min<int>(TEX2D_VIEWPORT_WIDTH, m_context.getRenderTarget().getWidth());
8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float	viewportH	= (float)de::min<int>(TEX2D_VIEWPORT_HEIGHT, m_context.getRenderTarget().getHeight());
8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float	minLayer	= -0.5f;
8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float	maxLayer	= (float)m_numLayers;
8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(cases); caseNdx++)
8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const glu::Texture2DArray*	tex		= cases[caseNdx].texNdx > 0 ? m_gridTex : m_gradientTex;
8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const float					ref		= cases[caseNdx].ref;
8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const float					lodX	= cases[caseNdx].lodX;
8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const float					lodY	= cases[caseNdx].lodY;
8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const float					oX		= cases[caseNdx].oX;
8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const float					oY		= cases[caseNdx].oY;
8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const float					sX		= deFloatExp2(lodX)*viewportW / float(tex->getRefTexture().getWidth());
8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const float					sY		= deFloatExp2(lodY)*viewportH / float(tex->getRefTexture().getHeight());
8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_cases.push_back(FilterCase(tex, ref, tcu::Vec3(oX, oY, minLayer), tcu::Vec3(oX+sX, oY+sY, maxLayer)));
8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_caseNdx = 0;
8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture2DArrayShadowCase::deinit (void)
8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_gradientTex;
8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_gridTex;
8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_gradientTex	= DE_NULL;
8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_gridTex		= DE_NULL;
8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderer.clear();
8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_cases.clear();
8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8823c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DArrayShadowCase::IterateResult Texture2DArrayShadowCase::iterate (void)
8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&			gl				= m_context.getRenderContext().getFunctions();
8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const RandomViewport			viewport		(m_context.getRenderTarget(), TEX2D_VIEWPORT_WIDTH, TEX2D_VIEWPORT_HEIGHT, deStringHash(getName()) ^ deInt32Hash(m_caseNdx));
8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const FilterCase&				curCase			= m_cases[m_caseNdx];
8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::ScopedLogSection		section			(m_testCtx.getLog(), string("Test") + de::toString(m_caseNdx), string("Test ") + de::toString(m_caseNdx));
8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ReferenceParams					sampleParams	(TEXTURETYPE_2D_ARRAY);
8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface					rendered		(viewport.width, viewport.height);
8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float						texCoord[]		=
8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		curCase.minCoord.x(), curCase.minCoord.y(), curCase.minCoord.z(),
8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		curCase.minCoord.x(), curCase.maxCoord.y(), (curCase.minCoord.z() + curCase.maxCoord.z()) / 2.0f,
8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		curCase.maxCoord.x(), curCase.minCoord.y(), (curCase.minCoord.z() + curCase.maxCoord.z()) / 2.0f,
8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		curCase.maxCoord.x(), curCase.maxCoord.y(), curCase.maxCoord.z()
8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (viewport.width < TEX2D_MIN_VIEWPORT_WIDTH || viewport.height < TEX2D_MIN_VIEWPORT_HEIGHT)
9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::NotSupportedError("Too small render target", "", __FILE__, __LINE__);
9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Setup params for reference.
9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleParams.sampler			= glu::mapGLSampler(m_wrapS, m_wrapT, m_minFilter, m_magFilter);
9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleParams.sampler.compare	= glu::mapGLCompareFunc(m_compareFunc);
9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleParams.samplerType		= SAMPLERTYPE_SHADOW;
9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleParams.lodMode			= LODMODE_EXACT;
9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleParams.ref				= curCase.ref;
9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog()
9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< TestLog::Message
9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< "Compare reference value =  " << sampleParams.ref << "\n"
9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< "Texture coordinates: " << curCase.minCoord << " -> " << curCase.maxCoord
9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< TestLog::EndMessage;
9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindTexture	(GL_TEXTURE_2D_ARRAY, curCase.texture->getGLTexture());
9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER,	m_minFilter);
9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER,	m_magFilter);
9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S,		m_wrapS);
9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T,		m_wrapT);
9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE,	GL_COMPARE_REF_TO_TEXTURE);
9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_FUNC,	m_compareFunc);
9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderer.renderQuad(0, &texCoord[0], sampleParams);
9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::readPixels(m_context.getRenderContext(), viewport.x, viewport.y, rendered.getAccess());
9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::