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