1d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan/*-------------------------------------------------------------------------
2d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan * Vulkan Conformance Tests
3d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan * ------------------------
4d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan *
5d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan * Copyright 2014 The Android Open Source Project
6d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan * Copyright (c) 2016 The Khronos Group Inc.
7d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan * Copyright (c) 2016 Samsung Electronics Co., Ltd.
8d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan *
9d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan * Licensed under the Apache License, Version 2.0 (the "License");
10d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan * you may not use this file except in compliance with the License.
11d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan * You may obtain a copy of the License at
12d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan *
13d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan *      http://www.apache.org/licenses/LICENSE-2.0
14d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan *
15d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan * Unless required by applicable law or agreed to in writing, software
16d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan * distributed under the License is distributed on an "AS IS" BASIS,
17d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan * See the License for the specific language governing permissions and
19d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan * limitations under the License.
20d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan *
21d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan *//*!
22d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan * \file
23d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan * \brief Shadow texture lookup tests.
24d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan *//*--------------------------------------------------------------------*/
25d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
26d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan#include "vktTextureShadowTests.hpp"
27d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
28d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan#include "deMath.h"
29d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan#include "deString.h"
30d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan#include "deStringUtil.hpp"
31d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan#include "gluPixelTransfer.hpp"
32d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan#include "gluTextureTestUtil.hpp"
33d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan#include "glwEnums.hpp"
34d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan#include "glwFunctions.hpp"
35d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan#include "tcuImageIO.hpp"
36d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan#include "tcuRenderTarget.hpp"
37d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan#include "tcuTexCompareVerifier.hpp"
38d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan#include "tcuTexVerifierUtil.hpp"
39d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan#include "tcuTexture.hpp"
40d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan#include "tcuTextureUtil.hpp"
41d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan#include "vkImageUtil.hpp"
42d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan#include "vkTypeUtil.hpp"
43d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan#include "vktTestGroupUtil.hpp"
44d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan#include "vktTextureTestUtil.hpp"
45d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
46d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledanusing namespace vk;
47d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
48d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledannamespace vkt
49d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan{
50d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledannamespace texture
51d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan{
52d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledannamespace
53d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan{
54d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
55d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledanusing std::vector;
56d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledanusing std::string;
57d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledanusing tcu::TestLog;
58d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledanusing tcu::Sampler;
59d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledanusing namespace texture::util;
60d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledanusing namespace glu::TextureTestUtil;
61d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
62d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledanenum
63d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan{
64d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	TEXCUBE_VIEWPORT_SIZE	= 28,
65d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	TEX2D_VIEWPORT_WIDTH	= 64,
66d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	TEX2D_VIEWPORT_HEIGHT	= 64
67d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan};
68d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
69d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledanstruct TextureShadowCommonTestCaseParameters
70d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan{
71d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan							TextureShadowCommonTestCaseParameters	(void);
72d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	Sampler::CompareMode	compareOp;
73d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan};
74d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
75d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard LedanTextureShadowCommonTestCaseParameters::TextureShadowCommonTestCaseParameters (void)
76d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	: compareOp				(Sampler::COMPAREMODE_EQUAL)
77d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan{
78d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan}
79d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
80d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledanstruct Texture2DShadowTestCaseParameters : public Texture2DTestCaseParameters, public TextureShadowCommonTestCaseParameters
81d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan{
82d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan};
83d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
84d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledanbool isFloatingPointDepthFormat (const tcu::TextureFormat& format)
85d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan{
86d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	// Only two depth and depth-stencil formats are floating point
87d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	return	(format.order == tcu::TextureFormat::D && format.type == tcu::TextureFormat::FLOAT) ||
88d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			(format.order == tcu::TextureFormat::DS && format.type == tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV);
89d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan}
90d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
91d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledanvoid clampFloatingPointTexture (const tcu::PixelBufferAccess& access)
92d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan{
93d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	DE_ASSERT(isFloatingPointDepthFormat(access.getFormat()));
94d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
95d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	for (int z = 0; z < access.getDepth(); ++z)
96d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	for (int y = 0; y < access.getHeight(); ++y)
97d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	for (int x = 0; x < access.getWidth(); ++x)
98d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		access.setPixDepth(de::clamp(access.getPixDepth(x, y, z), 0.0f, 1.0f), x, y, z);
99d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan}
100d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
101d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledanvoid clampFloatingPointTexture (tcu::Texture2D& target)
102d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan{
103d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	for (int level = 0; level < target.getNumLevels(); ++level)
104d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		if (!target.isLevelEmpty(level))
105d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			clampFloatingPointTexture(target.getLevel(level));
106d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan}
107d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
108d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledanstatic void clampFloatingPointTexture (tcu::Texture2DArray& target)
109d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan{
110d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	for (int level = 0; level < target.getNumLevels(); ++level)
111d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		if (!target.isLevelEmpty(level))
112d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			clampFloatingPointTexture(target.getLevel(level));
113d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan}
114d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
115d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledanvoid clampFloatingPointTexture (tcu::TextureCube& target)
116d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan{
117d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	for (int level = 0; level < target.getNumLevels(); ++level)
118d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		for (int face = tcu::CUBEFACE_NEGATIVE_X; face < tcu::CUBEFACE_LAST; ++face)
119d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			clampFloatingPointTexture(target.getLevelFace(level, (tcu::CubeFace)face));
120d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan}
121d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
122d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledantcu::PixelFormat getPixelFormat(tcu::TextureFormat texFormat)
123d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan{
124d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	const tcu::IVec4			formatBitDepth		= tcu::getTextureFormatBitDepth(tcu::getEffectiveDepthStencilTextureFormat(texFormat, Sampler::MODE_DEPTH));
125d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	return tcu::PixelFormat(formatBitDepth[0], formatBitDepth[1], formatBitDepth[2], formatBitDepth[3]);
126d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan}
127d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
128d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledantemplate<typename TextureType>
129d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledanbool verifyTexCompareResult (tcu::TestContext&						testCtx,
130d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan							 const tcu::ConstPixelBufferAccess&		result,
131d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan							 const TextureType&						src,
132d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan							 const float*							texCoord,
133d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan							 const ReferenceParams&					sampleParams,
134d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan							 const tcu::TexComparePrecision&		comparePrec,
135d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan							 const tcu::LodPrecision&				lodPrec,
136d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan							 const tcu::PixelFormat&				pixelFormat)
137d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan{
138d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	tcu::TestLog&	log					= testCtx.getLog();
139d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	tcu::Surface	reference			(result.getWidth(), result.getHeight());
140d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	tcu::Surface	errorMask			(result.getWidth(), result.getHeight());
141d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	const tcu::Vec3	nonShadowThreshold	= tcu::computeFixedPointThreshold(getBitsVec(pixelFormat)-1).swizzle(1,2,3);
142d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	int				numFailedPixels;
143d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
144d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	// sampleTexture() expects source image to be the same state as it would be in a GL implementation, that is
145d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	// the floating point depth values should be in [0, 1] range as data is clamped during texture upload. Since
146d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	// we don't have a separate "uploading" phase and just reuse the buffer we used for GL-upload, do the clamping
147d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	// here if necessary.
148d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
149d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	if (isFloatingPointDepthFormat(src.getFormat()))
150d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	{
151d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		TextureType clampedSource(src);
152d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
153d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		clampFloatingPointTexture(clampedSource);
154d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
155d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		// sample clamped values
156d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
157d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		sampleTexture(tcu::SurfaceAccess(reference, pixelFormat), clampedSource, texCoord, sampleParams);
158d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		numFailedPixels = computeTextureCompareDiff(result, reference.getAccess(), errorMask.getAccess(), clampedSource, texCoord, sampleParams, comparePrec, lodPrec, nonShadowThreshold);
159d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	}
160d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	else
161d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	{
162d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		// sample raw values (they are guaranteed to be in [0, 1] range as the format cannot represent any other values)
163d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
164d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		sampleTexture(tcu::SurfaceAccess(reference, pixelFormat), src, texCoord, sampleParams);
165d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		numFailedPixels = computeTextureCompareDiff(result, reference.getAccess(), errorMask.getAccess(), src, texCoord, sampleParams, comparePrec, lodPrec, nonShadowThreshold);
166d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	}
167d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
168d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	if (numFailedPixels > 0)
169d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		log << TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << TestLog::EndMessage;
170d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
171d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	log << TestLog::ImageSet("VerifyResult", "Verification result")
172d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		<< TestLog::Image("Rendered", "Rendered image", result);
173d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
174d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	if (numFailedPixels > 0)
175d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	{
176d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		log << TestLog::Image("Reference", "Ideal reference image", reference)
177d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			<< TestLog::Image("ErrorMask", "Error mask", errorMask);
178d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	}
179d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
180d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	log << TestLog::EndImageSet;
181d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
182d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	return numFailedPixels == 0;
183d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan}
184d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
185d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledanclass Texture2DShadowTestInstance : public TestInstance
186d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan{
187d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledanpublic:
188d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	typedef Texture2DShadowTestCaseParameters	ParameterType;
189d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan												Texture2DShadowTestInstance		(Context& context, const ParameterType& testParameters);
190d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan												~Texture2DShadowTestInstance	(void);
191d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
192d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	virtual tcu::TestStatus						iterate							(void);
193d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
194d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledanprivate:
195d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan												Texture2DShadowTestInstance		(const Texture2DShadowTestInstance& other);
196d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	Texture2DShadowTestInstance&				operator=						(const Texture2DShadowTestInstance& other);
197d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
198d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	struct FilterCase
199d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	{
200d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		int			textureIndex;
201d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
202d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		tcu::Vec2	minCoord;
203d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		tcu::Vec2	maxCoord;
204d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		float		ref;
205d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
206d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		FilterCase	(void)
207d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			: textureIndex(-1)
208d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			, ref		(0.0f)
209d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{
210d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		}
211d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
212d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		FilterCase	(int tex_, const float ref_, const tcu::Vec2& minCoord_, const tcu::Vec2& maxCoord_)
213d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			: textureIndex	(tex_)
214d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			, minCoord		(minCoord_)
215d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			, maxCoord		(maxCoord_)
216d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			, ref			(ref_)
217d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{
218d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		}
219d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	};
220d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
221d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	const ParameterType&			m_testParameters;
222d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	std::vector<TestTexture2DSp>	m_textures;
223d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	std::vector<FilterCase>			m_cases;
224d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
225d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	TextureRenderer					m_renderer;
226d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
227d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	int								m_caseNdx;
228d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan};
229d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
230d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard LedanTexture2DShadowTestInstance::Texture2DShadowTestInstance (Context& context, const ParameterType& testParameters)
231d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	: TestInstance			(context)
232d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	, m_testParameters		(testParameters)
233d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	, m_renderer			(context, testParameters.sampleCount, TEX2D_VIEWPORT_WIDTH, TEX2D_VIEWPORT_HEIGHT)
234d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	, m_caseNdx				(0)
235d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan{
236d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	// Create 2 textures.
237d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	m_textures.reserve(2);
238d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	for (int ndx = 0; ndx < 2; ndx++)
239d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	{
240d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		m_textures.push_back(TestTexture2DSp(new pipeline::TestTexture2D(vk::mapVkFormat(m_testParameters.format), m_testParameters.width, m_testParameters.height)));
241d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	}
242d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
243d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	const int	numLevels	= m_textures[0]->getNumLevels();
244d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
245d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	// Fill first gradient texture.
246d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	for (int levelNdx = 0; levelNdx < numLevels; ++levelNdx)
247d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	{
248d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		tcu::fillWithComponentGradients(m_textures[0]->getLevel(levelNdx, 0), tcu::Vec4(-0.5f, -0.5f, -0.5f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f));
249d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	}
250d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
251d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	// Fill second with grid texture.
252d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
253d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	{
254d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		const deUint32	step	= 0x00ffffff / numLevels;
255d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		const deUint32	rgb		= step*levelNdx;
256d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		const deUint32	colorA	= 0xff000000 | rgb;
257d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		const deUint32	colorB	= 0xff000000 | ~rgb;
258d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
259d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		tcu::fillWithGrid(m_textures[1]->getLevel(levelNdx, 0), 4, tcu::RGBA(colorA).toVec(), tcu::RGBA(colorB).toVec());
260d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	}
261d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
262d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	// Upload.
263d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	for (std::vector<TestTexture2DSp>::iterator i = m_textures.begin(); i != m_textures.end(); ++i)
264d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	{
265d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		m_renderer.add2DTexture(*i);
266d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	}
267d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
268d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	// Compute cases.
269d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	{
270d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		const float refInRangeUpper		= (m_testParameters.compareOp == Sampler::COMPAREMODE_EQUAL || m_testParameters.compareOp == Sampler::COMPAREMODE_NOT_EQUAL) ? 1.0f : 0.5f;
271d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		const float refInRangeLower		= (m_testParameters.compareOp == Sampler::COMPAREMODE_EQUAL || m_testParameters.compareOp == Sampler::COMPAREMODE_NOT_EQUAL) ? 0.0f : 0.5f;
272d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		const float refOutOfBoundsUpper	= 1.1f;		// !< lookup function should clamp values to [0, 1] range
273d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		const float refOutOfBoundsLower	= -0.1f;
274d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
275d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		const struct
276d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{
277d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			const int	texNdx;
278d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			const float	ref;
279d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			const float	lodX;
280d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			const float	lodY;
281d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			const float	oX;
282d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			const float	oY;
283d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		} cases[] =
284d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{
285d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			{ 0,	refInRangeUpper,		1.6f,	2.9f,	-1.0f,	-2.7f	},
286d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			{ 0,	refInRangeLower,		-2.0f,	-1.35f,	-0.2f,	0.7f	},
287d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			{ 1,	refInRangeUpper,		0.14f,	0.275f,	-1.5f,	-1.1f	},
288d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			{ 1,	refInRangeLower,		-0.92f,	-2.64f,	0.4f,	-0.1f	},
289d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			{ 1,	refOutOfBoundsUpper,	-0.39f,	-0.52f,	0.65f,	0.87f	},
290d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			{ 1,	refOutOfBoundsLower,	-1.55f,	0.65f,	0.35f,	0.91f	},
291d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		};
292d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
293d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(cases); caseNdx++)
294d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{
295d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			const int	texNdx	= de::clamp(cases[caseNdx].texNdx, 0, (int)m_textures.size()-1);
296d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			const float ref		= cases[caseNdx].ref;
297d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			const float	lodX	= cases[caseNdx].lodX;
298d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			const float	lodY	= cases[caseNdx].lodY;
299d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			const float	oX		= cases[caseNdx].oX;
300d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			const float	oY		= cases[caseNdx].oY;
301d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			const float	sX		= deFloatExp2(lodX) * float(m_renderer.getRenderWidth()) / float(m_textures[texNdx]->getTexture().getWidth());
302d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			const float	sY		= deFloatExp2(lodY) * float(m_renderer.getRenderHeight()) / float(m_textures[texNdx]->getTexture().getHeight());
303d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
304d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			m_cases.push_back(FilterCase(texNdx, ref, tcu::Vec2(oX, oY), tcu::Vec2(oX+sX, oY+sY)));
305d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		}
306d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	}
307d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
308d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	m_caseNdx = 0;
309d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan}
310d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
311d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard LedanTexture2DShadowTestInstance::~Texture2DShadowTestInstance (void)
312d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan{
313d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	m_textures.clear();
314d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	m_cases.clear();
315d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan}
316d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
317d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledantcu::TestStatus Texture2DShadowTestInstance::iterate (void)
318d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan{
319d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	tcu::TestLog&					log				= m_context.getTestContext().getLog();
320d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	const pipeline::TestTexture2D&	texture			= m_renderer.get2DTexture(m_cases[m_caseNdx].textureIndex);
321d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	const tcu::TextureFormat		texFmt			= texture.getTextureFormat();
322d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	const tcu::TextureFormatInfo	fmtInfo			= tcu::getTextureFormatInfo(texFmt);
323d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	const tcu::ScopedLogSection		section			(log, string("Test") + de::toString(m_caseNdx), string("Test ") + de::toString(m_caseNdx));
324d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
325d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	const FilterCase&				curCase			= m_cases[m_caseNdx];
326d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	ReferenceParams					sampleParams	(TEXTURETYPE_2D);
327d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	tcu::Surface					rendered		(m_renderer.getRenderWidth(), m_renderer.getRenderHeight());
328d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	vector<float>					texCoord;
329d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
330d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	// Setup params for reference.
331d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	sampleParams.sampler			= util::createSampler(m_testParameters.wrapS, m_testParameters.wrapT, m_testParameters.minFilter, m_testParameters.magFilter);
332d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	sampleParams.sampler.compare	= m_testParameters.compareOp;
333d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	sampleParams.samplerType		= SAMPLERTYPE_SHADOW;
334d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	sampleParams.lodMode			= LODMODE_EXACT;
335d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	sampleParams.colorBias			= fmtInfo.lookupBias;
336d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	sampleParams.colorScale			= fmtInfo.lookupScale;
337d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	sampleParams.ref				= curCase.ref;
338d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
339d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	log << TestLog::Message << "Compare reference value = " << sampleParams.ref << TestLog::EndMessage;
340d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
341d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	// Compute texture coordinates.
342d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	log << TestLog::Message << "Texture coordinates: " << curCase.minCoord << " -> " << curCase.maxCoord << TestLog::EndMessage;
343d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	computeQuadTexCoord2D(texCoord, curCase.minCoord, curCase.maxCoord);
344d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
345d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	m_renderer.renderQuad(rendered, curCase.textureIndex, &texCoord[0], sampleParams);
346d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
347d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	{
348d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		const tcu::PixelFormat		pixelFormat			= getPixelFormat(vk::mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM));
349433645782506cbdf8fa8b113ea0b5aa8ae761f0cPyry Haulos		tcu::LodPrecision			lodPrecision;
350d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		tcu::TexComparePrecision	texComparePrecision;
351d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
352d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		lodPrecision.derivateBits			= 18;
353d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		lodPrecision.lodBits				= 6;
354d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		texComparePrecision.coordBits		= tcu::IVec3(20,20,0);
355d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		texComparePrecision.uvwBits			= tcu::IVec3(7,7,0);
356d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		texComparePrecision.pcfBits			= 5;
357d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		texComparePrecision.referenceBits	= 16;
358d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		texComparePrecision.resultBits		= pixelFormat.redBits-1;
359d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
360d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		const bool isHighQuality = verifyTexCompareResult(m_context.getTestContext(), rendered.getAccess(), texture.getTexture(),
361d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan														  &texCoord[0], sampleParams, texComparePrecision, lodPrecision, pixelFormat);
362d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
363d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		if (!isHighQuality)
364d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{
365d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			m_context.getTestContext().getLog() << TestLog::Message << "Warning: Verification assuming high-quality PCF filtering failed." << TestLog::EndMessage;
366d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
367d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			lodPrecision.lodBits			= 4;
368d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			texComparePrecision.uvwBits		= tcu::IVec3(4,4,0);
369d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			texComparePrecision.pcfBits		= 0;
370d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
371d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			const bool isOk = verifyTexCompareResult(m_context.getTestContext(), rendered.getAccess(), texture.getTexture(),
372d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan													 &texCoord[0], sampleParams, texComparePrecision, lodPrecision, pixelFormat);
373d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
374d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			if (!isOk)
375d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			{
376d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan				m_context.getTestContext().getLog() << TestLog::Message << "ERROR: Verification against low precision requirements failed, failing test case." << TestLog::EndMessage;
377d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan				return tcu::TestStatus::fail("Image verification failed");
378d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			}
379d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		}
380d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	}
381d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
382d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	m_caseNdx += 1;
383d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	return m_caseNdx < (int)m_cases.size() ? tcu::TestStatus::incomplete() : tcu::TestStatus::pass("Pass");
384d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan}
385d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
386d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledanstruct TextureCubeShadowTestCaseParameters : public TextureShadowCommonTestCaseParameters, public TextureCubeTestCaseParameters
387d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan{
388d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan};
389d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
390d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledanclass TextureCubeShadowTestInstance : public TestInstance
391d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan{
392d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledanpublic:
393d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	typedef TextureCubeShadowTestCaseParameters ParameterType;
394d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan												TextureCubeShadowTestInstance		(Context& context, const ParameterType& testParameters);
395d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan												~TextureCubeShadowTestInstance		(void);
396d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
397d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	virtual tcu::TestStatus						iterate								(void);
398d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
399d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledanprivate:
400d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan												TextureCubeShadowTestInstance		(const TextureCubeShadowTestInstance& other);
401d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	TextureCubeShadowTestInstance&				operator=							(const TextureCubeShadowTestInstance& other);
402d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
403d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	struct FilterCase
404d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	{
405d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		int						textureIndex;
406d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		tcu::Vec2				bottomLeft;
407d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		tcu::Vec2				topRight;
408d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		float					ref;
409d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
410d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		FilterCase (void)
411d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			: textureIndex	(-1)
412d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			, ref			(0.0f)
413d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{
414d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		}
415d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
416d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		FilterCase (const int tex_, const float ref_, const tcu::Vec2& bottomLeft_, const tcu::Vec2& topRight_)
417d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			: textureIndex	(tex_)
418d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			, bottomLeft	(bottomLeft_)
419d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			, topRight		(topRight_)
420d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			, ref			(ref_)
421d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{
422d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		}
423d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	};
424d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
425d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	const ParameterType&		m_testParameters;
426d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	vector<TestTextureCubeSp>	m_textures;
427d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	std::vector<FilterCase>		m_cases;
428d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
429d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	TextureRenderer				m_renderer;
430d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	int							m_caseNdx;
431d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan};
432d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
433d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard LedanTextureCubeShadowTestInstance::TextureCubeShadowTestInstance (Context& context, const ParameterType& testParameters)
434d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	: TestInstance			(context)
435d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	, m_testParameters		(testParameters)
436d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	, m_renderer			(context, testParameters.sampleCount, TEXCUBE_VIEWPORT_SIZE, TEXCUBE_VIEWPORT_SIZE)
437d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	, m_caseNdx				(0)
438d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan{
439d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	const int						numLevels	= deLog2Floor32(m_testParameters.size)+1;
440d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	const tcu::TextureFormatInfo	fmtInfo		= tcu::getTextureFormatInfo(vk::mapVkFormat(m_testParameters.format));
441d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	const tcu::Vec4					cBias		= fmtInfo.valueMin;
442d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	const tcu::Vec4					cScale		= fmtInfo.valueMax-fmtInfo.valueMin;
443d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
444d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	// Create textures.
445d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
446d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	m_textures.reserve(2);
447d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	for (int ndx = 0; ndx < 2; ndx++)
448d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	{
449d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		m_textures.push_back(TestTextureCubeSp(new pipeline::TestTextureCube(vk::mapVkFormat(m_testParameters.format), m_testParameters.size)));
450d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	}
451d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
452d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	// Fill first with gradient texture.
453d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	static const tcu::Vec4 gradients[tcu::CUBEFACE_LAST][2] =
454d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	{
455d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{ tcu::Vec4(-1.0f, -1.0f, -1.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // negative x
456d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{ tcu::Vec4( 0.0f, -1.0f, -1.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // positive x
457d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{ tcu::Vec4(-1.0f,  0.0f, -1.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // negative y
458d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{ tcu::Vec4(-1.0f, -1.0f,  0.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // positive y
459d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{ tcu::Vec4(-1.0f, -1.0f, -1.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f) }, // negative z
460d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{ tcu::Vec4( 0.0f,  0.0f,  0.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }  // positive z
461d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	};
462d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
463d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	{
464d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
465d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{
466d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			tcu::fillWithComponentGradients(m_textures[0]->getLevel(levelNdx, face), gradients[face][0]*cScale + cBias, gradients[face][1]*cScale + cBias);
467d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		}
468d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	}
469d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
470d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	// Fill second with grid texture.
471d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
472d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	{
473d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
474d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{
475d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			const deUint32	step	= 0x00ffffff / (numLevels*tcu::CUBEFACE_LAST);
476d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			const deUint32	rgb		= step*levelNdx*face;
477d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			const deUint32	colorA	= 0xff000000 | rgb;
478d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			const deUint32	colorB	= 0xff000000 | ~rgb;
479d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
480d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			tcu::fillWithGrid(m_textures[1]->getLevel(levelNdx, face), 4, tcu::RGBA(colorA).toVec()*cScale + cBias, tcu::RGBA(colorB).toVec()*cScale + cBias);
481d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		}
482d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	}
483d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
484d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	// Upload.
485d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	for (vector<TestTextureCubeSp>::iterator i = m_textures.begin(); i != m_textures.end(); i++)
486d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	{
487d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		m_renderer.addCubeTexture(*i);
488d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	}
489d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
490d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	// Compute cases
491d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	{
492d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		const float refInRangeUpper		= (m_testParameters.compareOp == Sampler::COMPAREMODE_EQUAL || m_testParameters.compareOp == Sampler::COMPAREMODE_NOT_EQUAL) ? 1.0f : 0.5f;
493d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		const float refInRangeLower		= (m_testParameters.compareOp == Sampler::COMPAREMODE_EQUAL || m_testParameters.compareOp == Sampler::COMPAREMODE_NOT_EQUAL) ? 0.0f : 0.5f;
494d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		const float refOutOfBoundsUpper	= 1.1f;
495d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		const float refOutOfBoundsLower	= -0.1f;
496d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
497d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		m_cases.push_back(FilterCase(0,	refInRangeUpper,		tcu::Vec2(-1.25f, -1.2f),	tcu::Vec2(1.2f, 1.25f)));	// minification
498d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		m_cases.push_back(FilterCase(0,	refInRangeLower,		tcu::Vec2(0.8f, 0.8f),		tcu::Vec2(1.25f, 1.20f)));	// magnification
499d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		m_cases.push_back(FilterCase(1,	refInRangeUpper,		tcu::Vec2(-1.19f, -1.3f),	tcu::Vec2(1.1f, 1.35f)));	// minification
500d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		m_cases.push_back(FilterCase(1,	refInRangeLower,		tcu::Vec2(-1.2f, -1.1f),	tcu::Vec2(-0.8f, -0.8f)));	// magnification
501d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		m_cases.push_back(FilterCase(1,	refOutOfBoundsUpper,	tcu::Vec2(-0.61f, -0.1f),	tcu::Vec2(0.9f, 1.18f)));	// reference value clamp, upper
502d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		m_cases.push_back(FilterCase(1,	refOutOfBoundsLower,	tcu::Vec2(-0.75f, 1.0f),	tcu::Vec2(0.05f, 0.75f)));	// reference value clamp, lower
503d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	}
504d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan}
505d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
506d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard LedanTextureCubeShadowTestInstance::~TextureCubeShadowTestInstance	(void)
507d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan{
508d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan}
509d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
510d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledanstatic const char* getFaceDesc (const tcu::CubeFace face)
511d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan{
512d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	switch (face)
513d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	{
514d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		case tcu::CUBEFACE_NEGATIVE_X:	return "-X";
515d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		case tcu::CUBEFACE_POSITIVE_X:	return "+X";
516d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		case tcu::CUBEFACE_NEGATIVE_Y:	return "-Y";
517d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		case tcu::CUBEFACE_POSITIVE_Y:	return "+Y";
518d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		case tcu::CUBEFACE_NEGATIVE_Z:	return "-Z";
519d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		case tcu::CUBEFACE_POSITIVE_Z:	return "+Z";
520d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		default:
521d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			DE_ASSERT(false);
522d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			return DE_NULL;
523d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	}
524d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan}
525d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
526d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledantcu::TestStatus TextureCubeShadowTestInstance::iterate (void)
527d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan{
528d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
529d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	tcu::TestLog&						log				= m_context.getTestContext().getLog();
530d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	const tcu::ScopedLogSection			iterSection		(log, string("Test") + de::toString(m_caseNdx), string("Test ") + de::toString(m_caseNdx));
531d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	const FilterCase&					curCase			= m_cases[m_caseNdx];
532d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	const pipeline::TestTextureCube&	texture			= m_renderer.getCubeTexture(curCase.textureIndex);
533d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
534d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	ReferenceParams						sampleParams	(TEXTURETYPE_CUBE);
535d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
536d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	// Params for reference computation.
537d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	sampleParams.sampler					= util::createSampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, m_testParameters.minFilter, m_testParameters.magFilter);
538d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	sampleParams.sampler.seamlessCubeMap	= true;
539d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	sampleParams.sampler.compare			= m_testParameters.compareOp;
540d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	sampleParams.samplerType				= SAMPLERTYPE_SHADOW;
541d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	sampleParams.lodMode					= LODMODE_EXACT;
542d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	sampleParams.ref						= curCase.ref;
543d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
544d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	log	<< TestLog::Message
545d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		<< "Compare reference value = " << sampleParams.ref << "\n"
546d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		<< "Coordinates: " << curCase.bottomLeft << " -> " << curCase.topRight
547d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		<< TestLog::EndMessage;
548d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
549d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
550d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	{
551d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		const tcu::CubeFace		face		= tcu::CubeFace(faceNdx);
552d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		tcu::Surface			result		(m_renderer.getRenderWidth(), m_renderer.getRenderHeight());
553d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		vector<float>			texCoord;
554d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
555d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		computeQuadTexCoordCube(texCoord, face, curCase.bottomLeft, curCase.topRight);
556d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
557d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		log << TestLog::Message << "Face " << getFaceDesc(face) << TestLog::EndMessage;
558d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
559d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		// \todo Log texture coordinates.
560d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
561d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		m_renderer.renderQuad(result, curCase.textureIndex, &texCoord[0], sampleParams);
562d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
563d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{
564d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			const tcu::PixelFormat		pixelFormat			= getPixelFormat(vk::mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM));
565433645782506cbdf8fa8b113ea0b5aa8ae761f0cPyry Haulos			tcu::LodPrecision			lodPrecision;
566d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			tcu::TexComparePrecision	texComparePrecision;
567d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
568d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			lodPrecision.derivateBits			= 10;
569d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			lodPrecision.lodBits				= 5;
570d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			texComparePrecision.coordBits		= tcu::IVec3(10,10,10);
571d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			texComparePrecision.uvwBits			= tcu::IVec3(6,6,0);
572d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			texComparePrecision.pcfBits			= 5;
573d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			texComparePrecision.referenceBits	= 16;
574d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			texComparePrecision.resultBits		= pixelFormat.redBits-1;
575d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
576d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			const bool isHighQuality = verifyTexCompareResult(m_context.getTestContext(), result.getAccess(), texture.getTexture(),
577d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan															  &texCoord[0], sampleParams, texComparePrecision, lodPrecision, pixelFormat);
578d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
579d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			if (!isHighQuality)
580d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			{
581d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan				log << TestLog::Message << "Warning: Verification assuming high-quality PCF filtering failed." << TestLog::EndMessage;
582d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
583d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan				lodPrecision.lodBits			= 4;
584d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan				texComparePrecision.uvwBits		= tcu::IVec3(4,4,0);
585d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan				texComparePrecision.pcfBits		= 0;
586d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
587d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan				const bool isOk = verifyTexCompareResult(m_context.getTestContext(), result.getAccess(), texture.getTexture(),
588d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan														 &texCoord[0], sampleParams, texComparePrecision, lodPrecision, pixelFormat);
589d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
590d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan				if (!isOk)
591d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan				{
592d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan					log << TestLog::Message << "ERROR: Verification against low precision requirements failed, failing test case." << TestLog::EndMessage;
593d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan					return tcu::TestStatus::fail("Image verification failed");
594d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan				}
595d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			}
596d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		}
597d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	}
598d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
599d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	m_caseNdx += 1;
600d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	return m_caseNdx < (int)m_cases.size() ? tcu::TestStatus::incomplete() : tcu::TestStatus::pass("Pass");
601d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan}
602d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
603d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledanstruct Texture2DArrayShadowTestCaseParameters : public TextureShadowCommonTestCaseParameters, public Texture2DArrayTestCaseParameters
604d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan{
605d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan};
606d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
607d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledanclass Texture2DArrayShadowTestInstance : public TestInstance
608d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan{
609d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledanpublic:
610d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	typedef Texture2DArrayShadowTestCaseParameters	ParameterType;
611d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan													Texture2DArrayShadowTestInstance		(Context& context, const ParameterType& testParameters);
612d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan													~Texture2DArrayShadowTestInstance		(void);
613d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
614d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	virtual tcu::TestStatus							iterate									(void);
615d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
616d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledanprivate:
617d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan													Texture2DArrayShadowTestInstance		(const Texture2DArrayShadowTestInstance& other);
618d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	Texture2DArrayShadowTestInstance&				operator=								(const Texture2DArrayShadowTestInstance& other);
619d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
620d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	struct FilterCase
621d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	{
622d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		int							textureIndex;
623d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		tcu::Vec3					minCoord;
624d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		tcu::Vec3					maxCoord;
625d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		float						ref;
626d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
627d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		FilterCase (void)
628d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			: textureIndex	(-1)
629d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			, ref			(0.0f)
630d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{
631d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		}
632d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
633d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		FilterCase (const int tex_, float ref_, const tcu::Vec3& minCoord_, const tcu::Vec3& maxCoord_)
634d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			: textureIndex	(tex_)
635d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			, minCoord		(minCoord_)
636d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			, maxCoord		(maxCoord_)
637d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			, ref			(ref_)
638d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{
639d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		}
640d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	};
641d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
642d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	const ParameterType&				m_testParameters;
643d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	std::vector<TestTexture2DArraySp>	m_textures;
644d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	std::vector<FilterCase>				m_cases;
645d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
646d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	TextureRenderer						m_renderer;
647d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
648d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	int									m_caseNdx;
649d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan};
650d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
651d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard LedanTexture2DArrayShadowTestInstance::Texture2DArrayShadowTestInstance (Context& context, const ParameterType& testParameters)
652d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	: TestInstance			(context)
653d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	, m_testParameters		(testParameters)
654d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	, m_renderer			(context, testParameters.sampleCount, TEX2D_VIEWPORT_WIDTH, TEX2D_VIEWPORT_HEIGHT)
655d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	, m_caseNdx				(0)
656d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan{
657d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	const int						numLevels	= deLog2Floor32(de::max(m_testParameters.width, m_testParameters.height))+1;
658d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	const tcu::TextureFormatInfo	fmtInfo		= tcu::getTextureFormatInfo(vk::mapVkFormat(m_testParameters.format));
659d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	const tcu::Vec4					cScale		= fmtInfo.valueMax-fmtInfo.valueMin;
660d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	const tcu::Vec4					cBias		= fmtInfo.valueMin;
661d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
662d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	// Create 2 textures.
663d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	m_textures.reserve(2);
664d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	for (int ndx = 0; ndx < 2; ndx++)
665d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	{
666d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		m_textures.push_back(TestTexture2DArraySp(new pipeline::TestTexture2DArray(vk::mapVkFormat(m_testParameters.format), m_testParameters.width, m_testParameters.height, m_testParameters.numLayers)));
667d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	}
668d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
669d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	// Fill first gradient texture.
670d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
671d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	{
672d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		const tcu::Vec4 gMin = tcu::Vec4(-0.5f, -0.5f, -0.5f, 2.0f)*cScale + cBias;
673d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		const tcu::Vec4 gMax = tcu::Vec4( 1.0f,  1.0f,  1.0f, 0.0f)*cScale + cBias;
674d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
675d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		tcu::fillWithComponentGradients(m_textures[0]->getTexture().getLevel(levelNdx), gMin, gMax);
676d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	}
677d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
678d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	// Fill second with grid texture.
679d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
680d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	{
681d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		const deUint32	step	= 0x00ffffff / numLevels;
682d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		const deUint32	rgb		= step*levelNdx;
683d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		const deUint32	colorA	= 0xff000000 | rgb;
684d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		const deUint32	colorB	= 0xff000000 | ~rgb;
685d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
686d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		tcu::fillWithGrid(m_textures[1]->getTexture().getLevel(levelNdx), 4, tcu::RGBA(colorA).toVec()*cScale + cBias, tcu::RGBA(colorB).toVec()*cScale + cBias);
687d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	}
688d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
689d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	// Upload.
690d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	for (std::vector<TestTexture2DArraySp>::iterator i = m_textures.begin(); i != m_textures.end(); ++i)
691d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	{
692d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		m_renderer.add2DArrayTexture(*i);
693d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	}
694d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
695d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	// Compute cases.
696d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	{
697d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		const float refInRangeUpper		= (m_testParameters.compareOp == Sampler::COMPAREMODE_EQUAL || m_testParameters.compareOp == Sampler::COMPAREMODE_NOT_EQUAL) ? 1.0f : 0.5f;
698d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		const float refInRangeLower		= (m_testParameters.compareOp == Sampler::COMPAREMODE_EQUAL || m_testParameters.compareOp == Sampler::COMPAREMODE_NOT_EQUAL) ? 0.0f : 0.5f;
699d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		const float refOutOfBoundsUpper	= 1.1f;		// !< lookup function should clamp values to [0, 1] range
700d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		const float refOutOfBoundsLower	= -0.1f;
701d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
702d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		const struct
703d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{
704d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			const int	texNdx;
705d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			const float	ref;
706d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			const float	lodX;
707d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			const float	lodY;
708d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			const float	oX;
709d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			const float	oY;
710d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		} cases[] =
711d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{
712d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			{ 0,	refInRangeUpper,		1.6f,	2.9f,	-1.0f,	-2.7f	},
713d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			{ 0,	refInRangeLower,		-2.0f,	-1.35f,	-0.2f,	0.7f	},
714d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			{ 1,	refInRangeUpper,		0.14f,	0.275f,	-1.5f,	-1.1f	},
715d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			{ 1,	refInRangeLower,		-0.92f,	-2.64f,	0.4f,	-0.1f	},
716d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			{ 1,	refOutOfBoundsUpper,	-0.49f,	-0.22f,	0.45f,	0.97f	},
717d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			{ 1,	refOutOfBoundsLower,	-0.85f,	0.75f,	0.25f,	0.61f	},
718d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		};
719d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
720d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		const float	minLayer	= -0.5f;
721d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		const float	maxLayer	= (float)m_testParameters.numLayers;
722d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
723d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(cases); caseNdx++)
724d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{
725d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			const int	tex		= cases[caseNdx].texNdx > 0 ? 1 : 0;
726d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			const float	ref		= cases[caseNdx].ref;
727d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			const float	lodX	= cases[caseNdx].lodX;
728d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			const float	lodY	= cases[caseNdx].lodY;
729d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			const float	oX		= cases[caseNdx].oX;
730d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			const float	oY		= cases[caseNdx].oY;
731d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			const float	sX		= deFloatExp2(lodX) * float(m_renderer.getRenderWidth()) / float(m_textures[tex]->getTexture().getWidth());
732d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			const float	sY		= deFloatExp2(lodY) * float(m_renderer.getRenderHeight()) / float(m_textures[tex]->getTexture().getHeight());
733d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
734d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			m_cases.push_back(FilterCase(tex, ref, tcu::Vec3(oX, oY, minLayer), tcu::Vec3(oX+sX, oY+sY, maxLayer)));
735d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		}
736d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	}
737d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan}
738d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
739d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard LedanTexture2DArrayShadowTestInstance::~Texture2DArrayShadowTestInstance (void)
740d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan{
741d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan}
742d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
743d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledantcu::TestStatus Texture2DArrayShadowTestInstance::iterate (void)
744d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan{
745d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	tcu::TestLog&						log				= m_context.getTestContext().getLog();
746d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	const FilterCase&					curCase			= m_cases[m_caseNdx];
747d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	const pipeline::TestTexture2DArray&	texture			= m_renderer.get2DArrayTexture(curCase.textureIndex);
748d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
749d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	ReferenceParams						sampleParams	(TEXTURETYPE_2D_ARRAY);
750d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	tcu::Surface						rendered		(m_renderer.getRenderWidth(), m_renderer.getRenderHeight());
751d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	const tcu::ScopedLogSection			section			(log, string("Test") + de::toString(m_caseNdx), string("Test ") + de::toString(m_caseNdx));
752d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
753d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	const float							texCoord[]		=
754d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	{
755d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		curCase.minCoord.x(), curCase.minCoord.y(), curCase.minCoord.z(),
756d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		curCase.minCoord.x(), curCase.maxCoord.y(), (curCase.minCoord.z() + curCase.maxCoord.z()) / 2.0f,
757d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		curCase.maxCoord.x(), curCase.minCoord.y(), (curCase.minCoord.z() + curCase.maxCoord.z()) / 2.0f,
758d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		curCase.maxCoord.x(), curCase.maxCoord.y(), curCase.maxCoord.z()
759d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	};
760d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
761d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	// Setup params for reference.
762d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	sampleParams.sampler			= util::createSampler(m_testParameters.wrapS, m_testParameters.wrapT, m_testParameters.minFilter, m_testParameters.magFilter);
763d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	sampleParams.sampler.compare	= m_testParameters.compareOp;
764d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	sampleParams.samplerType		= SAMPLERTYPE_SHADOW;
765d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	sampleParams.lodMode			= LODMODE_EXACT;
766d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	sampleParams.ref				= curCase.ref;
767d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
768d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	log	<< TestLog::Message
769d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		<< "Compare reference value = " << sampleParams.ref << "\n"
770d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		<< "Texture coordinates: " << curCase.minCoord << " -> " << curCase.maxCoord
771d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		<< TestLog::EndMessage;
772d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
773d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	m_renderer.renderQuad(rendered, curCase.textureIndex, &texCoord[0], sampleParams);
774d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
775d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	{
776d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		const tcu::PixelFormat		pixelFormat			= getPixelFormat(vk::mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM));
777433645782506cbdf8fa8b113ea0b5aa8ae761f0cPyry Haulos		tcu::LodPrecision			lodPrecision;
778d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		tcu::TexComparePrecision	texComparePrecision;
779d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
780d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		lodPrecision.derivateBits			= 18;
781d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		lodPrecision.lodBits				= 6;
782d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		texComparePrecision.coordBits		= tcu::IVec3(20,20,20);
783d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		texComparePrecision.uvwBits			= tcu::IVec3(7,7,7);
784d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		texComparePrecision.pcfBits			= 5;
785d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		texComparePrecision.referenceBits	= 16;
786d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		texComparePrecision.resultBits		= pixelFormat.redBits-1;
787d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
788d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		const bool isHighQuality = verifyTexCompareResult(m_context.getTestContext(), rendered.getAccess(), texture.getTexture(),
789d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan														  &texCoord[0], sampleParams, texComparePrecision, lodPrecision, pixelFormat);
790d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
791d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		if (!isHighQuality)
792d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{
793d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			log << TestLog::Message << "Warning: Verification assuming high-quality PCF filtering failed." << TestLog::EndMessage;
794d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
795d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			lodPrecision.lodBits			= 4;
796d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			texComparePrecision.uvwBits		= tcu::IVec3(4,4,4);
797d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			texComparePrecision.pcfBits		= 0;
798d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
799d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			const bool isOk = verifyTexCompareResult(m_context.getTestContext(), rendered.getAccess(), texture.getTexture(),
800d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan													 &texCoord[0], sampleParams, texComparePrecision, lodPrecision, pixelFormat);
801d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
802d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			if (!isOk)
803d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			{
804d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan				log << TestLog::Message << "ERROR: Verification against low precision requirements failed, failing test case." << TestLog::EndMessage;
805d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan				return tcu::TestStatus::fail("Image verification failed");
806d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			}
807d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		}
808d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	}
809d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
810d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	m_caseNdx += 1;
811d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	return m_caseNdx < (int)m_cases.size() ? tcu::TestStatus::incomplete() : tcu::TestStatus::pass("Pass");
812d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan}
813d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
814d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledanvoid populateTextureShadowTests (tcu::TestCaseGroup* textureShadowTests)
815d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan{
816d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	tcu::TestContext&				testCtx				= textureShadowTests->getTestContext();
817d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
818d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	static const struct
819d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	{
820d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		const char*		name;
821d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		const VkFormat	format;
822d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	} formats[] =
823d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	{
824d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{ "d16_unorm",				VK_FORMAT_D16_UNORM				},
825d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{ "x8_d24_unorm_pack32",	VK_FORMAT_X8_D24_UNORM_PACK32	},
826d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{ "d32_sfloat",				VK_FORMAT_D32_SFLOAT			},
827d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{ "d16_unorm_s8_uint",		VK_FORMAT_D16_UNORM_S8_UINT		},
828d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{ "d24_unorm_s8_uint",		VK_FORMAT_D24_UNORM_S8_UINT		},
829d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{ "d32_sfloat_s8_uint",		VK_FORMAT_D32_SFLOAT_S8_UINT	}
830d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	};
831d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
832d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	static const struct
833d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	{
834d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		const char*					name;
835d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		const Sampler::FilterMode	minFilter;
836d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		const Sampler::FilterMode	magFilter;
837d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	} filters[] =
838d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	{
839d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{ "nearest",				Sampler::NEAREST,					Sampler::NEAREST	},
840d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{ "linear",					Sampler::LINEAR,					Sampler::LINEAR		},
841d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{ "nearest_mipmap_nearest",	Sampler::NEAREST_MIPMAP_NEAREST,	Sampler::LINEAR		},
842d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{ "linear_mipmap_nearest",	Sampler::LINEAR_MIPMAP_NEAREST,		Sampler::LINEAR		},
843d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{ "nearest_mipmap_linear",	Sampler::NEAREST_MIPMAP_LINEAR,		Sampler::LINEAR		},
844d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{ "linear_mipmap_linear",	Sampler::LINEAR_MIPMAP_LINEAR,		Sampler::LINEAR		}
845d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	};
846d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
847d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	static const struct
848d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	{
849d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		const char*					name;
850d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		const Sampler::CompareMode	op;
851d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	} compareOp[] =
852d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	{
853d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{ "less_or_equal",		Sampler::COMPAREMODE_LESS_OR_EQUAL		},
854d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{ "greater_or_equal",	Sampler::COMPAREMODE_GREATER_OR_EQUAL	},
855d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{ "less",				Sampler::COMPAREMODE_LESS				},
856d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{ "greater",			Sampler::COMPAREMODE_GREATER			},
857d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{ "equal",				Sampler::COMPAREMODE_EQUAL				},
858d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{ "not_equal",			Sampler::COMPAREMODE_NOT_EQUAL			},
859d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{ "always",				Sampler::COMPAREMODE_ALWAYS				},
860d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{ "never",				Sampler::COMPAREMODE_NEVER				}
861d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	};
862d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
863d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	// 2D cases.
864d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	{
865d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		de::MovePtr<tcu::TestCaseGroup>	group2D	(new tcu::TestCaseGroup(testCtx, "2d", "2D texture shadow lookup tests"));
866d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
867d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(filters); filterNdx++)
868d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{
869d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			de::MovePtr<tcu::TestCaseGroup>	filterGroup	(new tcu::TestCaseGroup(testCtx, filters[filterNdx].name, ""));
870d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
871d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			for (int compareNdx = 0; compareNdx < DE_LENGTH_OF_ARRAY(compareOp); compareNdx++)
872d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			{
873d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan				for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
874d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan				{
875d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan					const string						name			= string(compareOp[compareNdx].name) + "_" + formats[formatNdx].name;
876d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan					Texture2DShadowTestCaseParameters	testParameters;
877d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
878d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan					testParameters.minFilter	= filters[filterNdx].minFilter;
879d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan					testParameters.magFilter	= filters[filterNdx].magFilter;
880d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan					testParameters.format		= formats[formatNdx].format;
881d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan					testParameters.compareOp	= compareOp[compareNdx].op;
882d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan					testParameters.wrapS		= Sampler::REPEAT_GL;
883d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan					testParameters.wrapT		= Sampler::REPEAT_GL;
884d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan					testParameters.width		= 32;
885d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan					testParameters.height		= 64;
886d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
887d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan					testParameters.programs.push_back(PROGRAM_2D_SHADOW);
888d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
889d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan					filterGroup->addChild(new TextureTestCase<Texture2DShadowTestInstance>(testCtx, name.c_str(), "", testParameters));
890d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan				}
891d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			}
892d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
893d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			group2D->addChild(filterGroup.release());
894d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		}
895d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
896d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		textureShadowTests->addChild(group2D.release());
897d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	}
898d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
899d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	// Cubemap cases.
900d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	{
901d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		de::MovePtr<tcu::TestCaseGroup>	groupCube	(new tcu::TestCaseGroup(testCtx, "cube", "Cube map texture shadow lookup tests"));
902d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
903d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(filters); filterNdx++)
904d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{
905d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			de::MovePtr<tcu::TestCaseGroup>	filterGroup	(new tcu::TestCaseGroup(testCtx, filters[filterNdx].name, ""));
906d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
907d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			for (int compareNdx = 0; compareNdx < DE_LENGTH_OF_ARRAY(compareOp); compareNdx++)
908d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			{
909d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan				for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
910d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan				{
911d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan					const string							name			= string(compareOp[compareNdx].name) + "_" + formats[formatNdx].name;
912d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan					TextureCubeShadowTestCaseParameters		testParameters;
913d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
914d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan					testParameters.minFilter	= filters[filterNdx].minFilter;
915d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan					testParameters.magFilter	= filters[filterNdx].magFilter;
916d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan					testParameters.format		= formats[formatNdx].format;
917d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan					testParameters.compareOp	= compareOp[compareNdx].op;
918d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan					testParameters.wrapS		= Sampler::REPEAT_GL;
919d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan					testParameters.wrapT		= Sampler::REPEAT_GL;
920d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan					testParameters.size			= 32;
921d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
922d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan					testParameters.programs.push_back(PROGRAM_CUBE_SHADOW);
923d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
924d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan					filterGroup->addChild(new TextureTestCase<TextureCubeShadowTestInstance>(testCtx, name.c_str(), "", testParameters));
925d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan				}
926d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			}
927d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
928d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			groupCube->addChild(filterGroup.release());
929d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		}
930d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
931d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		textureShadowTests->addChild(groupCube.release());
932d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	}
933d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
934d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	// 2D array cases.
935d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	{
936d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		de::MovePtr<tcu::TestCaseGroup>	group2DArray	(new tcu::TestCaseGroup(testCtx, "2d_array", "2D texture array shadow lookup tests"));
937d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
938d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(filters); filterNdx++)
939d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		{
940d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			de::MovePtr<tcu::TestCaseGroup>	filterGroup	(new tcu::TestCaseGroup(testCtx, filters[filterNdx].name, ""));
941d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
942d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			for (int compareNdx = 0; compareNdx < DE_LENGTH_OF_ARRAY(compareOp); compareNdx++)
943d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			{
944d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan				for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
945d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan				{
946d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan					const string							name			= string(compareOp[compareNdx].name) + "_" + formats[formatNdx].name;
947d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan					Texture2DArrayShadowTestCaseParameters	testParameters;
948d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
949d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan					testParameters.minFilter	= filters[filterNdx].minFilter;
950d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan					testParameters.magFilter	= filters[filterNdx].magFilter;
951d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan					testParameters.format		= formats[formatNdx].format;
952d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan					testParameters.compareOp	= compareOp[compareNdx].op;
953d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan					testParameters.wrapS		= Sampler::REPEAT_GL;
954d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan					testParameters.wrapT		= Sampler::REPEAT_GL;
955d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan					testParameters.width		= 32;
956d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan					testParameters.height		= 64;
957d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan					testParameters.numLayers	= 8;
958d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
959d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan					testParameters.programs.push_back(PROGRAM_2D_ARRAY_SHADOW);
960d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
961d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan					filterGroup->addChild(new TextureTestCase<Texture2DArrayShadowTestInstance>(testCtx, name.c_str(), "", testParameters));
962d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan				}
963d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			}
964d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
965d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan			group2DArray->addChild(filterGroup.release());
966d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		}
967d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
968d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan		textureShadowTests->addChild(group2DArray.release());
969d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	}
970d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan}
971d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
972d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan} // anonymous
973d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
974d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledantcu::TestCaseGroup* createTextureShadowTests (tcu::TestContext& testCtx)
975d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan{
976d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan	return createTestGroup(testCtx, "shadow", "Texture shadow tests.", populateTextureShadowTests);
977d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan}
978d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan
979d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan} // texture
980d766ec7288478fd296695e6be1dc02b29b2de3aeSzilard Ledan} // vkt
981