1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright 2014 The Android Open Source Project
6 * Copyright (c) 2016 The Khronos Group Inc.
7 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
8 *
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 * http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 *
21 *//*!
22 * \file
23 * \brief Shadow texture lookup tests.
24 *//*--------------------------------------------------------------------*/
25
26 #include "vktTextureShadowTests.hpp"
27 #include "vktAmberTestCase.hpp"
28
29 #include "deMath.h"
30 #include "deString.h"
31 #include "deStringUtil.hpp"
32 #include "gluPixelTransfer.hpp"
33 #include "gluTextureTestUtil.hpp"
34 #include "glwEnums.hpp"
35 #include "glwFunctions.hpp"
36 #include "tcuImageIO.hpp"
37 #include "tcuRenderTarget.hpp"
38 #include "tcuTexCompareVerifier.hpp"
39 #include "tcuTexVerifierUtil.hpp"
40 #include "tcuTexture.hpp"
41 #include "tcuTextureUtil.hpp"
42 #include "tcuVectorUtil.hpp"
43 #include "vkImageUtil.hpp"
44 #include "vkTypeUtil.hpp"
45 #include "vktTestGroupUtil.hpp"
46 #include "vktTextureTestUtil.hpp"
47
48 using namespace vk;
49
50 namespace vkt
51 {
52 namespace texture
53 {
54 namespace
55 {
56
57 using std::vector;
58 using std::string;
59 using tcu::TestLog;
60 using tcu::Sampler;
61 using namespace texture::util;
62 using namespace glu::TextureTestUtil;
63
64 enum
65 {
66 TEXCUBE_VIEWPORT_SIZE = 28,
67 TEX1D_VIEWPORT_WIDTH = 64,
68 TEX2D_VIEWPORT_WIDTH = 64,
69 TEX2D_VIEWPORT_HEIGHT = 64
70 };
71
72 struct TextureShadowCommonTestCaseParameters
73 {
74 TextureShadowCommonTestCaseParameters (void);
75 Sampler::CompareMode compareOp;
76 TextureBinding::ImageBackingMode backingMode;
77 };
78
TextureShadowCommonTestCaseParameters(void)79 TextureShadowCommonTestCaseParameters::TextureShadowCommonTestCaseParameters (void)
80 : compareOp (Sampler::COMPAREMODE_EQUAL)
81 , backingMode (TextureBinding::IMAGE_BACKING_MODE_REGULAR)
82 {
83 }
84
85 struct Texture2DShadowTestCaseParameters : public Texture2DTestCaseParameters, public TextureShadowCommonTestCaseParameters
86 {
87 };
88
isFloatingPointDepthFormat(const tcu::TextureFormat & format)89 bool isFloatingPointDepthFormat (const tcu::TextureFormat& format)
90 {
91 // Only two depth and depth-stencil formats are floating point
92 return (format.order == tcu::TextureFormat::D && format.type == tcu::TextureFormat::FLOAT) ||
93 (format.order == tcu::TextureFormat::DS && format.type == tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV);
94 }
95
clampFloatingPointTexture(const tcu::PixelBufferAccess & access)96 void clampFloatingPointTexture (const tcu::PixelBufferAccess& access)
97 {
98 DE_ASSERT(isFloatingPointDepthFormat(access.getFormat()));
99
100 for (int z = 0; z < access.getDepth(); ++z)
101 for (int y = 0; y < access.getHeight(); ++y)
102 for (int x = 0; x < access.getWidth(); ++x)
103 access.setPixDepth(de::clamp(access.getPixDepth(x, y, z), 0.0f, 1.0f), x, y, z);
104 }
105
clampFloatingPointTexture(tcu::Texture2D & target)106 void clampFloatingPointTexture (tcu::Texture2D& target)
107 {
108 for (int level = 0; level < target.getNumLevels(); ++level)
109 if (!target.isLevelEmpty(level))
110 clampFloatingPointTexture(target.getLevel(level));
111 }
112
clampFloatingPointTexture(tcu::Texture2DArray & target)113 static void clampFloatingPointTexture (tcu::Texture2DArray& target)
114 {
115 for (int level = 0; level < target.getNumLevels(); ++level)
116 if (!target.isLevelEmpty(level))
117 clampFloatingPointTexture(target.getLevel(level));
118 }
119
clampFloatingPointTexture(tcu::TextureCube & target)120 void clampFloatingPointTexture (tcu::TextureCube& target)
121 {
122 for (int level = 0; level < target.getNumLevels(); ++level)
123 for (int face = tcu::CUBEFACE_NEGATIVE_X; face < tcu::CUBEFACE_LAST; ++face)
124 clampFloatingPointTexture(target.getLevelFace(level, (tcu::CubeFace)face));
125 }
126
clampFloatingPointTexture(tcu::Texture1D & target)127 void clampFloatingPointTexture (tcu::Texture1D& target)
128 {
129 for (int level = 0; level < target.getNumLevels(); ++level)
130 if (!target.isLevelEmpty(level))
131 clampFloatingPointTexture(target.getLevel(level));
132 }
133
clampFloatingPointTexture(tcu::Texture1DArray & target)134 static void clampFloatingPointTexture (tcu::Texture1DArray& target)
135 {
136 for (int level = 0; level < target.getNumLevels(); ++level)
137 if (!target.isLevelEmpty(level))
138 clampFloatingPointTexture(target.getLevel(level));
139 }
140
clampFloatingPointTexture(tcu::TextureCubeArray & target)141 void clampFloatingPointTexture (tcu::TextureCubeArray& target)
142 {
143 for (int level = 0; level < target.getNumLevels(); ++level)
144 clampFloatingPointTexture(target.getLevel(level)); // face and layer are inside level's depth
145 }
146
getPixelFormat(tcu::TextureFormat texFormat)147 tcu::PixelFormat getPixelFormat(tcu::TextureFormat texFormat)
148 {
149 const tcu::IVec4 formatBitDepth = tcu::getTextureFormatBitDepth(tcu::getEffectiveDepthStencilTextureFormat(texFormat, Sampler::MODE_DEPTH));
150 return tcu::PixelFormat(formatBitDepth[0], formatBitDepth[1], formatBitDepth[2], formatBitDepth[3]);
151 }
152
153 template<typename TextureType>
verifyTexCompareResult(tcu::TestContext & testCtx,const tcu::ConstPixelBufferAccess & result,const TextureType & src,const float * texCoord,const ReferenceParams & sampleParams,const tcu::TexComparePrecision & comparePrec,const tcu::LodPrecision & lodPrec,const tcu::PixelFormat & pixelFormat)154 bool verifyTexCompareResult (tcu::TestContext& testCtx,
155 const tcu::ConstPixelBufferAccess& result,
156 const TextureType& src,
157 const float* texCoord,
158 const ReferenceParams& sampleParams,
159 const tcu::TexComparePrecision& comparePrec,
160 const tcu::LodPrecision& lodPrec,
161 const tcu::PixelFormat& pixelFormat)
162 {
163 tcu::TestLog& log = testCtx.getLog();
164 tcu::Surface reference (result.getWidth(), result.getHeight());
165 tcu::Surface errorMask (result.getWidth(), result.getHeight());
166 const tcu::IVec4 nonShadowBits = tcu::max(getBitsVec(pixelFormat)-1, tcu::IVec4(0));
167 const tcu::Vec3 nonShadowThreshold = tcu::computeFixedPointThreshold(nonShadowBits).swizzle(1,2,3);
168 int numFailedPixels;
169
170 // sampleTexture() expects source image to be the same state as it would be in a GL implementation, that is
171 // the floating point depth values should be in [0, 1] range as data is clamped during texture upload. Since
172 // we don't have a separate "uploading" phase and just reuse the buffer we used for GL-upload, do the clamping
173 // here if necessary.
174
175 if (isFloatingPointDepthFormat(src.getFormat()))
176 {
177 TextureType clampedSource(src);
178
179 clampFloatingPointTexture(clampedSource);
180
181 // sample clamped values
182
183 sampleTexture(tcu::SurfaceAccess(reference, pixelFormat), clampedSource, texCoord, sampleParams);
184 numFailedPixels = computeTextureCompareDiff(result, reference.getAccess(), errorMask.getAccess(), clampedSource, texCoord, sampleParams, comparePrec, lodPrec, nonShadowThreshold);
185 }
186 else
187 {
188 // sample raw values (they are guaranteed to be in [0, 1] range as the format cannot represent any other values)
189
190 sampleTexture(tcu::SurfaceAccess(reference, pixelFormat), src, texCoord, sampleParams);
191 numFailedPixels = computeTextureCompareDiff(result, reference.getAccess(), errorMask.getAccess(), src, texCoord, sampleParams, comparePrec, lodPrec, nonShadowThreshold);
192 }
193
194 if (numFailedPixels > 0)
195 log << TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << TestLog::EndMessage;
196
197 log << TestLog::ImageSet("VerifyResult", "Verification result")
198 << TestLog::Image("Rendered", "Rendered image", result);
199
200 if (numFailedPixels > 0)
201 {
202 log << TestLog::Image("Reference", "Ideal reference image", reference)
203 << TestLog::Image("ErrorMask", "Error mask", errorMask);
204 }
205
206 log << TestLog::EndImageSet;
207
208 return numFailedPixels == 0;
209 }
210
211 #ifdef CTS_USES_VULKANSC
isDepthFormat(VkFormat format)212 bool isDepthFormat(VkFormat format)
213 {
214 if (isCompressedFormat(format))
215 return false;
216
217 if (isYCbCrFormat(format))
218 return false;
219
220 const tcu::TextureFormat tcuFormat = mapVkFormat(format);
221 return tcuFormat.order == tcu::TextureFormat::D || tcuFormat.order == tcu::TextureFormat::DS;
222 }
223 #endif // CTS_USES_VULKANSC
224
checkTextureSupport(Context & context,const Texture2DShadowTestCaseParameters & testParameters)225 void checkTextureSupport (Context& context, const Texture2DShadowTestCaseParameters& testParameters)
226 {
227 #ifndef CTS_USES_VULKANSC
228 const VkFormatProperties3 formatProperties = context.getFormatProperties(testParameters.format);
229 if (!(formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT_KHR))
230 TCU_THROW(NotSupportedError, "Format does not support shadow sampling");
231 #else
232 DE_UNREF(context);
233 if (!isDepthFormat(testParameters.format))
234 TCU_THROW(NotSupportedError, "Format cannot be used as depth format");
235 #endif // CTS_USES_VULKANSC
236 }
237
238 class Texture2DShadowTestInstance : public TestInstance
239 {
240 public:
241 typedef Texture2DShadowTestCaseParameters ParameterType;
242 Texture2DShadowTestInstance (Context& context, const ParameterType& testParameters);
243 ~Texture2DShadowTestInstance (void);
244
245 virtual tcu::TestStatus iterate (void);
246
247 private:
248 Texture2DShadowTestInstance (const Texture2DShadowTestInstance& other);
249 Texture2DShadowTestInstance& operator= (const Texture2DShadowTestInstance& other);
250
251 struct FilterCase
252 {
253 int textureIndex;
254
255 tcu::Vec2 minCoord;
256 tcu::Vec2 maxCoord;
257 float ref;
258
FilterCasevkt::texture::__anon433fb3630111::Texture2DShadowTestInstance::FilterCase259 FilterCase (void)
260 : textureIndex(-1)
261 , ref (0.0f)
262 {
263 }
264
FilterCasevkt::texture::__anon433fb3630111::Texture2DShadowTestInstance::FilterCase265 FilterCase (int tex_, const float ref_, const tcu::Vec2& minCoord_, const tcu::Vec2& maxCoord_)
266 : textureIndex (tex_)
267 , minCoord (minCoord_)
268 , maxCoord (maxCoord_)
269 , ref (ref_)
270 {
271 }
272 };
273
274 const ParameterType& m_testParameters;
275 std::vector<TestTexture2DSp> m_textures;
276 std::vector<FilterCase> m_cases;
277
278 TextureRenderer m_renderer;
279
280 int m_caseNdx;
281 };
282
Texture2DShadowTestInstance(Context & context,const ParameterType & testParameters)283 Texture2DShadowTestInstance::Texture2DShadowTestInstance (Context& context, const ParameterType& testParameters)
284 : TestInstance (context)
285 , m_testParameters (testParameters)
286 , m_renderer (context, testParameters.sampleCount, TEX2D_VIEWPORT_WIDTH, TEX2D_VIEWPORT_HEIGHT)
287 , m_caseNdx (0)
288 {
289 // Create 2 textures.
290 m_textures.reserve(2);
291 for (int ndx = 0; ndx < 2; ndx++)
292 {
293 m_textures.push_back(TestTexture2DSp(new pipeline::TestTexture2D(vk::mapVkFormat(m_testParameters.format), m_testParameters.width, m_testParameters.height)));
294 }
295
296 const int numLevels = m_textures[0]->getNumLevels();
297
298 // Fill first gradient texture.
299 for (int levelNdx = 0; levelNdx < numLevels; ++levelNdx)
300 {
301 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));
302 }
303
304 // Fill second with grid texture.
305 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
306 {
307 const deUint32 step = 0x00ffffff / numLevels;
308 const deUint32 rgb = step*levelNdx;
309 const deUint32 colorA = 0xff000000 | rgb;
310 const deUint32 colorB = 0xff000000 | ~rgb;
311
312 tcu::fillWithGrid(m_textures[1]->getLevel(levelNdx, 0), 4, tcu::RGBA(colorA).toVec(), tcu::RGBA(colorB).toVec());
313 }
314
315 // Upload.
316 for (std::vector<TestTexture2DSp>::iterator i = m_textures.begin(); i != m_textures.end(); ++i)
317 {
318 m_renderer.add2DTexture(*i, m_testParameters.aspectMask, m_testParameters.backingMode);
319 }
320
321 // Compute cases.
322 {
323 const float refInRangeUpper = (m_testParameters.compareOp == Sampler::COMPAREMODE_EQUAL || m_testParameters.compareOp == Sampler::COMPAREMODE_NOT_EQUAL) ? 1.0f : 0.5f;
324 const float refInRangeLower = (m_testParameters.compareOp == Sampler::COMPAREMODE_EQUAL || m_testParameters.compareOp == Sampler::COMPAREMODE_NOT_EQUAL) ? 0.0f : 0.5f;
325 const float refOutOfBoundsUpper = 1.1f; // !< lookup function should clamp values to [0, 1] range
326 const float refOutOfBoundsLower = -0.1f;
327
328 const struct
329 {
330 const int texNdx;
331 const float ref;
332 const float lodX;
333 const float lodY;
334 const float oX;
335 const float oY;
336 } cases[] =
337 {
338 { 0, refInRangeUpper, 1.6f, 2.9f, -1.0f, -2.7f },
339 { 0, refInRangeLower, -2.0f, -1.35f, -0.2f, 0.7f },
340 { 1, refInRangeUpper, 0.14f, 0.275f, -1.5f, -1.1f },
341 { 1, refInRangeLower, -0.92f, -2.64f, 0.4f, -0.1f },
342 { 1, refOutOfBoundsUpper, -0.39f, -0.52f, 0.65f, 0.87f },
343 { 1, refOutOfBoundsLower, -1.55f, 0.65f, 0.35f, 0.91f },
344 };
345
346 for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(cases); caseNdx++)
347 {
348 const int texNdx = de::clamp(cases[caseNdx].texNdx, 0, (int)m_textures.size()-1);
349 const float ref = cases[caseNdx].ref;
350 const float lodX = cases[caseNdx].lodX;
351 const float lodY = cases[caseNdx].lodY;
352 const float oX = cases[caseNdx].oX;
353 const float oY = cases[caseNdx].oY;
354 const float sX = deFloatExp2(lodX) * float(m_renderer.getRenderWidth()) / float(m_textures[texNdx]->getTexture().getWidth());
355 const float sY = deFloatExp2(lodY) * float(m_renderer.getRenderHeight()) / float(m_textures[texNdx]->getTexture().getHeight());
356
357 m_cases.push_back(FilterCase(texNdx, ref, tcu::Vec2(oX, oY), tcu::Vec2(oX+sX, oY+sY)));
358 }
359 }
360
361 m_caseNdx = 0;
362 }
363
~Texture2DShadowTestInstance(void)364 Texture2DShadowTestInstance::~Texture2DShadowTestInstance (void)
365 {
366 m_textures.clear();
367 m_cases.clear();
368 }
369
iterate(void)370 tcu::TestStatus Texture2DShadowTestInstance::iterate (void)
371 {
372 tcu::TestLog& log = m_context.getTestContext().getLog();
373 const pipeline::TestTexture2D& texture = m_renderer.get2DTexture(m_cases[m_caseNdx].textureIndex);
374 const tcu::TextureFormat texFmt = texture.getTextureFormat();
375 const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(texFmt);
376 const tcu::ScopedLogSection section (log, string("Test") + de::toString(m_caseNdx), string("Test ") + de::toString(m_caseNdx));
377
378 const FilterCase& curCase = m_cases[m_caseNdx];
379 ReferenceParams sampleParams (TEXTURETYPE_2D);
380 tcu::Surface rendered (m_renderer.getRenderWidth(), m_renderer.getRenderHeight());
381 vector<float> texCoord;
382
383 // Setup params for reference.
384 sampleParams.sampler = util::createSampler(m_testParameters.wrapS, m_testParameters.wrapT, m_testParameters.minFilter, m_testParameters.magFilter);
385 sampleParams.sampler.compare = m_testParameters.compareOp;
386 sampleParams.samplerType = SAMPLERTYPE_SHADOW;
387 sampleParams.lodMode = LODMODE_EXACT;
388 sampleParams.colorBias = fmtInfo.lookupBias;
389 sampleParams.colorScale = fmtInfo.lookupScale;
390 sampleParams.ref = curCase.ref;
391
392 log << TestLog::Message << "Compare reference value = " << sampleParams.ref << TestLog::EndMessage;
393
394 // Compute texture coordinates.
395 log << TestLog::Message << "Texture coordinates: " << curCase.minCoord << " -> " << curCase.maxCoord << TestLog::EndMessage;
396 computeQuadTexCoord2D(texCoord, curCase.minCoord, curCase.maxCoord);
397
398 m_renderer.renderQuad(rendered, curCase.textureIndex, &texCoord[0], sampleParams);
399
400 {
401 const tcu::PixelFormat pixelFormat = getPixelFormat(vk::mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM));
402 tcu::LodPrecision lodPrecision;
403 tcu::TexComparePrecision texComparePrecision;
404
405 lodPrecision.derivateBits = 18;
406 lodPrecision.lodBits = 6;
407 texComparePrecision.coordBits = tcu::IVec3(20,20,0);
408 texComparePrecision.uvwBits = tcu::IVec3(7,7,0);
409 texComparePrecision.pcfBits = 5;
410 texComparePrecision.referenceBits = 16;
411 texComparePrecision.resultBits = pixelFormat.redBits-1;
412
413 #ifdef CTS_USES_VULKANSC
414 if (m_context.getTestContext().getCommandLine().isSubProcess())
415 #endif // CTS_USES_VULKANSC
416 {
417 const bool isHighQuality = verifyTexCompareResult(m_context.getTestContext(), rendered.getAccess(), texture.getTexture(),
418 &texCoord[0], sampleParams, texComparePrecision, lodPrecision, pixelFormat);
419
420 if (!isHighQuality)
421 {
422 m_context.getTestContext().getLog() << TestLog::Message << "Warning: Verification assuming high-quality PCF filtering failed." << TestLog::EndMessage;
423
424 lodPrecision.lodBits = 4;
425 texComparePrecision.uvwBits = tcu::IVec3(4,4,0);
426 texComparePrecision.pcfBits = 0;
427
428 const bool isOk = verifyTexCompareResult(m_context.getTestContext(), rendered.getAccess(), texture.getTexture(),
429 &texCoord[0], sampleParams, texComparePrecision, lodPrecision, pixelFormat);
430
431 if (!isOk)
432 {
433 m_context.getTestContext().getLog() << TestLog::Message << "ERROR: Verification against low precision requirements failed, failing test case." << TestLog::EndMessage;
434 return tcu::TestStatus::fail("Image verification failed");
435 }
436 }
437 }
438 }
439
440 m_caseNdx += 1;
441 return m_caseNdx < (int)m_cases.size() ? tcu::TestStatus::incomplete() : tcu::TestStatus::pass("Pass");
442 }
443
444 struct TextureCubeShadowTestCaseParameters : public TextureShadowCommonTestCaseParameters, public TextureCubeTestCaseParameters
445 {
446 };
447
checkTextureSupport(Context & context,const TextureCubeShadowTestCaseParameters & testParameters)448 void checkTextureSupport (Context& context, const TextureCubeShadowTestCaseParameters& testParameters)
449 {
450 #ifndef CTS_USES_VULKANSC
451 const VkFormatProperties3 formatProperties = context.getFormatProperties(testParameters.format);
452 if (!(formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT_KHR))
453 TCU_THROW(NotSupportedError, "Format does not support shadow sampling");
454 if (!testParameters.seamless)
455 context.requireDeviceFunctionality("VK_EXT_non_seamless_cube_map");
456 #else
457 DE_UNREF(context);
458 if (!isDepthFormat(testParameters.format))
459 TCU_THROW(NotSupportedError, "Format cannot be used as depth format");
460 #endif // CTS_USES_VULKANSC
461 }
462
463
464 class TextureCubeShadowTestInstance : public TestInstance
465 {
466 public:
467 typedef TextureCubeShadowTestCaseParameters ParameterType;
468 TextureCubeShadowTestInstance (Context& context, const ParameterType& testParameters);
469 ~TextureCubeShadowTestInstance (void);
470
471 virtual tcu::TestStatus iterate (void);
472
473 private:
474 TextureCubeShadowTestInstance (const TextureCubeShadowTestInstance& other);
475 TextureCubeShadowTestInstance& operator= (const TextureCubeShadowTestInstance& other);
476
477 struct FilterCase
478 {
479 int textureIndex;
480 tcu::Vec2 bottomLeft;
481 tcu::Vec2 topRight;
482 float ref;
483
FilterCasevkt::texture::__anon433fb3630111::TextureCubeShadowTestInstance::FilterCase484 FilterCase (void)
485 : textureIndex (-1)
486 , ref (0.0f)
487 {
488 }
489
FilterCasevkt::texture::__anon433fb3630111::TextureCubeShadowTestInstance::FilterCase490 FilterCase (const int tex_, const float ref_, const tcu::Vec2& bottomLeft_, const tcu::Vec2& topRight_)
491 : textureIndex (tex_)
492 , bottomLeft (bottomLeft_)
493 , topRight (topRight_)
494 , ref (ref_)
495 {
496 }
497 };
498
499 const ParameterType& m_testParameters;
500 vector<TestTextureCubeSp> m_textures;
501 std::vector<FilterCase> m_cases;
502
503 TextureRenderer m_renderer;
504 int m_caseNdx;
505 };
506
TextureCubeShadowTestInstance(Context & context,const ParameterType & testParameters)507 TextureCubeShadowTestInstance::TextureCubeShadowTestInstance (Context& context, const ParameterType& testParameters)
508 : TestInstance (context)
509 , m_testParameters (testParameters)
510 , m_renderer (context, testParameters.sampleCount, TEXCUBE_VIEWPORT_SIZE, TEXCUBE_VIEWPORT_SIZE)
511 , m_caseNdx (0)
512 {
513 const int numLevels = deLog2Floor32(m_testParameters.size)+1;
514 const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(vk::mapVkFormat(m_testParameters.format));
515 const tcu::Vec4 cBias = fmtInfo.valueMin;
516 const tcu::Vec4 cScale = fmtInfo.valueMax-fmtInfo.valueMin;
517
518 // Create textures.
519
520 m_textures.reserve(2);
521 for (int ndx = 0; ndx < 2; ndx++)
522 {
523 m_textures.push_back(TestTextureCubeSp(new pipeline::TestTextureCube(vk::mapVkFormat(m_testParameters.format), m_testParameters.size)));
524 }
525
526 // Fill first with gradient texture.
527 static const tcu::Vec4 gradients[tcu::CUBEFACE_LAST][2] =
528 {
529 { tcu::Vec4(-1.0f, -1.0f, -1.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // negative x
530 { tcu::Vec4( 0.0f, -1.0f, -1.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // positive x
531 { tcu::Vec4(-1.0f, 0.0f, -1.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // negative y
532 { tcu::Vec4(-1.0f, -1.0f, 0.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // positive y
533 { tcu::Vec4(-1.0f, -1.0f, -1.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f) }, // negative z
534 { tcu::Vec4( 0.0f, 0.0f, 0.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) } // positive z
535 };
536
537 for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
538 {
539 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
540 {
541 tcu::fillWithComponentGradients(m_textures[0]->getLevel(levelNdx, face), gradients[face][0]*cScale + cBias, gradients[face][1]*cScale + cBias);
542 }
543 }
544
545 // Fill second with grid texture.
546 for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
547 {
548 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
549 {
550 const deUint32 step = 0x00ffffff / (numLevels*tcu::CUBEFACE_LAST);
551 const deUint32 rgb = step*levelNdx*face;
552 const deUint32 colorA = 0xff000000 | rgb;
553 const deUint32 colorB = 0xff000000 | ~rgb;
554
555 tcu::fillWithGrid(m_textures[1]->getLevel(levelNdx, face), 4, tcu::RGBA(colorA).toVec()*cScale + cBias, tcu::RGBA(colorB).toVec()*cScale + cBias);
556 }
557 }
558
559 // Upload.
560 for (vector<TestTextureCubeSp>::iterator i = m_textures.begin(); i != m_textures.end(); i++)
561 {
562 m_renderer.addCubeTexture(*i, m_testParameters.aspectMask, m_testParameters.backingMode);
563 }
564
565 // Compute cases
566 {
567 const float refInRangeUpper = (m_testParameters.compareOp == Sampler::COMPAREMODE_EQUAL || m_testParameters.compareOp == Sampler::COMPAREMODE_NOT_EQUAL) ? 1.0f : 0.5f;
568 const float refInRangeLower = (m_testParameters.compareOp == Sampler::COMPAREMODE_EQUAL || m_testParameters.compareOp == Sampler::COMPAREMODE_NOT_EQUAL) ? 0.0f : 0.5f;
569 const float refOutOfBoundsUpper = 1.1f;
570 const float refOutOfBoundsLower = -0.1f;
571
572 m_cases.push_back(FilterCase(0, refInRangeUpper, tcu::Vec2(-1.25f, -1.2f), tcu::Vec2(1.2f, 1.25f))); // minification
573 m_cases.push_back(FilterCase(0, refInRangeLower, tcu::Vec2(0.8f, 0.8f), tcu::Vec2(1.25f, 1.20f))); // magnification
574 m_cases.push_back(FilterCase(1, refInRangeUpper, tcu::Vec2(-1.19f, -1.3f), tcu::Vec2(1.1f, 1.35f))); // minification
575 m_cases.push_back(FilterCase(1, refInRangeLower, tcu::Vec2(-1.2f, -1.1f), tcu::Vec2(-0.8f, -0.8f))); // magnification
576 m_cases.push_back(FilterCase(1, refOutOfBoundsUpper, tcu::Vec2(-0.61f, -0.1f), tcu::Vec2(0.9f, 1.18f))); // reference value clamp, upper
577 m_cases.push_back(FilterCase(1, refOutOfBoundsLower, tcu::Vec2(-0.75f, 1.0f), tcu::Vec2(0.05f, 0.75f))); // reference value clamp, lower
578 }
579 }
580
~TextureCubeShadowTestInstance(void)581 TextureCubeShadowTestInstance::~TextureCubeShadowTestInstance (void)
582 {
583 }
584
getFaceDesc(const tcu::CubeFace face)585 static const char* getFaceDesc (const tcu::CubeFace face)
586 {
587 switch (face)
588 {
589 case tcu::CUBEFACE_NEGATIVE_X: return "-X";
590 case tcu::CUBEFACE_POSITIVE_X: return "+X";
591 case tcu::CUBEFACE_NEGATIVE_Y: return "-Y";
592 case tcu::CUBEFACE_POSITIVE_Y: return "+Y";
593 case tcu::CUBEFACE_NEGATIVE_Z: return "-Z";
594 case tcu::CUBEFACE_POSITIVE_Z: return "+Z";
595 default:
596 DE_ASSERT(false);
597 return DE_NULL;
598 }
599 }
600
iterate(void)601 tcu::TestStatus TextureCubeShadowTestInstance::iterate (void)
602 {
603
604 tcu::TestLog& log = m_context.getTestContext().getLog();
605 const tcu::ScopedLogSection iterSection (log, string("Test") + de::toString(m_caseNdx), string("Test ") + de::toString(m_caseNdx));
606 const FilterCase& curCase = m_cases[m_caseNdx];
607 const pipeline::TestTextureCube& texture = m_renderer.getCubeTexture(curCase.textureIndex);
608
609 ReferenceParams sampleParams (TEXTURETYPE_CUBE);
610
611 // Params for reference computation.
612 sampleParams.sampler = util::createSampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, m_testParameters.minFilter, m_testParameters.magFilter);
613 sampleParams.sampler.seamlessCubeMap = m_testParameters.seamless;
614 sampleParams.sampler.compare = m_testParameters.compareOp;
615 sampleParams.samplerType = SAMPLERTYPE_SHADOW;
616 sampleParams.lodMode = LODMODE_EXACT;
617 sampleParams.ref = curCase.ref;
618
619 log << TestLog::Message
620 << "Compare reference value = " << sampleParams.ref << "\n"
621 << "Coordinates: " << curCase.bottomLeft << " -> " << curCase.topRight
622 << TestLog::EndMessage;
623
624 for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
625 {
626 const tcu::CubeFace face = tcu::CubeFace(faceNdx);
627 tcu::Surface result (m_renderer.getRenderWidth(), m_renderer.getRenderHeight());
628 vector<float> texCoord;
629
630 computeQuadTexCoordCube(texCoord, face, curCase.bottomLeft, curCase.topRight);
631
632 log << TestLog::Message << "Face " << getFaceDesc(face) << TestLog::EndMessage;
633
634 // \todo Log texture coordinates.
635
636 m_renderer.renderQuad(result, curCase.textureIndex, &texCoord[0], sampleParams);
637
638 {
639 const tcu::PixelFormat pixelFormat = getPixelFormat(vk::mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM));
640 tcu::LodPrecision lodPrecision;
641 tcu::TexComparePrecision texComparePrecision;
642
643 lodPrecision.derivateBits = 10;
644 lodPrecision.lodBits = 5;
645 texComparePrecision.coordBits = tcu::IVec3(10,10,10);
646 texComparePrecision.uvwBits = tcu::IVec3(6,6,0);
647 texComparePrecision.pcfBits = 5;
648 texComparePrecision.referenceBits = 16;
649 texComparePrecision.resultBits = pixelFormat.redBits-1;
650
651 #ifdef CTS_USES_VULKANSC
652 if (m_context.getTestContext().getCommandLine().isSubProcess())
653 #endif // CTS_USES_VULKANSC
654 {
655 const bool isHighQuality = verifyTexCompareResult(m_context.getTestContext(), result.getAccess(), texture.getTexture(),
656 &texCoord[0], sampleParams, texComparePrecision, lodPrecision, pixelFormat);
657
658 if (!isHighQuality)
659 {
660 log << TestLog::Message << "Warning: Verification assuming high-quality PCF filtering failed." << TestLog::EndMessage;
661
662 lodPrecision.lodBits = 4;
663 texComparePrecision.uvwBits = tcu::IVec3(4,4,0);
664 texComparePrecision.pcfBits = 0;
665
666 const bool isOk = verifyTexCompareResult(m_context.getTestContext(), result.getAccess(), texture.getTexture(),
667 &texCoord[0], sampleParams, texComparePrecision, lodPrecision, pixelFormat);
668
669 if (!isOk)
670 {
671 log << TestLog::Message << "ERROR: Verification against low precision requirements failed, failing test case." << TestLog::EndMessage;
672 return tcu::TestStatus::fail("Image verification failed");
673 }
674 }
675 }
676 }
677 }
678
679 m_caseNdx += 1;
680 return m_caseNdx < (int)m_cases.size() ? tcu::TestStatus::incomplete() : tcu::TestStatus::pass("Pass");
681 }
682
683 struct Texture2DArrayShadowTestCaseParameters : public TextureShadowCommonTestCaseParameters, public Texture2DArrayTestCaseParameters
684 {
685 };
686
checkTextureSupport(Context & context,const Texture2DArrayShadowTestCaseParameters & testParameters)687 void checkTextureSupport (Context& context, const Texture2DArrayShadowTestCaseParameters& testParameters)
688 {
689 #ifndef CTS_USES_VULKANSC
690 const VkFormatProperties3 formatProperties = context.getFormatProperties(testParameters.format);
691 if (!(formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT_KHR))
692 TCU_THROW(NotSupportedError, "Format does not support shadow sampling");
693 #else
694 DE_UNREF(context);
695 if (!isDepthFormat(testParameters.format))
696 TCU_THROW(NotSupportedError, "Format cannot be used as depth format");
697 #endif // CTS_USES_VULKANSC
698 }
699
700 class Texture2DArrayShadowTestInstance : public TestInstance
701 {
702 public:
703 typedef Texture2DArrayShadowTestCaseParameters ParameterType;
704 Texture2DArrayShadowTestInstance (Context& context, const ParameterType& testParameters);
705 ~Texture2DArrayShadowTestInstance (void);
706
707 virtual tcu::TestStatus iterate (void);
708
709 private:
710 Texture2DArrayShadowTestInstance (const Texture2DArrayShadowTestInstance& other);
711 Texture2DArrayShadowTestInstance& operator= (const Texture2DArrayShadowTestInstance& other);
712
713 struct FilterCase
714 {
715 int textureIndex;
716 tcu::Vec3 minCoord;
717 tcu::Vec3 maxCoord;
718 float ref;
719
FilterCasevkt::texture::__anon433fb3630111::Texture2DArrayShadowTestInstance::FilterCase720 FilterCase (void)
721 : textureIndex (-1)
722 , ref (0.0f)
723 {
724 }
725
FilterCasevkt::texture::__anon433fb3630111::Texture2DArrayShadowTestInstance::FilterCase726 FilterCase (const int tex_, float ref_, const tcu::Vec3& minCoord_, const tcu::Vec3& maxCoord_)
727 : textureIndex (tex_)
728 , minCoord (minCoord_)
729 , maxCoord (maxCoord_)
730 , ref (ref_)
731 {
732 }
733 };
734
735 const ParameterType& m_testParameters;
736 std::vector<TestTexture2DArraySp> m_textures;
737 std::vector<FilterCase> m_cases;
738
739 TextureRenderer m_renderer;
740
741 int m_caseNdx;
742 };
743
Texture2DArrayShadowTestInstance(Context & context,const ParameterType & testParameters)744 Texture2DArrayShadowTestInstance::Texture2DArrayShadowTestInstance (Context& context, const ParameterType& testParameters)
745 : TestInstance (context)
746 , m_testParameters (testParameters)
747 , m_renderer (context, testParameters.sampleCount, TEX2D_VIEWPORT_WIDTH, TEX2D_VIEWPORT_HEIGHT)
748 , m_caseNdx (0)
749 {
750 const int numLevels = deLog2Floor32(de::max(m_testParameters.width, m_testParameters.height))+1;
751 const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(vk::mapVkFormat(m_testParameters.format));
752 const tcu::Vec4 cScale = fmtInfo.valueMax-fmtInfo.valueMin;
753 const tcu::Vec4 cBias = fmtInfo.valueMin;
754
755 // Create 2 textures.
756 m_textures.reserve(2);
757 for (int ndx = 0; ndx < 2; ndx++)
758 {
759 m_textures.push_back(TestTexture2DArraySp(new pipeline::TestTexture2DArray(vk::mapVkFormat(m_testParameters.format), m_testParameters.width, m_testParameters.height, m_testParameters.numLayers)));
760 }
761
762 // Fill first gradient texture.
763 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
764 {
765 const tcu::Vec4 gMin = tcu::Vec4(-0.5f, -0.5f, -0.5f, 2.0f)*cScale + cBias;
766 const tcu::Vec4 gMax = tcu::Vec4( 1.0f, 1.0f, 1.0f, 0.0f)*cScale + cBias;
767
768 tcu::fillWithComponentGradients(m_textures[0]->getTexture().getLevel(levelNdx), gMin, gMax);
769 }
770
771 // Fill second with grid texture.
772 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
773 {
774 const deUint32 step = 0x00ffffff / numLevels;
775 const deUint32 rgb = step*levelNdx;
776 const deUint32 colorA = 0xff000000 | rgb;
777 const deUint32 colorB = 0xff000000 | ~rgb;
778
779 tcu::fillWithGrid(m_textures[1]->getTexture().getLevel(levelNdx), 4, tcu::RGBA(colorA).toVec()*cScale + cBias, tcu::RGBA(colorB).toVec()*cScale + cBias);
780 }
781
782 // Upload.
783 for (std::vector<TestTexture2DArraySp>::iterator i = m_textures.begin(); i != m_textures.end(); ++i)
784 {
785 m_renderer.add2DArrayTexture(*i, m_testParameters.aspectMask, m_testParameters.backingMode);
786 }
787
788 // Compute cases.
789 {
790 const float refInRangeUpper = (m_testParameters.compareOp == Sampler::COMPAREMODE_EQUAL || m_testParameters.compareOp == Sampler::COMPAREMODE_NOT_EQUAL) ? 1.0f : 0.5f;
791 const float refInRangeLower = (m_testParameters.compareOp == Sampler::COMPAREMODE_EQUAL || m_testParameters.compareOp == Sampler::COMPAREMODE_NOT_EQUAL) ? 0.0f : 0.5f;
792 const float refOutOfBoundsUpper = 1.1f; // !< lookup function should clamp values to [0, 1] range
793 const float refOutOfBoundsLower = -0.1f;
794
795 const struct
796 {
797 const int texNdx;
798 const float ref;
799 const float lodX;
800 const float lodY;
801 const float oX;
802 const float oY;
803 } cases[] =
804 {
805 { 0, refInRangeUpper, 1.6f, 2.9f, -1.0f, -2.7f },
806 { 0, refInRangeLower, -2.0f, -1.35f, -0.2f, 0.7f },
807 { 1, refInRangeUpper, 0.14f, 0.275f, -1.5f, -1.1f },
808 { 1, refInRangeLower, -0.92f, -2.64f, 0.4f, -0.1f },
809 { 1, refOutOfBoundsUpper, -0.49f, -0.22f, 0.45f, 0.97f },
810 { 1, refOutOfBoundsLower, -0.85f, 0.75f, 0.25f, 0.61f },
811 };
812
813 const float minLayer = -0.5f;
814 const float maxLayer = (float)m_testParameters.numLayers;
815
816 for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(cases); caseNdx++)
817 {
818 const int tex = cases[caseNdx].texNdx > 0 ? 1 : 0;
819 const float ref = cases[caseNdx].ref;
820 const float lodX = cases[caseNdx].lodX;
821 const float lodY = cases[caseNdx].lodY;
822 const float oX = cases[caseNdx].oX;
823 const float oY = cases[caseNdx].oY;
824 const float sX = deFloatExp2(lodX) * float(m_renderer.getRenderWidth()) / float(m_textures[tex]->getTexture().getWidth());
825 const float sY = deFloatExp2(lodY) * float(m_renderer.getRenderHeight()) / float(m_textures[tex]->getTexture().getHeight());
826
827 m_cases.push_back(FilterCase(tex, ref, tcu::Vec3(oX, oY, minLayer), tcu::Vec3(oX+sX, oY+sY, maxLayer)));
828 }
829 }
830 }
831
~Texture2DArrayShadowTestInstance(void)832 Texture2DArrayShadowTestInstance::~Texture2DArrayShadowTestInstance (void)
833 {
834 }
835
iterate(void)836 tcu::TestStatus Texture2DArrayShadowTestInstance::iterate (void)
837 {
838 tcu::TestLog& log = m_context.getTestContext().getLog();
839 const FilterCase& curCase = m_cases[m_caseNdx];
840 const pipeline::TestTexture2DArray& texture = m_renderer.get2DArrayTexture(curCase.textureIndex);
841
842 ReferenceParams sampleParams (TEXTURETYPE_2D_ARRAY);
843 tcu::Surface rendered (m_renderer.getRenderWidth(), m_renderer.getRenderHeight());
844 const tcu::ScopedLogSection section (log, string("Test") + de::toString(m_caseNdx), string("Test ") + de::toString(m_caseNdx));
845
846 const float texCoord[] =
847 {
848 curCase.minCoord.x(), curCase.minCoord.y(), curCase.minCoord.z(),
849 curCase.minCoord.x(), curCase.maxCoord.y(), (curCase.minCoord.z() + curCase.maxCoord.z()) / 2.0f,
850 curCase.maxCoord.x(), curCase.minCoord.y(), (curCase.minCoord.z() + curCase.maxCoord.z()) / 2.0f,
851 curCase.maxCoord.x(), curCase.maxCoord.y(), curCase.maxCoord.z()
852 };
853
854 // Setup params for reference.
855 sampleParams.sampler = util::createSampler(m_testParameters.wrapS, m_testParameters.wrapT, m_testParameters.minFilter, m_testParameters.magFilter);
856 sampleParams.sampler.compare = m_testParameters.compareOp;
857 sampleParams.samplerType = SAMPLERTYPE_SHADOW;
858 sampleParams.lodMode = LODMODE_EXACT;
859 sampleParams.ref = curCase.ref;
860
861 log << TestLog::Message
862 << "Compare reference value = " << sampleParams.ref << "\n"
863 << "Texture coordinates: " << curCase.minCoord << " -> " << curCase.maxCoord
864 << TestLog::EndMessage;
865
866 m_renderer.renderQuad(rendered, curCase.textureIndex, &texCoord[0], sampleParams);
867
868 {
869 const tcu::PixelFormat pixelFormat = getPixelFormat(vk::mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM));
870 tcu::LodPrecision lodPrecision;
871 tcu::TexComparePrecision texComparePrecision;
872
873 lodPrecision.derivateBits = 18;
874 lodPrecision.lodBits = 6;
875 texComparePrecision.coordBits = tcu::IVec3(20,20,20);
876 texComparePrecision.uvwBits = tcu::IVec3(7,7,7);
877 texComparePrecision.pcfBits = 5;
878 texComparePrecision.referenceBits = 16;
879 texComparePrecision.resultBits = pixelFormat.redBits-1;
880
881 #ifdef CTS_USES_VULKANSC
882 if (m_context.getTestContext().getCommandLine().isSubProcess())
883 #endif // CTS_USES_VULKANSC
884 {
885 const bool isHighQuality = verifyTexCompareResult(m_context.getTestContext(), rendered.getAccess(), texture.getTexture(),
886 &texCoord[0], sampleParams, texComparePrecision, lodPrecision, pixelFormat);
887
888 if (!isHighQuality)
889 {
890 log << TestLog::Message << "Warning: Verification assuming high-quality PCF filtering failed." << TestLog::EndMessage;
891
892 lodPrecision.lodBits = 4;
893 texComparePrecision.uvwBits = tcu::IVec3(4,4,4);
894 texComparePrecision.pcfBits = 0;
895
896 const bool isOk = verifyTexCompareResult(m_context.getTestContext(), rendered.getAccess(), texture.getTexture(),
897 &texCoord[0], sampleParams, texComparePrecision, lodPrecision, pixelFormat);
898
899 if (!isOk)
900 {
901 log << TestLog::Message << "ERROR: Verification against low precision requirements failed, failing test case." << TestLog::EndMessage;
902 return tcu::TestStatus::fail("Image verification failed");
903 }
904 }
905 }
906 }
907
908 m_caseNdx += 1;
909 return m_caseNdx < (int)m_cases.size() ? tcu::TestStatus::incomplete() : tcu::TestStatus::pass("Pass");
910 }
911
912 struct Texture1DShadowTestCaseParameters : public Texture1DTestCaseParameters, public TextureShadowCommonTestCaseParameters
913 {
914 };
915
checkTextureSupport(Context & context,const Texture1DShadowTestCaseParameters & testParameters)916 void checkTextureSupport (Context& context, const Texture1DShadowTestCaseParameters& testParameters)
917 {
918 #ifndef CTS_USES_VULKANSC
919 const VkFormatProperties3 formatProperties = context.getFormatProperties(testParameters.format);
920 if (!(formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT_KHR))
921 TCU_THROW(NotSupportedError, "Format does not support shadow sampling");
922 #else
923 DE_UNREF(context);
924 if (!isDepthFormat(testParameters.format))
925 TCU_THROW(NotSupportedError, "Format cannot be used as depth format");
926 #endif // CTS_USES_VULKANSC
927 }
928
929 class Texture1DShadowTestInstance : public TestInstance
930 {
931 public:
932 typedef Texture1DShadowTestCaseParameters ParameterType;
933 Texture1DShadowTestInstance (Context& context, const ParameterType& testParameters);
934 ~Texture1DShadowTestInstance (void);
935
936 virtual tcu::TestStatus iterate (void);
937
938 private:
939 Texture1DShadowTestInstance (const Texture1DShadowTestInstance& other) = delete;
940 Texture1DShadowTestInstance& operator= (const Texture1DShadowTestInstance& other) = delete;
941
942 struct FilterCase
943 {
944 int textureIndex;
945
946 float minCoord;
947 float maxCoord;
948 float ref;
949
FilterCasevkt::texture::__anon433fb3630111::Texture1DShadowTestInstance::FilterCase950 FilterCase (void)
951 : textureIndex(-1)
952 , minCoord (0)
953 , maxCoord (0)
954 , ref (0.0f)
955 {
956 }
957
FilterCasevkt::texture::__anon433fb3630111::Texture1DShadowTestInstance::FilterCase958 FilterCase (int tex_, const float ref_, const float& minCoord_, const float& maxCoord_)
959 : textureIndex (tex_)
960 , minCoord (minCoord_)
961 , maxCoord (maxCoord_)
962 , ref (ref_)
963 {
964 }
965 };
966
967 const ParameterType& m_testParameters;
968 std::vector<TestTexture1DSp> m_textures;
969 std::vector<FilterCase> m_cases;
970
971 TextureRenderer m_renderer;
972
973 int m_caseNdx;
974 };
975
Texture1DShadowTestInstance(Context & context,const ParameterType & testParameters)976 Texture1DShadowTestInstance::Texture1DShadowTestInstance (Context& context, const ParameterType& testParameters)
977 : TestInstance (context)
978 , m_testParameters (testParameters)
979 , m_renderer (context, testParameters.sampleCount, TEX1D_VIEWPORT_WIDTH, 1, 1, vk::makeComponentMappingRGBA(), vk::VK_IMAGE_TYPE_1D, vk::VK_IMAGE_VIEW_TYPE_1D)
980 , m_caseNdx (0)
981 {
982 // Create 2 textures.
983 m_textures.reserve(2);
984 for (int ndx = 0; ndx < 2; ndx++)
985 {
986 m_textures.push_back(TestTexture1DSp(new pipeline::TestTexture1D(vk::mapVkFormat(m_testParameters.format), m_testParameters.width)));
987 }
988
989 const int numLevels = m_textures[0]->getNumLevels();
990
991 // Fill first gradient texture.
992 for (int levelNdx = 0; levelNdx < numLevels; ++levelNdx)
993 {
994 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));
995 }
996
997 // Fill second with grid texture.
998 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
999 {
1000 const deUint32 step = 0x00ffffff / numLevels;
1001 const deUint32 rgb = step*levelNdx;
1002 const deUint32 colorA = 0xff000000 | rgb;
1003 const deUint32 colorB = 0xff000000 | ~rgb;
1004
1005 tcu::fillWithGrid(m_textures[1]->getLevel(levelNdx, 0), 4, tcu::RGBA(colorA).toVec(), tcu::RGBA(colorB).toVec());
1006 }
1007
1008 // Upload.
1009 for (std::vector<TestTexture1DSp>::iterator i = m_textures.begin(); i != m_textures.end(); ++i)
1010 {
1011 m_renderer.add1DTexture(*i, m_testParameters.aspectMask, m_testParameters.backingMode);
1012 }
1013
1014 // Compute cases.
1015 {
1016 const bool compareModeSet = (m_testParameters.compareOp == Sampler::COMPAREMODE_EQUAL || m_testParameters.compareOp == Sampler::COMPAREMODE_NOT_EQUAL);
1017 const float refInRangeUpper = compareModeSet ? 1.0f : 0.5f;
1018 const float refInRangeLower = compareModeSet ? 0.0f : 0.5f;
1019 const float refOutOfBoundsUpper = 1.1f; // !< lookup function should clamp values to [0, 1] range
1020 const float refOutOfBoundsLower = -0.1f;
1021
1022 const struct
1023 {
1024 const int texNdx;
1025 const float ref;
1026 const float lodX;
1027 const float oX;
1028 }
1029 cases[] =
1030 {
1031 { 0, refInRangeUpper, +1.600f, -1.000f },
1032 { 0, refInRangeLower, -2.000f, -0.200f },
1033 { 1, refInRangeUpper, +0.140f, -1.500f },
1034 { 1, refInRangeLower, -0.920f, +0.400f },
1035 { 1, refOutOfBoundsUpper, -0.390f, +0.650f },
1036 { 1, refOutOfBoundsLower, -1.550f, +0.350f },
1037 };
1038
1039 for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(cases); caseNdx++)
1040 {
1041 const int texNdx = de::clamp(cases[caseNdx].texNdx, 0, (int)m_textures.size()-1);
1042 const float ref = cases[caseNdx].ref;
1043 const float lodX = cases[caseNdx].lodX;
1044 const float oX = cases[caseNdx].oX;
1045 const float sX = deFloatExp2(lodX) * float(m_renderer.getRenderWidth()) / float(m_textures[texNdx]->getTexture().getWidth());
1046
1047 m_cases.push_back(FilterCase(texNdx, ref, oX, oX+sX));
1048 }
1049 }
1050
1051 m_caseNdx = 0;
1052 }
1053
~Texture1DShadowTestInstance(void)1054 Texture1DShadowTestInstance::~Texture1DShadowTestInstance (void)
1055 {
1056 m_textures.clear();
1057 m_cases.clear();
1058 }
1059
iterate(void)1060 tcu::TestStatus Texture1DShadowTestInstance::iterate (void)
1061 {
1062 tcu::TestLog& log = m_context.getTestContext().getLog();
1063 const pipeline::TestTexture1D& texture = m_renderer.get1DTexture(m_cases[m_caseNdx].textureIndex);
1064 const tcu::TextureFormat texFmt = texture.getTextureFormat();
1065 const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(texFmt);
1066 const tcu::ScopedLogSection section (log, string("Test") + de::toString(m_caseNdx), string("Test ") + de::toString(m_caseNdx));
1067
1068 const FilterCase& curCase = m_cases[m_caseNdx];
1069 ReferenceParams sampleParams (TEXTURETYPE_1D);
1070 tcu::Surface rendered (m_renderer.getRenderWidth(), 1);
1071 vector<float> texCoord;
1072
1073 // Setup params for reference.
1074 sampleParams.sampler = util::createSampler(m_testParameters.wrapS, m_testParameters.minFilter, m_testParameters.magFilter);
1075 sampleParams.sampler.compare = m_testParameters.compareOp;
1076 sampleParams.samplerType = SAMPLERTYPE_SHADOW;
1077 sampleParams.lodMode = LODMODE_EXACT;
1078 sampleParams.colorBias = fmtInfo.lookupBias;
1079 sampleParams.colorScale = fmtInfo.lookupScale;
1080 sampleParams.ref = curCase.ref;
1081
1082 log << TestLog::Message << "Compare reference value = " << sampleParams.ref << TestLog::EndMessage;
1083
1084 // Compute texture coordinates.
1085 log << TestLog::Message << "Texture coordinates: " << curCase.minCoord << " -> " << curCase.maxCoord << TestLog::EndMessage;
1086 computeQuadTexCoord1D(texCoord, curCase.minCoord, curCase.maxCoord);
1087
1088 m_renderer.renderQuad(rendered, curCase.textureIndex, &texCoord[0], sampleParams);
1089
1090 {
1091 const tcu::PixelFormat pixelFormat = getPixelFormat(vk::mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM));
1092 tcu::LodPrecision lodPrecision;
1093 tcu::TexComparePrecision texComparePrecision;
1094
1095 lodPrecision.derivateBits = 18;
1096 lodPrecision.lodBits = 6;
1097 texComparePrecision.coordBits = tcu::IVec3(20,0,0);
1098 texComparePrecision.uvwBits = tcu::IVec3(7,0,0);
1099 texComparePrecision.pcfBits = 5;
1100 texComparePrecision.referenceBits = 16;
1101 texComparePrecision.resultBits = pixelFormat.redBits-1;
1102
1103 #ifdef CTS_USES_VULKANSC
1104 if (m_context.getTestContext().getCommandLine().isSubProcess())
1105 #endif // CTS_USES_VULKANSC
1106 {
1107 const bool isHighQuality = verifyTexCompareResult(m_context.getTestContext(), rendered.getAccess(), texture.getTexture(),
1108 &texCoord[0], sampleParams, texComparePrecision, lodPrecision, pixelFormat);
1109
1110 if (!isHighQuality)
1111 {
1112 m_context.getTestContext().getLog() << TestLog::Message << "Warning: Verification assuming high-quality PCF filtering failed." << TestLog::EndMessage;
1113
1114 lodPrecision.lodBits = 4;
1115 texComparePrecision.uvwBits = tcu::IVec3(4,0,0);
1116 texComparePrecision.pcfBits = 0;
1117
1118 const bool isOk = verifyTexCompareResult(m_context.getTestContext(), rendered.getAccess(), texture.getTexture(),
1119 &texCoord[0], sampleParams, texComparePrecision, lodPrecision, pixelFormat);
1120
1121 if (!isOk)
1122 {
1123 m_context.getTestContext().getLog() << TestLog::Message << "ERROR: Verification against low precision requirements failed, failing test case." << TestLog::EndMessage;
1124 return tcu::TestStatus::fail("Image verification failed");
1125 }
1126 }
1127 }
1128 }
1129
1130 m_caseNdx += 1;
1131 return m_caseNdx < (int)m_cases.size() ? tcu::TestStatus::incomplete() : tcu::TestStatus::pass("Pass");
1132 }
1133
1134 struct Texture1DArrayShadowTestCaseParameters : public TextureShadowCommonTestCaseParameters, public Texture1DArrayTestCaseParameters
1135 {
1136 };
1137
checkTextureSupport(Context & context,const Texture1DArrayShadowTestCaseParameters & testParameters)1138 void checkTextureSupport (Context& context, const Texture1DArrayShadowTestCaseParameters& testParameters)
1139 {
1140 #ifndef CTS_USES_VULKANSC
1141 const VkFormatProperties3 formatProperties = context.getFormatProperties(testParameters.format);
1142 if (!(formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT_KHR))
1143 TCU_THROW(NotSupportedError, "Format does not support shadow sampling");
1144 #else
1145 DE_UNREF(context);
1146 if (!isDepthFormat(testParameters.format))
1147 TCU_THROW(NotSupportedError, "Format cannot be used as depth format");
1148 #endif // CTS_USES_VULKANSC
1149 }
1150
1151 class Texture1DArrayShadowTestInstance : public TestInstance
1152 {
1153 public:
1154 typedef Texture1DArrayShadowTestCaseParameters ParameterType;
1155 Texture1DArrayShadowTestInstance (Context& context, const ParameterType& testParameters);
1156 ~Texture1DArrayShadowTestInstance (void);
1157
1158 virtual tcu::TestStatus iterate (void);
1159
1160 private:
1161 Texture1DArrayShadowTestInstance (const Texture1DArrayShadowTestInstance& other) = delete;
1162 Texture1DArrayShadowTestInstance& operator= (const Texture1DArrayShadowTestInstance& other) = delete;
1163
1164 struct FilterCase
1165 {
1166 int textureIndex;
1167 tcu::Vec2 minCoord;
1168 tcu::Vec2 maxCoord;
1169 float ref;
1170
FilterCasevkt::texture::__anon433fb3630111::Texture1DArrayShadowTestInstance::FilterCase1171 FilterCase (void)
1172 : textureIndex (-1)
1173 , ref (0.0f)
1174 {
1175 }
1176
FilterCasevkt::texture::__anon433fb3630111::Texture1DArrayShadowTestInstance::FilterCase1177 FilterCase (const int tex_, float ref_, const tcu::Vec2& minCoord_, const tcu::Vec2& maxCoord_)
1178 : textureIndex (tex_)
1179 , minCoord (minCoord_)
1180 , maxCoord (maxCoord_)
1181 , ref (ref_)
1182 {
1183 }
1184 };
1185
1186 const ParameterType& m_testParameters;
1187 std::vector<TestTexture1DArraySp> m_textures;
1188 std::vector<FilterCase> m_cases;
1189
1190 TextureRenderer m_renderer;
1191
1192 int m_caseNdx;
1193 };
1194
Texture1DArrayShadowTestInstance(Context & context,const ParameterType & testParameters)1195 Texture1DArrayShadowTestInstance::Texture1DArrayShadowTestInstance (Context& context, const ParameterType& testParameters)
1196 : TestInstance (context)
1197 , m_testParameters (testParameters)
1198 , m_renderer (context, testParameters.sampleCount, TEX1D_VIEWPORT_WIDTH, 1)
1199 , m_caseNdx (0)
1200 {
1201 const int numLevels = deLog2Floor32(m_testParameters.width) + 1;
1202 const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(vk::mapVkFormat(m_testParameters.format));
1203 const tcu::Vec4 cScale = fmtInfo.valueMax-fmtInfo.valueMin;
1204 const tcu::Vec4 cBias = fmtInfo.valueMin;
1205
1206 // Create 2 textures.
1207 m_textures.reserve(2);
1208 for (int ndx = 0; ndx < 2; ndx++)
1209 {
1210 m_textures.push_back(TestTexture1DArraySp(new pipeline::TestTexture1DArray(vk::mapVkFormat(m_testParameters.format), m_testParameters.width, m_testParameters.numLayers)));
1211 }
1212
1213 // Fill first gradient texture.
1214 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
1215 {
1216 const tcu::Vec4 gMin = tcu::Vec4(-0.5f, -0.5f, -0.5f, 2.0f)*cScale + cBias;
1217 const tcu::Vec4 gMax = tcu::Vec4( 1.0f, 1.0f, 1.0f, 0.0f)*cScale + cBias;
1218
1219 tcu::fillWithComponentGradients(m_textures[0]->getTexture().getLevel(levelNdx), gMin, gMax);
1220 }
1221
1222 // Fill second with grid texture.
1223 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
1224 {
1225 const deUint32 step = 0x00ffffff / numLevels;
1226 const deUint32 rgb = step*levelNdx;
1227 const deUint32 colorA = 0xff000000 | rgb;
1228 const deUint32 colorB = 0xff000000 | ~rgb;
1229
1230 tcu::fillWithGrid(m_textures[1]->getTexture().getLevel(levelNdx), 4, tcu::RGBA(colorA).toVec()*cScale + cBias, tcu::RGBA(colorB).toVec()*cScale + cBias);
1231 }
1232
1233 // Upload.
1234 for (std::vector<TestTexture1DArraySp>::iterator i = m_textures.begin(); i != m_textures.end(); ++i)
1235 {
1236 m_renderer.add1DArrayTexture(*i, m_testParameters.aspectMask, m_testParameters.backingMode);
1237 }
1238
1239 // Compute cases.
1240 {
1241 const bool compareModeSet = (m_testParameters.compareOp == Sampler::COMPAREMODE_EQUAL || m_testParameters.compareOp == Sampler::COMPAREMODE_NOT_EQUAL);
1242 const float refInRangeUpper = compareModeSet ? 1.0f : 0.5f;
1243 const float refInRangeLower = compareModeSet ? 0.0f : 0.5f;
1244 const float refOutOfBoundsUpper = 1.1f; // !< lookup function should clamp values to [0, 1] range
1245 const float refOutOfBoundsLower = -0.1f;
1246
1247 const struct
1248 {
1249 const int texNdx;
1250 const float ref;
1251 const float lodX;
1252 const float oX;
1253 }
1254 cases[] =
1255 {
1256 { 0, refInRangeUpper, 1.6f, -1.0f, },
1257 { 0, refInRangeLower, -2.0f, -0.2f, },
1258 { 1, refInRangeUpper, 0.14f, -1.5f, },
1259 { 1, refInRangeLower, -0.92f, 0.4f, },
1260 { 1, refOutOfBoundsUpper, -0.49f, 0.45f, },
1261 { 1, refOutOfBoundsLower, -0.85f, 0.25f, },
1262 };
1263
1264 const float minLayer = -0.5f;
1265 const float maxLayer = (float)m_testParameters.numLayers;
1266
1267 for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(cases); caseNdx++)
1268 {
1269 const int tex = cases[caseNdx].texNdx > 0 ? 1 : 0;
1270 const float ref = cases[caseNdx].ref;
1271 const float lodX = cases[caseNdx].lodX;
1272 const float oX = cases[caseNdx].oX;
1273 const float sX = deFloatExp2(lodX) * float(m_renderer.getRenderWidth()) / float(m_textures[tex]->getTexture().getWidth());
1274
1275 m_cases.push_back(FilterCase(tex, ref, tcu::Vec2(oX, minLayer), tcu::Vec2(oX+sX, maxLayer)));
1276 }
1277 }
1278 }
1279
~Texture1DArrayShadowTestInstance(void)1280 Texture1DArrayShadowTestInstance::~Texture1DArrayShadowTestInstance (void)
1281 {
1282 }
1283
iterate(void)1284 tcu::TestStatus Texture1DArrayShadowTestInstance::iterate (void)
1285 {
1286 tcu::TestLog& log = m_context.getTestContext().getLog();
1287 const FilterCase& curCase = m_cases[m_caseNdx];
1288 const pipeline::TestTexture1DArray& texture = m_renderer.get1DArrayTexture(curCase.textureIndex);
1289
1290 ReferenceParams sampleParams (TEXTURETYPE_1D_ARRAY);
1291 tcu::Surface rendered (m_renderer.getRenderWidth(), m_renderer.getRenderHeight());
1292 const tcu::ScopedLogSection section (log, string("Test") + de::toString(m_caseNdx), string("Test ") + de::toString(m_caseNdx));
1293
1294 const float texCoord[] =
1295 {
1296 curCase.minCoord.x(), curCase.minCoord.y(),
1297 curCase.minCoord.x(), (curCase.minCoord.y() + curCase.maxCoord.y()) / 2.0f,
1298 curCase.maxCoord.x(), (curCase.minCoord.y() + curCase.maxCoord.y()) / 2.0f,
1299 curCase.maxCoord.x(), curCase.maxCoord.y()
1300 };
1301
1302 // Setup params for reference.
1303 sampleParams.sampler = util::createSampler(m_testParameters.wrapS, m_testParameters.minFilter, m_testParameters.magFilter);
1304 sampleParams.sampler.compare = m_testParameters.compareOp;
1305 sampleParams.samplerType = SAMPLERTYPE_SHADOW;
1306 sampleParams.lodMode = LODMODE_EXACT;
1307 sampleParams.ref = curCase.ref;
1308
1309 log << TestLog::Message
1310 << "Compare reference value = " << sampleParams.ref << "\n"
1311 << "Texture coordinates: " << curCase.minCoord << " -> " << curCase.maxCoord
1312 << TestLog::EndMessage;
1313
1314 m_renderer.renderQuad(rendered, curCase.textureIndex, &texCoord[0], sampleParams);
1315
1316 {
1317 const tcu::PixelFormat pixelFormat = getPixelFormat(vk::mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM));
1318 tcu::LodPrecision lodPrecision;
1319 tcu::TexComparePrecision texComparePrecision;
1320
1321 lodPrecision.derivateBits = 18;
1322 lodPrecision.lodBits = 6;
1323 texComparePrecision.coordBits = tcu::IVec3(20,20,20);
1324 texComparePrecision.uvwBits = tcu::IVec3(7,7,7);
1325 texComparePrecision.pcfBits = 5;
1326 texComparePrecision.referenceBits = 16;
1327 texComparePrecision.resultBits = pixelFormat.redBits-1;
1328
1329 #ifdef CTS_USES_VULKANSC
1330 if (m_context.getTestContext().getCommandLine().isSubProcess())
1331 #endif // CTS_USES_VULKANSC
1332 {
1333 const bool isHighQuality = verifyTexCompareResult(m_context.getTestContext(), rendered.getAccess(), texture.getTexture(),
1334 &texCoord[0], sampleParams, texComparePrecision, lodPrecision, pixelFormat);
1335
1336 if (!isHighQuality)
1337 {
1338 log << TestLog::Message << "Warning: Verification assuming high-quality PCF filtering failed." << TestLog::EndMessage;
1339
1340 lodPrecision.lodBits = 4;
1341 texComparePrecision.uvwBits = tcu::IVec3(4,4,4);
1342 texComparePrecision.pcfBits = 0;
1343
1344 const bool isOk = verifyTexCompareResult(m_context.getTestContext(), rendered.getAccess(), texture.getTexture(),
1345 &texCoord[0], sampleParams, texComparePrecision, lodPrecision, pixelFormat);
1346
1347 if (!isOk)
1348 {
1349 log << TestLog::Message << "ERROR: Verification against low precision requirements failed, failing test case." << TestLog::EndMessage;
1350 return tcu::TestStatus::fail("Image verification failed");
1351 }
1352 }
1353 }
1354 }
1355
1356 m_caseNdx += 1;
1357 return m_caseNdx < (int)m_cases.size() ? tcu::TestStatus::incomplete() : tcu::TestStatus::pass("Pass");
1358 }
1359
1360 struct TextureCubeArrayShadowTestCaseParameters : public TextureShadowCommonTestCaseParameters, public TextureCubeArrayTestCaseParameters
1361 {
1362 };
1363
checkTextureSupport(Context & context,const TextureCubeArrayShadowTestCaseParameters & testParameters)1364 void checkTextureSupport (Context& context, const TextureCubeArrayShadowTestCaseParameters& testParameters)
1365 {
1366 #ifndef CTS_USES_VULKANSC
1367 const VkFormatProperties3 formatProperties = context.getFormatProperties(testParameters.format);
1368 if (!(formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT_KHR))
1369 TCU_THROW(NotSupportedError, "Format does not support shadow sampling");
1370 if (!testParameters.seamless)
1371 context.requireDeviceFunctionality("VK_EXT_non_seamless_cube_map");
1372 #else
1373 DE_UNREF(context);
1374 if (!isDepthFormat(testParameters.format))
1375 TCU_THROW(NotSupportedError, "Format cannot be used as depth format");
1376 #endif // CTS_USES_VULKANSC
1377 }
1378
1379 class TextureCubeArrayShadowTestInstance : public TestInstance
1380 {
1381 public:
1382 typedef TextureCubeArrayShadowTestCaseParameters ParameterType;
1383 TextureCubeArrayShadowTestInstance (Context& context, const ParameterType& testParameters);
1384 ~TextureCubeArrayShadowTestInstance (void);
1385
1386 virtual tcu::TestStatus iterate (void);
1387
1388 private:
1389 TextureCubeArrayShadowTestInstance (const TextureCubeArrayShadowTestInstance& other);
1390 TextureCubeArrayShadowTestInstance& operator= (const TextureCubeArrayShadowTestInstance& other);
1391
1392 struct FilterCase
1393 {
1394 int textureIndex;
1395 tcu::Vec2 bottomLeft;
1396 tcu::Vec2 topRight;
1397 float ref;
1398
FilterCasevkt::texture::__anon433fb3630111::TextureCubeArrayShadowTestInstance::FilterCase1399 FilterCase (void)
1400 : textureIndex (-1)
1401 , ref (0.0f)
1402 {
1403 }
1404
FilterCasevkt::texture::__anon433fb3630111::TextureCubeArrayShadowTestInstance::FilterCase1405 FilterCase (const int tex_, const float ref_, const tcu::Vec2& bottomLeft_, const tcu::Vec2& topRight_)
1406 : textureIndex (tex_)
1407 , bottomLeft (bottomLeft_)
1408 , topRight (topRight_)
1409 , ref (ref_)
1410 {
1411 }
1412 };
1413
1414 const ParameterType& m_testParameters;
1415 vector<TestTextureCubeArraySp> m_textures;
1416 std::vector<FilterCase> m_cases;
1417
1418 TextureRenderer m_renderer;
1419 int m_caseNdx;
1420 };
1421
TextureCubeArrayShadowTestInstance(Context & context,const ParameterType & testParameters)1422 TextureCubeArrayShadowTestInstance::TextureCubeArrayShadowTestInstance (Context& context, const ParameterType& testParameters)
1423 : TestInstance (context)
1424 , m_testParameters (testParameters)
1425 , m_renderer (context, testParameters.sampleCount, TEXCUBE_VIEWPORT_SIZE, TEXCUBE_VIEWPORT_SIZE)
1426 , m_caseNdx (0)
1427 {
1428 const int numLevels = deLog2Floor32(m_testParameters.size)+1;
1429 const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(vk::mapVkFormat(m_testParameters.format));
1430 const tcu::Vec4 cBias = fmtInfo.valueMin;
1431 const tcu::Vec4 cScale = fmtInfo.valueMax-fmtInfo.valueMin;
1432
1433 // Create textures.
1434
1435 m_textures.reserve(2);
1436 for (int ndx = 0; ndx < 2; ndx++)
1437 {
1438 m_textures.push_back(TestTextureCubeArraySp(new pipeline::TestTextureCubeArray(vk::mapVkFormat(m_testParameters.format), m_testParameters.size, m_testParameters.numLayers)));
1439 }
1440
1441 // Fill first with gradient texture.
1442 static const tcu::Vec4 gradients[tcu::CUBEFACE_LAST][2] =
1443 {
1444 { tcu::Vec4(-1.0f, -1.0f, -1.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // negative x
1445 { tcu::Vec4( 0.0f, -1.0f, -1.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // positive x
1446 { tcu::Vec4(-1.0f, 0.0f, -1.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // negative y
1447 { tcu::Vec4(-1.0f, -1.0f, 0.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // positive y
1448 { tcu::Vec4(-1.0f, -1.0f, -1.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f) }, // negative z
1449 { tcu::Vec4( 0.0f, 0.0f, 0.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) } // positive z
1450 };
1451
1452 for (int layerFace = 0; layerFace < m_textures[0]->getArraySize(); layerFace++)
1453 {
1454 const int face = layerFace % 6;
1455 const int layer = layerFace / 6;
1456 const tcu::Vec4 gradient0 = gradients[face][0] / float(layer + 1);
1457 const tcu::Vec4 gradient1 = gradients[face][1] / float(layer + 1);
1458
1459 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
1460 {
1461 tcu::fillWithComponentGradients(m_textures[0]->getLevel(levelNdx, layerFace), gradient0*cScale + cBias, gradient1*cScale + cBias);
1462 }
1463 }
1464
1465 // Fill second with grid texture.
1466 for (int layerFace = 0; layerFace < m_textures[1]->getArraySize(); layerFace++)
1467 {
1468 const int face = layerFace % 6;
1469 const int layer = layerFace / 6;
1470 const int cellSize = 4 + layer;
1471
1472 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
1473 {
1474 const deUint32 step = 0x00ffffff / (numLevels*tcu::CUBEFACE_LAST);
1475 const deUint32 rgb = step*levelNdx*face;
1476 const deUint32 colorA = 0xff000000 | rgb;
1477 const deUint32 colorB = 0xff000000 | ~rgb;
1478
1479 tcu::fillWithGrid(m_textures[1]->getLevel(levelNdx, layerFace), cellSize, tcu::RGBA(colorA).toVec()*cScale + cBias, tcu::RGBA(colorB).toVec()*cScale + cBias);
1480 }
1481 }
1482
1483 // Upload.
1484 for (vector<TestTextureCubeArraySp>::iterator i = m_textures.begin(); i != m_textures.end(); i++)
1485 {
1486 m_renderer.addCubeArrayTexture(*i, m_testParameters.aspectMask, m_testParameters.backingMode);
1487 }
1488
1489 // Compute cases
1490 {
1491 const bool compareModeSet = (m_testParameters.compareOp == Sampler::COMPAREMODE_EQUAL || m_testParameters.compareOp == Sampler::COMPAREMODE_NOT_EQUAL);
1492 const float refInRangeUpper = compareModeSet ? 1.0f : 0.5f;
1493 const float refInRangeLower = compareModeSet ? 0.0f : 0.5f;
1494 const float refOutOfBoundsUpper = 1.1f;
1495 const float refOutOfBoundsLower = -0.1f;
1496
1497 m_cases.push_back(FilterCase(0, refInRangeUpper, tcu::Vec2(-1.25f, -1.2f), tcu::Vec2(1.2f, 1.25f))); // minification
1498 m_cases.push_back(FilterCase(0, refInRangeLower, tcu::Vec2(0.8f, 0.8f), tcu::Vec2(1.25f, 1.20f))); // magnification
1499 m_cases.push_back(FilterCase(1, refInRangeUpper, tcu::Vec2(-1.19f, -1.3f), tcu::Vec2(1.1f, 1.35f))); // minification
1500 m_cases.push_back(FilterCase(1, refInRangeLower, tcu::Vec2(-1.2f, -1.1f), tcu::Vec2(-0.8f, -0.8f))); // magnification
1501 m_cases.push_back(FilterCase(1, refOutOfBoundsUpper, tcu::Vec2(-0.61f, -0.1f), tcu::Vec2(0.9f, 1.18f))); // reference value clamp, upper
1502 m_cases.push_back(FilterCase(1, refOutOfBoundsLower, tcu::Vec2(-0.75f, 1.0f), tcu::Vec2(0.05f, 0.75f))); // reference value clamp, lower
1503 }
1504 }
1505
~TextureCubeArrayShadowTestInstance(void)1506 TextureCubeArrayShadowTestInstance::~TextureCubeArrayShadowTestInstance (void)
1507 {
1508 }
1509
iterate(void)1510 tcu::TestStatus TextureCubeArrayShadowTestInstance::iterate (void)
1511 {
1512
1513 tcu::TestLog& log = m_context.getTestContext().getLog();
1514 const tcu::ScopedLogSection iterSection (log, string("Test") + de::toString(m_caseNdx), string("Test ") + de::toString(m_caseNdx));
1515 const FilterCase& curCase = m_cases[m_caseNdx];
1516 const pipeline::TestTextureCubeArray& texture = m_renderer.getCubeArrayTexture(curCase.textureIndex);
1517
1518 ReferenceParams sampleParams (TEXTURETYPE_CUBE_ARRAY);
1519
1520 // Params for reference computation.
1521 sampleParams.sampler = util::createSampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, m_testParameters.minFilter, m_testParameters.magFilter);
1522 sampleParams.sampler.seamlessCubeMap = m_testParameters.seamless;
1523 sampleParams.sampler.compare = m_testParameters.compareOp;
1524 sampleParams.samplerType = SAMPLERTYPE_SHADOW;
1525 sampleParams.lodMode = LODMODE_EXACT;
1526 sampleParams.ref = curCase.ref;
1527
1528 log << TestLog::Message
1529 << "Compare reference value = " << sampleParams.ref << "\n"
1530 << "Coordinates: " << curCase.bottomLeft << " -> " << curCase.topRight
1531 << TestLog::EndMessage;
1532
1533 for (int layerFace = 0; layerFace < m_textures[curCase.textureIndex]->getArraySize(); layerFace++)
1534 {
1535 const tcu::CubeFace face = tcu::CubeFace(layerFace % 6);
1536 const int layer = layerFace / 6;
1537 const float minLayer = -0.5f + float(layer);
1538 const float maxLayer = (float)m_testParameters.numLayers;
1539 tcu::Surface result (m_renderer.getRenderWidth(), m_renderer.getRenderHeight());
1540 vector<float> texCoord;
1541
1542 computeQuadTexCoordCubeArray(texCoord, face, curCase.bottomLeft, curCase.topRight, tcu::Vec2(minLayer, maxLayer));
1543
1544 log << TestLog::Message << "Face " << getFaceDesc(face) << " at layer " << layer << TestLog::EndMessage;
1545
1546 // \todo Log texture coordinates.
1547
1548 m_renderer.renderQuad(result, curCase.textureIndex, &texCoord[0], sampleParams);
1549
1550 {
1551 const tcu::PixelFormat pixelFormat = getPixelFormat(vk::mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM));
1552 tcu::LodPrecision lodPrecision;
1553 tcu::TexComparePrecision texComparePrecision;
1554
1555 lodPrecision.derivateBits = 10;
1556 lodPrecision.lodBits = 5;
1557 texComparePrecision.coordBits = tcu::IVec3(10,10,10);
1558 texComparePrecision.uvwBits = tcu::IVec3(6,6,0);
1559 texComparePrecision.pcfBits = 5;
1560 texComparePrecision.referenceBits = 16;
1561 texComparePrecision.resultBits = pixelFormat.redBits-1;
1562
1563 #ifdef CTS_USES_VULKANSC
1564 if (m_context.getTestContext().getCommandLine().isSubProcess())
1565 #endif // CTS_USES_VULKANSC
1566 {
1567 const bool isHighQuality = verifyTexCompareResult(m_context.getTestContext(), result.getAccess(), texture.getTexture(),
1568 &texCoord[0], sampleParams, texComparePrecision, lodPrecision, pixelFormat);
1569
1570 if (!isHighQuality)
1571 {
1572 log << TestLog::Message << "Warning: Verification assuming high-quality PCF filtering failed." << TestLog::EndMessage;
1573
1574 lodPrecision.lodBits = 4;
1575 texComparePrecision.uvwBits = tcu::IVec3(4,4,0);
1576 texComparePrecision.pcfBits = 0;
1577
1578 const bool isOk = verifyTexCompareResult(m_context.getTestContext(), result.getAccess(), texture.getTexture(),
1579 &texCoord[0], sampleParams, texComparePrecision, lodPrecision, pixelFormat);
1580
1581 if (!isOk)
1582 {
1583 log << TestLog::Message << "ERROR: Verification against low precision requirements failed, failing test case." << TestLog::EndMessage;
1584 return tcu::TestStatus::fail("Image verification failed");
1585 }
1586 }
1587 }
1588 }
1589 }
1590
1591 m_caseNdx += 1;
1592 return m_caseNdx < (int)m_cases.size() ? tcu::TestStatus::incomplete() : tcu::TestStatus::pass("Pass");
1593 }
1594 } // anonymous
1595
populateTextureShadowTests(tcu::TestCaseGroup * textureShadowTests)1596 void populateTextureShadowTests (tcu::TestCaseGroup* textureShadowTests)
1597 {
1598 tcu::TestContext& testCtx = textureShadowTests->getTestContext();
1599
1600 static const struct
1601 {
1602 const char* name;
1603 const TextureBinding::ImageBackingMode backingMode;
1604 } backingModes[] =
1605 {
1606 { "", TextureBinding::IMAGE_BACKING_MODE_REGULAR },
1607 #ifndef CTS_USES_VULKANSC
1608 { "sparse_", TextureBinding::IMAGE_BACKING_MODE_SPARSE }
1609 #endif // CTS_USES_VULKANSC
1610 };
1611
1612 static const struct
1613 {
1614 const char* name;
1615 const VkFormat format;
1616 const VkImageAspectFlags aspect;
1617 } formats[] =
1618 {
1619 { "d16_unorm", VK_FORMAT_D16_UNORM, VK_IMAGE_ASPECT_DEPTH_BIT },
1620 { "x8_d24_unorm_pack32", VK_FORMAT_X8_D24_UNORM_PACK32, VK_IMAGE_ASPECT_DEPTH_BIT },
1621 { "d32_sfloat", VK_FORMAT_D32_SFLOAT, VK_IMAGE_ASPECT_DEPTH_BIT },
1622 { "d16_unorm_s8_uint", VK_FORMAT_D16_UNORM_S8_UINT, VK_IMAGE_ASPECT_DEPTH_BIT },
1623 { "d24_unorm_s8_uint", VK_FORMAT_D24_UNORM_S8_UINT, VK_IMAGE_ASPECT_DEPTH_BIT },
1624 { "d32_sfloat_s8_uint", VK_FORMAT_D32_SFLOAT_S8_UINT, VK_IMAGE_ASPECT_DEPTH_BIT },
1625 { "r16_unorm", VK_FORMAT_R16_UNORM, VK_IMAGE_ASPECT_COLOR_BIT },
1626 { "r32_sfloat", VK_FORMAT_R32_SFLOAT, VK_IMAGE_ASPECT_COLOR_BIT }
1627 };
1628
1629 static const struct
1630 {
1631 const char* name;
1632 const Sampler::FilterMode minFilter;
1633 const Sampler::FilterMode magFilter;
1634 } filters[] =
1635 {
1636 { "nearest", Sampler::NEAREST, Sampler::NEAREST },
1637 { "linear", Sampler::LINEAR, Sampler::LINEAR },
1638 { "nearest_mipmap_nearest", Sampler::NEAREST_MIPMAP_NEAREST, Sampler::LINEAR },
1639 { "linear_mipmap_nearest", Sampler::LINEAR_MIPMAP_NEAREST, Sampler::LINEAR },
1640 { "nearest_mipmap_linear", Sampler::NEAREST_MIPMAP_LINEAR, Sampler::LINEAR },
1641 { "linear_mipmap_linear", Sampler::LINEAR_MIPMAP_LINEAR, Sampler::LINEAR }
1642 };
1643
1644 static const struct
1645 {
1646 const char* name;
1647 const Sampler::CompareMode op;
1648 } compareOp[] =
1649 {
1650 { "less_or_equal", Sampler::COMPAREMODE_LESS_OR_EQUAL },
1651 { "greater_or_equal", Sampler::COMPAREMODE_GREATER_OR_EQUAL },
1652 { "less", Sampler::COMPAREMODE_LESS },
1653 { "greater", Sampler::COMPAREMODE_GREATER },
1654 { "equal", Sampler::COMPAREMODE_EQUAL },
1655 { "not_equal", Sampler::COMPAREMODE_NOT_EQUAL },
1656 { "always", Sampler::COMPAREMODE_ALWAYS },
1657 { "never", Sampler::COMPAREMODE_NEVER }
1658 };
1659
1660 static const struct
1661 {
1662 const char* name;
1663 deBool seamless;
1664 } seamModes[] =
1665 {
1666 {"", true},
1667 #ifndef CTS_USES_VULKANSC
1668 {"non_seamless_", false}
1669 #endif // CTS_USES_VULKANSC
1670 };
1671
1672 // 2D cases.
1673 {
1674 de::MovePtr<tcu::TestCaseGroup> group2D (new tcu::TestCaseGroup(testCtx, "2d", "2D texture shadow lookup tests"));
1675
1676 for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(filters); filterNdx++)
1677 {
1678 de::MovePtr<tcu::TestCaseGroup> filterGroup (new tcu::TestCaseGroup(testCtx, filters[filterNdx].name, ""));
1679
1680 for (int compareNdx = 0; compareNdx < DE_LENGTH_OF_ARRAY(compareOp); compareNdx++)
1681 {
1682 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
1683 {
1684 for (int backingNdx = 0; backingNdx < DE_LENGTH_OF_ARRAY(backingModes); backingNdx++)
1685 {
1686 const string name = string(backingModes[backingNdx].name) + compareOp[compareNdx].name + "_" + formats[formatNdx].name;
1687 Texture2DShadowTestCaseParameters testParameters;
1688
1689 testParameters.minFilter = filters[filterNdx].minFilter;
1690 testParameters.magFilter = filters[filterNdx].magFilter;
1691 testParameters.format = formats[formatNdx].format;
1692 testParameters.backingMode = backingModes[backingNdx].backingMode;
1693 testParameters.compareOp = compareOp[compareNdx].op;
1694 testParameters.wrapS = Sampler::REPEAT_GL;
1695 testParameters.wrapT = Sampler::REPEAT_GL;
1696 testParameters.width = 32;
1697 testParameters.height = 64;
1698 testParameters.aspectMask = formats[formatNdx].aspect;
1699 testParameters.programs.push_back(PROGRAM_2D_SHADOW);
1700
1701 filterGroup->addChild(new TextureTestCase<Texture2DShadowTestInstance>(testCtx, name.c_str(), "", testParameters));
1702 }
1703 }
1704 }
1705
1706 group2D->addChild(filterGroup.release());
1707 }
1708
1709 textureShadowTests->addChild(group2D.release());
1710 }
1711
1712 // Cubemap cases.
1713 {
1714 de::MovePtr<tcu::TestCaseGroup> groupCube (new tcu::TestCaseGroup(testCtx, "cube", "Cube map texture shadow lookup tests"));
1715
1716 for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(filters); filterNdx++)
1717 {
1718 de::MovePtr<tcu::TestCaseGroup> filterGroup (new tcu::TestCaseGroup(testCtx, filters[filterNdx].name, ""));
1719
1720 for (int compareNdx = 0; compareNdx < DE_LENGTH_OF_ARRAY(compareOp); compareNdx++)
1721 {
1722 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
1723 {
1724 for (int backingNdx = 0; backingNdx < DE_LENGTH_OF_ARRAY(backingModes); backingNdx++)
1725 {
1726 for (int seamNdx = 0; seamNdx < DE_LENGTH_OF_ARRAY(seamModes); seamNdx++)
1727 {
1728 const string name = string(backingModes[backingNdx].name) + seamModes[seamNdx].name + compareOp[compareNdx].name + "_" + formats[formatNdx].name;
1729 TextureCubeShadowTestCaseParameters testParameters;
1730
1731 testParameters.minFilter = filters[filterNdx].minFilter;
1732 testParameters.magFilter = filters[filterNdx].magFilter;
1733 testParameters.format = formats[formatNdx].format;
1734 testParameters.backingMode = backingModes[backingNdx].backingMode;
1735 testParameters.seamless = seamModes[seamNdx].seamless;
1736 testParameters.compareOp = compareOp[compareNdx].op;
1737 testParameters.wrapS = Sampler::REPEAT_GL;
1738 testParameters.wrapT = Sampler::REPEAT_GL;
1739 testParameters.size = 32;
1740 testParameters.aspectMask = formats[formatNdx].aspect;
1741
1742 testParameters.programs.push_back(PROGRAM_CUBE_SHADOW);
1743
1744 filterGroup->addChild(new TextureTestCase<TextureCubeShadowTestInstance>(testCtx, name.c_str(), "", testParameters));
1745 }
1746 }
1747 }
1748 }
1749
1750 groupCube->addChild(filterGroup.release());
1751 }
1752
1753 textureShadowTests->addChild(groupCube.release());
1754 }
1755
1756 // 2D array cases.
1757 {
1758 de::MovePtr<tcu::TestCaseGroup> group2DArray (new tcu::TestCaseGroup(testCtx, "2d_array", "2D texture array shadow lookup tests"));
1759
1760 for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(filters); filterNdx++)
1761 {
1762 de::MovePtr<tcu::TestCaseGroup> filterGroup (new tcu::TestCaseGroup(testCtx, filters[filterNdx].name, ""));
1763
1764 for (int compareNdx = 0; compareNdx < DE_LENGTH_OF_ARRAY(compareOp); compareNdx++)
1765 {
1766 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
1767 {
1768 for (int backingNdx = 0; backingNdx < DE_LENGTH_OF_ARRAY(backingModes); backingNdx++)
1769 {
1770 const string name = string(backingModes[backingNdx].name) + compareOp[compareNdx].name + "_" + formats[formatNdx].name;
1771 Texture2DArrayShadowTestCaseParameters testParameters;
1772
1773 testParameters.minFilter = filters[filterNdx].minFilter;
1774 testParameters.magFilter = filters[filterNdx].magFilter;
1775 testParameters.format = formats[formatNdx].format;
1776 testParameters.backingMode = backingModes[backingNdx].backingMode;
1777 testParameters.compareOp = compareOp[compareNdx].op;
1778 testParameters.wrapS = Sampler::REPEAT_GL;
1779 testParameters.wrapT = Sampler::REPEAT_GL;
1780 testParameters.width = 32;
1781 testParameters.height = 64;
1782 testParameters.numLayers = 8;
1783 testParameters.aspectMask = formats[formatNdx].aspect;
1784
1785 testParameters.programs.push_back(PROGRAM_2D_ARRAY_SHADOW);
1786
1787 filterGroup->addChild(new TextureTestCase<Texture2DArrayShadowTestInstance>(testCtx, name.c_str(), "", testParameters));
1788 }
1789 }
1790 }
1791
1792 group2DArray->addChild(filterGroup.release());
1793 }
1794
1795 textureShadowTests->addChild(group2DArray.release());
1796 }
1797
1798 // 1D cases.
1799 {
1800 de::MovePtr<tcu::TestCaseGroup> group1D (new tcu::TestCaseGroup(testCtx, "1d", "1D texture shadow lookup tests"));
1801
1802 for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(filters); filterNdx++)
1803 {
1804 de::MovePtr<tcu::TestCaseGroup> filterGroup (new tcu::TestCaseGroup(testCtx, filters[filterNdx].name, ""));
1805
1806 for (int compareNdx = 0; compareNdx < DE_LENGTH_OF_ARRAY(compareOp); compareNdx++)
1807 {
1808 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
1809 {
1810 for (int backingNdx = 0; backingNdx < DE_LENGTH_OF_ARRAY(backingModes); backingNdx++)
1811 {
1812 const string name = string(backingModes[backingNdx].name) + compareOp[compareNdx].name + "_" + formats[formatNdx].name;
1813 Texture1DShadowTestCaseParameters testParameters;
1814
1815 testParameters.minFilter = filters[filterNdx].minFilter;
1816 testParameters.magFilter = filters[filterNdx].magFilter;
1817 testParameters.format = formats[formatNdx].format;
1818 testParameters.backingMode = backingModes[backingNdx].backingMode;
1819 testParameters.compareOp = compareOp[compareNdx].op;
1820 testParameters.wrapS = Sampler::REPEAT_GL;
1821 testParameters.width = 32;
1822 testParameters.aspectMask = formats[formatNdx].aspect;
1823 testParameters.programs.push_back(PROGRAM_1D_SHADOW);
1824
1825 filterGroup->addChild(new TextureTestCase<Texture1DShadowTestInstance>(testCtx, name.c_str(), "", testParameters));
1826 }
1827 }
1828 }
1829
1830 group1D->addChild(filterGroup.release());
1831 }
1832
1833 textureShadowTests->addChild(group1D.release());
1834 }
1835
1836 // 1D array cases.
1837 {
1838 de::MovePtr<tcu::TestCaseGroup> group1DArray (new tcu::TestCaseGroup(testCtx, "1d_array", "1D texture array shadow lookup tests"));
1839
1840 for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(filters); filterNdx++)
1841 {
1842 de::MovePtr<tcu::TestCaseGroup> filterGroup (new tcu::TestCaseGroup(testCtx, filters[filterNdx].name, ""));
1843
1844 for (int compareNdx = 0; compareNdx < DE_LENGTH_OF_ARRAY(compareOp); compareNdx++)
1845 {
1846 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
1847 {
1848 for (int backingNdx = 0; backingNdx < DE_LENGTH_OF_ARRAY(backingModes); backingNdx++)
1849 {
1850 const string name = string(backingModes[backingNdx].name) + compareOp[compareNdx].name + "_" + formats[formatNdx].name;
1851 Texture1DArrayShadowTestCaseParameters testParameters;
1852
1853 testParameters.minFilter = filters[filterNdx].minFilter;
1854 testParameters.magFilter = filters[filterNdx].magFilter;
1855 testParameters.format = formats[formatNdx].format;
1856 testParameters.backingMode = backingModes[backingNdx].backingMode;
1857 testParameters.compareOp = compareOp[compareNdx].op;
1858 testParameters.wrapS = Sampler::REPEAT_GL;
1859 testParameters.width = 32;
1860 testParameters.numLayers = 8;
1861 testParameters.aspectMask = formats[formatNdx].aspect;
1862
1863 testParameters.programs.push_back(PROGRAM_1D_ARRAY_SHADOW);
1864
1865 filterGroup->addChild(new TextureTestCase<Texture1DArrayShadowTestInstance>(testCtx, name.c_str(), "", testParameters));
1866 }
1867 }
1868 }
1869
1870 group1DArray->addChild(filterGroup.release());
1871 }
1872
1873 textureShadowTests->addChild(group1DArray.release());
1874 }
1875
1876 // Cubemap Array cases.
1877 {
1878 de::MovePtr<tcu::TestCaseGroup> groupCubeArray (new tcu::TestCaseGroup(testCtx, "cube_array", "Cube map texture shadow lookup tests"));
1879
1880 for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(filters); filterNdx++)
1881 {
1882 de::MovePtr<tcu::TestCaseGroup> filterGroup (new tcu::TestCaseGroup(testCtx, filters[filterNdx].name, ""));
1883
1884 for (int compareNdx = 0; compareNdx < DE_LENGTH_OF_ARRAY(compareOp); compareNdx++)
1885 {
1886 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
1887 {
1888 for (int backingNdx = 0; backingNdx < DE_LENGTH_OF_ARRAY(backingModes); backingNdx++)
1889 {
1890 for (int seamNdx = 0; seamNdx < DE_LENGTH_OF_ARRAY(seamModes); seamNdx++)
1891 {
1892 const string name = string(backingModes[backingNdx].name) + seamModes[seamNdx].name + compareOp[compareNdx].name + "_" + formats[formatNdx].name;
1893 TextureCubeArrayShadowTestCaseParameters testParameters;
1894
1895 testParameters.minFilter = filters[filterNdx].minFilter;
1896 testParameters.magFilter = filters[filterNdx].magFilter;
1897 testParameters.format = formats[formatNdx].format;
1898 testParameters.backingMode = backingModes[backingNdx].backingMode;
1899 testParameters.compareOp = compareOp[compareNdx].op;
1900 testParameters.seamless = seamModes[seamNdx].seamless;
1901 testParameters.wrapS = Sampler::REPEAT_GL;
1902 testParameters.wrapT = Sampler::REPEAT_GL;
1903 testParameters.size = 32;
1904 testParameters.numLayers = 4 * 6;
1905 testParameters.aspectMask = formats[formatNdx].aspect;
1906
1907 testParameters.programs.push_back(PROGRAM_CUBE_ARRAY_SHADOW);
1908
1909 filterGroup->addChild(new TextureTestCase<TextureCubeArrayShadowTestInstance>(testCtx, name.c_str(), "", testParameters));
1910 }
1911 }
1912 }
1913 }
1914
1915 groupCubeArray->addChild(filterGroup.release());
1916 }
1917
1918 textureShadowTests->addChild(groupCubeArray.release());
1919 }
1920 #ifndef CTS_USES_VULKANSC
1921 // Texel replacement tests.
1922 {
1923 de::MovePtr<tcu::TestCaseGroup> groupTexelReplacement (new tcu::TestCaseGroup(testCtx, "texel_replacement", "Texel replacement texture shadow lookup tests"));
1924
1925 cts_amber::AmberTestCase* testCaseLod = cts_amber::createAmberTestCase(testCtx, "d32_sfloat", "", "texture/shadow/texel_replacement", "d32_sfloat.amber");
1926
1927 groupTexelReplacement->addChild(testCaseLod);
1928 textureShadowTests->addChild(groupTexelReplacement.release());
1929 }
1930 #endif // CTS_USES_VULKANSC
1931 }
1932
createTextureShadowTests(tcu::TestContext & testCtx)1933 tcu::TestCaseGroup* createTextureShadowTests (tcu::TestContext& testCtx)
1934 {
1935 return createTestGroup(testCtx, "shadow", "Texture shadow tests.", populateTextureShadowTests);
1936 }
1937
1938 } // texture
1939 } // vkt
1940