1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Imagination Technologies Ltd.
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 *//*!
21 * \file
22 * \brief Sampler Tests
23 *//*--------------------------------------------------------------------*/
24
25 #include "vktPipelineSamplerTests.hpp"
26 #include "vktPipelineImageSamplingInstance.hpp"
27 #include "vktPipelineImageUtil.hpp"
28 #include "vktPipelineVertexUtil.hpp"
29 #include "vktTestCase.hpp"
30 #include "vkImageUtil.hpp"
31 #include "vkPrograms.hpp"
32 #include "tcuPlatform.hpp"
33 #include "tcuTextureUtil.hpp"
34 #include "deStringUtil.hpp"
35 #include "deMemory.h"
36
37 #include <iomanip>
38 #include <sstream>
39 #include <vector>
40
41 namespace vkt
42 {
43 namespace pipeline
44 {
45
46 using namespace vk;
47 using de::MovePtr;
48
49 namespace
50 {
51
52 class SamplerTest : public vkt::TestCase
53 {
54 public:
55 SamplerTest (tcu::TestContext& testContext,
56 const char* name,
57 const char* description,
58 VkImageViewType imageViewType,
59 VkFormat imageFormat,
60 int imageSize,
61 float samplerLod);
~SamplerTest(void)62 virtual ~SamplerTest (void) {}
63
64 tcu::Vec4 swizzle (tcu::Vec4 inputData, VkComponentMapping componentMapping, float zeroOrOneValue) const;
65 virtual void initPrograms (SourceCollections& sourceCollections) const;
66 virtual TestInstance* createInstance (Context& context) const;
67 virtual tcu::UVec2 getRenderSize (VkImageViewType viewType) const;
68 virtual std::vector<Vertex4Tex4> createVertices (void) const;
69 virtual VkSamplerCreateInfo getSamplerCreateInfo (void) const;
70 virtual VkComponentMapping getComponentMapping (void) const;
71
72 static std::string getGlslSamplerType (const tcu::TextureFormat& format, VkImageViewType type);
73 static tcu::IVec3 getImageSize (VkImageViewType viewType, int size);
74 static int getArraySize (VkImageViewType viewType);
75
76 protected:
77 VkImageViewType m_imageViewType;
78 VkFormat m_imageFormat;
79 int m_imageSize;
80 VkImageViewCreateInfo m_imageViewParams;
81 VkSamplerCreateInfo m_samplerParams;
82 float m_samplerLod;
83 };
84
85 class SamplerMagFilterTest : public SamplerTest
86 {
87 public:
88 SamplerMagFilterTest (tcu::TestContext& testContext,
89 const char* name,
90 const char* description,
91 VkImageViewType imageViewType,
92 VkFormat imageFormat,
93 VkFilter magFilter);
~SamplerMagFilterTest(void)94 virtual ~SamplerMagFilterTest (void) {}
95 virtual VkSamplerCreateInfo getSamplerCreateInfo (void) const;
96
97 private:
98 VkFilter m_magFilter;
99 };
100
101 class SamplerMinFilterTest : public SamplerTest
102 {
103 public:
104 SamplerMinFilterTest (tcu::TestContext& testContext,
105 const char* name,
106 const char* description,
107 VkImageViewType imageViewType,
108 VkFormat imageFormat,
109 VkFilter minFilter);
~SamplerMinFilterTest(void)110 virtual ~SamplerMinFilterTest (void) {}
111 virtual VkSamplerCreateInfo getSamplerCreateInfo (void) const;
112
113 private:
114 VkFilter m_minFilter;
115 };
116
117 class SamplerMagReduceFilterTest : public SamplerMagFilterTest
118 {
119 public:
120 SamplerMagReduceFilterTest (tcu::TestContext& testContext,
121 const char* name,
122 const char* description,
123 VkImageViewType imageViewType,
124 VkFormat imageFormat,
125 VkComponentMapping componentMapping,
126 VkSamplerReductionModeEXT reductionMode);
127
~SamplerMagReduceFilterTest(void)128 virtual ~SamplerMagReduceFilterTest (void) {}
129 virtual VkSamplerCreateInfo getSamplerCreateInfo (void) const;
130 virtual VkComponentMapping getComponentMapping (void) const;
131
132 private:
133 const VkSamplerReductionModeCreateInfoEXT m_reductionCreaterInfo;
134 VkComponentMapping m_componentMapping;
135 };
136
137 class SamplerMinReduceFilterTest : public SamplerMinFilterTest
138 {
139 public:
140 SamplerMinReduceFilterTest (tcu::TestContext& testContext,
141 const char* name,
142 const char* description,
143 VkImageViewType imageViewType,
144 VkFormat imageFormat,
145 VkComponentMapping componentMapping,
146 VkSamplerReductionModeEXT reductionMode);
147
~SamplerMinReduceFilterTest(void)148 virtual ~SamplerMinReduceFilterTest (void) {}
149 virtual VkSamplerCreateInfo getSamplerCreateInfo (void) const;
150 virtual VkComponentMapping getComponentMapping (void) const;
151
152 private:
153 const VkSamplerReductionModeCreateInfoEXT m_reductionCreaterInfo;
154 VkComponentMapping m_componentMapping;
155 };
156
157 class SamplerLodTest : public SamplerTest
158 {
159 public:
160 SamplerLodTest (tcu::TestContext& testContext,
161 const char* name,
162 const char* description,
163 VkImageViewType imageViewType,
164 VkFormat imageFormat,
165 VkSamplerMipmapMode mipmapMode,
166 float minLod,
167 float maxLod,
168 float mipLodBias,
169 float samplerLod);
~SamplerLodTest(void)170 virtual ~SamplerLodTest (void) {}
171 virtual VkSamplerCreateInfo getSamplerCreateInfo (void) const;
172
173 private:
174 VkSamplerMipmapMode m_mipmapMode;
175 float m_minLod;
176 float m_maxLod;
177 float m_mipLodBias;
178 };
179
180 class SamplerAddressModesTest : public SamplerTest
181 {
182 public:
183 SamplerAddressModesTest (tcu::TestContext& testContext,
184 const char* name,
185 const char* description,
186 VkImageViewType imageViewType,
187 VkFormat imageFormat,
188 VkSamplerAddressMode addressU,
189 VkSamplerAddressMode addressV,
190 VkSamplerAddressMode addressW,
191 VkBorderColor borderColor);
~SamplerAddressModesTest(void)192 virtual ~SamplerAddressModesTest (void) {}
193 virtual tcu::UVec2 getRenderSize (VkImageViewType viewType) const;
194 virtual std::vector<Vertex4Tex4> createVertices (void) const;
195 virtual VkSamplerCreateInfo getSamplerCreateInfo (void) const;
196
197 private:
198 VkSamplerAddressMode m_addressU;
199 VkSamplerAddressMode m_addressV;
200 VkSamplerAddressMode m_addressW;
201 VkBorderColor m_borderColor;
202 };
203
204
205 // SamplerTest
206
SamplerTest(tcu::TestContext & testContext,const char * name,const char * description,VkImageViewType imageViewType,VkFormat imageFormat,int imageSize,float samplerLod)207 SamplerTest::SamplerTest (tcu::TestContext& testContext,
208 const char* name,
209 const char* description,
210 VkImageViewType imageViewType,
211 VkFormat imageFormat,
212 int imageSize,
213 float samplerLod)
214 : vkt::TestCase (testContext, name, description)
215 , m_imageViewType (imageViewType)
216 , m_imageFormat (imageFormat)
217 , m_imageSize (imageSize)
218 , m_samplerLod (samplerLod)
219 {
220 }
221
swizzle(tcu::Vec4 inputData,VkComponentMapping componentMapping,float zeroOrOneValue) const222 tcu::Vec4 SamplerTest::swizzle (tcu::Vec4 inputData, VkComponentMapping componentMapping, float zeroOrOneValue) const
223 {
224 // Remove VK_COMPONENT_SWIZZLE_IDENTITY to avoid addressing channelValues[0]
225 const vk::VkComponentMapping nonIdentityMapping =
226 {
227 componentMapping.r == VK_COMPONENT_SWIZZLE_IDENTITY ? VK_COMPONENT_SWIZZLE_R : componentMapping.r,
228 componentMapping.g == VK_COMPONENT_SWIZZLE_IDENTITY ? VK_COMPONENT_SWIZZLE_G : componentMapping.g,
229 componentMapping.b == VK_COMPONENT_SWIZZLE_IDENTITY ? VK_COMPONENT_SWIZZLE_B : componentMapping.b,
230 componentMapping.a == VK_COMPONENT_SWIZZLE_IDENTITY ? VK_COMPONENT_SWIZZLE_A : componentMapping.a
231
232 };
233 // array map with enum VkComponentSwizzle
234 const float channelValues[] =
235 {
236 -1.0f, // impossible
237 zeroOrOneValue, // SWIZZLE_0
238 zeroOrOneValue, // SWIZZLE_1
239 inputData.x(),
240 inputData.y(),
241 inputData.z(),
242 inputData.w(),
243 -1.0f
244 };
245
246 return tcu::Vec4(channelValues[nonIdentityMapping.r],
247 channelValues[nonIdentityMapping.g],
248 channelValues[nonIdentityMapping.b],
249 channelValues[nonIdentityMapping.a]);
250 }
251
initPrograms(SourceCollections & sourceCollections) const252 void SamplerTest::initPrograms (SourceCollections& sourceCollections) const
253 {
254 std::ostringstream vertexSrc;
255 std::ostringstream fragmentSrc;
256 const char* texCoordSwizzle = DE_NULL;
257 tcu::TextureFormat format = (isCompressedFormat(m_imageFormat)) ? tcu::getUncompressedFormat(mapVkCompressedFormat(m_imageFormat))
258 : mapVkFormat(m_imageFormat);
259 tcu::Vec4 lookupScale;
260 tcu::Vec4 lookupBias;
261
262 getLookupScaleBias(m_imageFormat, lookupScale, lookupBias);
263
264 tcu::Vec4 swizzledScale = swizzle(lookupScale, getComponentMapping(), 1.0f);
265 tcu::Vec4 swizzledBias = swizzle(lookupBias, getComponentMapping(), 0.0f);
266
267 switch (m_imageViewType)
268 {
269 case VK_IMAGE_VIEW_TYPE_1D:
270 texCoordSwizzle = "x";
271 break;
272 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
273 case VK_IMAGE_VIEW_TYPE_2D:
274 texCoordSwizzle = "xy";
275 break;
276 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
277 case VK_IMAGE_VIEW_TYPE_3D:
278 case VK_IMAGE_VIEW_TYPE_CUBE:
279 texCoordSwizzle = "xyz";
280 break;
281 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
282 texCoordSwizzle = "xyzw";
283 break;
284 default:
285 DE_ASSERT(false);
286 break;
287 }
288
289 vertexSrc << "#version 440\n"
290 << "layout(location = 0) in vec4 position;\n"
291 << "layout(location = 1) in vec4 texCoords;\n"
292 << "layout(location = 0) out highp vec4 vtxTexCoords;\n"
293 << "out gl_PerVertex {\n"
294 << " vec4 gl_Position;\n"
295 << "};\n"
296 << "void main (void)\n"
297 << "{\n"
298 << " gl_Position = position;\n"
299 << " vtxTexCoords = texCoords;\n"
300 << "}\n";
301
302 fragmentSrc << "#version 440\n"
303 << "layout(set = 0, binding = 0) uniform highp " << getGlslSamplerType(format, m_imageViewType) << " texSampler;\n"
304 << "layout(location = 0) in highp vec4 vtxTexCoords;\n"
305 << "layout(location = 0) out highp vec4 fragColor;\n"
306 << "void main (void)\n"
307 << "{\n"
308 << " fragColor = ";
309
310 if (m_samplerLod > 0.0f)
311 fragmentSrc << "textureLod(texSampler, vtxTexCoords." << texCoordSwizzle << ", " << std::fixed << m_samplerLod << ")";
312 else
313 fragmentSrc << "texture(texSampler, vtxTexCoords." << texCoordSwizzle << ")" << std::fixed;
314
315 fragmentSrc << " * vec4" << std::scientific << swizzledScale << " + vec4" << swizzledBias << ";\n"
316 << "}\n";
317
318 sourceCollections.glslSources.add("tex_vert") << glu::VertexSource(vertexSrc.str());
319 sourceCollections.glslSources.add("tex_frag") << glu::FragmentSource(fragmentSrc.str());
320 }
321
createInstance(Context & context) const322 TestInstance* SamplerTest::createInstance (Context& context) const
323 {
324 const tcu::UVec2 renderSize = getRenderSize(m_imageViewType);
325 const std::vector<Vertex4Tex4> vertices = createVertices();
326 const VkSamplerCreateInfo samplerParams = getSamplerCreateInfo();
327 const VkComponentMapping componentMapping = getComponentMapping();
328
329 const VkImageAspectFlags imageAspect = (!isCompressedFormat(m_imageFormat) && hasDepthComponent(mapVkFormat(m_imageFormat).order)) ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
330
331 const VkImageSubresourceRange subresourceRange =
332 {
333 imageAspect, // VkImageAspectFlags aspectMask;
334 0u, // deUint32 baseMipLevel;
335 (deUint32)deLog2Floor32(m_imageSize) + 1, // deUint32 mipLevels;
336 0u, // deUint32 baseArrayLayer;
337 (deUint32)SamplerTest::getArraySize(m_imageViewType) // deUint32 arraySize;
338 };
339
340
341
342 return new ImageSamplingInstance(context, renderSize, m_imageViewType, m_imageFormat,
343 getImageSize(m_imageViewType, m_imageSize),
344 getArraySize(m_imageViewType),
345 componentMapping, subresourceRange,
346 samplerParams, m_samplerLod,vertices);
347 }
348
getRenderSize(VkImageViewType viewType) const349 tcu::UVec2 SamplerTest::getRenderSize (VkImageViewType viewType) const
350 {
351 if (viewType == VK_IMAGE_VIEW_TYPE_1D || viewType == VK_IMAGE_VIEW_TYPE_2D)
352 {
353 return tcu::UVec2(16u, 16u);
354 }
355 else
356 {
357 return tcu::UVec2(16u * 3u, 16u * 2u);
358 }
359 }
360
createVertices(void) const361 std::vector<Vertex4Tex4> SamplerTest::createVertices (void) const
362 {
363 std::vector<Vertex4Tex4> vertices = createTestQuadMosaic(m_imageViewType);
364 // Adjust texture coordinate to avoid doing NEAREST filtering exactly on texel boundaries.
365 // TODO: Would be nice to base this on number of texels and subtexel precision. But this
366 // seems to work.
367 for (unsigned int i = 0; i < vertices.size(); ++i) {
368 vertices[i].texCoord += tcu::Vec4(0.002f, 0.002f, 0.002f, 0.0f);
369 }
370 return vertices;
371 }
372
getSamplerCreateInfo(void) const373 VkSamplerCreateInfo SamplerTest::getSamplerCreateInfo (void) const
374 {
375 const VkSamplerCreateInfo defaultSamplerParams =
376 {
377 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType;
378 DE_NULL, // const void* pNext;
379 0u, // VkSamplerCreateFlags flags;
380 VK_FILTER_NEAREST, // VkFilter magFilter;
381 VK_FILTER_NEAREST, // VkFilter minFilter;
382 VK_SAMPLER_MIPMAP_MODE_NEAREST, // VkSamplerMipmapMode mipmapMode;
383 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeU;
384 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeV;
385 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeW;
386 0.0f, // float mipLodBias;
387 VK_FALSE, // VkBool32 anisotropyEnable;
388 1.0f, // float maxAnisotropy;
389 false, // VkBool32 compareEnable;
390 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp;
391 0.0f, // float minLod;
392 0.25f, // float maxLod;
393 getFormatBorderColor(BORDER_COLOR_TRANSPARENT_BLACK, m_imageFormat), // VkBorderColor borderColor;
394 false // VkBool32 unnormalizedCoordinates;
395 };
396
397 return defaultSamplerParams;
398 }
399
getComponentMapping(void) const400 VkComponentMapping SamplerTest::getComponentMapping (void) const
401 {
402 const VkComponentMapping componentMapping = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
403 return componentMapping;
404 }
405
getGlslSamplerType(const tcu::TextureFormat & format,VkImageViewType type)406 std::string SamplerTest::getGlslSamplerType (const tcu::TextureFormat& format, VkImageViewType type)
407 {
408 std::ostringstream samplerType;
409
410 if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
411 samplerType << "u";
412 else if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
413 samplerType << "i";
414
415 switch (type)
416 {
417 case VK_IMAGE_VIEW_TYPE_1D:
418 samplerType << "sampler1D";
419 break;
420
421 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
422 samplerType << "sampler1DArray";
423 break;
424
425 case VK_IMAGE_VIEW_TYPE_2D:
426 samplerType << "sampler2D";
427 break;
428
429 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
430 samplerType << "sampler2DArray";
431 break;
432
433 case VK_IMAGE_VIEW_TYPE_3D:
434 samplerType << "sampler3D";
435 break;
436
437 case VK_IMAGE_VIEW_TYPE_CUBE:
438 samplerType << "samplerCube";
439 break;
440
441 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
442 samplerType << "samplerCubeArray";
443 break;
444
445 default:
446 DE_FATAL("Unknown image view type");
447 break;
448 }
449
450 return samplerType.str();
451 }
452
getImageSize(VkImageViewType viewType,int size)453 tcu::IVec3 SamplerTest::getImageSize (VkImageViewType viewType, int size)
454 {
455 switch (viewType)
456 {
457 case VK_IMAGE_VIEW_TYPE_1D:
458 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
459 return tcu::IVec3(size, 1, 1);
460
461 case VK_IMAGE_VIEW_TYPE_3D:
462 return tcu::IVec3(size, size, 4);
463
464 default:
465 break;
466 }
467
468 return tcu::IVec3(size, size, 1);
469 }
470
getArraySize(VkImageViewType viewType)471 int SamplerTest::getArraySize (VkImageViewType viewType)
472 {
473 switch (viewType)
474 {
475 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
476 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
477 case VK_IMAGE_VIEW_TYPE_CUBE:
478 return 6;
479
480 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
481 return 36;
482
483 default:
484 break;
485 }
486
487 return 1;
488 }
489
490
491 // SamplerMagFilterTest
492
SamplerMagFilterTest(tcu::TestContext & testContext,const char * name,const char * description,VkImageViewType imageViewType,VkFormat imageFormat,VkFilter magFilter)493 SamplerMagFilterTest::SamplerMagFilterTest (tcu::TestContext& testContext,
494 const char* name,
495 const char* description,
496 VkImageViewType imageViewType,
497 VkFormat imageFormat,
498 VkFilter magFilter)
499 : SamplerTest (testContext, name, description, imageViewType, imageFormat, 8, 0.0f)
500 , m_magFilter (magFilter)
501 {
502 }
503
getSamplerCreateInfo(void) const504 VkSamplerCreateInfo SamplerMagFilterTest::getSamplerCreateInfo (void) const
505 {
506 VkSamplerCreateInfo samplerParams = SamplerTest::getSamplerCreateInfo();
507 samplerParams.magFilter = m_magFilter;
508
509 return samplerParams;
510 }
511
512
513 // SamplerMinFilterTest
514
SamplerMinFilterTest(tcu::TestContext & testContext,const char * name,const char * description,VkImageViewType imageViewType,VkFormat imageFormat,VkFilter minFilter)515 SamplerMinFilterTest::SamplerMinFilterTest (tcu::TestContext& testContext,
516 const char* name,
517 const char* description,
518 VkImageViewType imageViewType,
519 VkFormat imageFormat,
520 VkFilter minFilter)
521 : SamplerTest (testContext, name, description, imageViewType, imageFormat, 32, 0.0f)
522 , m_minFilter (minFilter)
523 {
524 }
525
getSamplerCreateInfo(void) const526 VkSamplerCreateInfo SamplerMinFilterTest::getSamplerCreateInfo (void) const
527 {
528 VkSamplerCreateInfo samplerParams = SamplerTest::getSamplerCreateInfo();
529 samplerParams.minFilter = m_minFilter;
530 // set minLod to epsilon, to force use of the minFilter
531 samplerParams.minLod = 0.01f;
532
533 return samplerParams;
534 }
535
536
537 namespace
538 {
539
getSamplerReductionCreateInfo(VkSamplerReductionModeEXT reductionMode)540 VkSamplerReductionModeCreateInfoEXT getSamplerReductionCreateInfo (VkSamplerReductionModeEXT reductionMode)
541 {
542 const VkSamplerReductionModeCreateInfoEXT ret =
543 {
544 VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT, // VkStructureType sType
545 DE_NULL, // const void* pNext
546 reductionMode // VkSamplerReductionModeEXT reductionMode
547 };
548 return ret;
549 }
550
551 }
552
553
554 // SamplerMagReduceFilterTest
555
SamplerMagReduceFilterTest(tcu::TestContext & testContext,const char * name,const char * description,VkImageViewType imageViewType,VkFormat imageFormat,VkComponentMapping componentMapping,VkSamplerReductionModeEXT reductionMode)556 SamplerMagReduceFilterTest::SamplerMagReduceFilterTest (tcu::TestContext& testContext,
557 const char* name,
558 const char* description,
559 VkImageViewType imageViewType,
560 VkFormat imageFormat,
561 VkComponentMapping componentMapping,
562 VkSamplerReductionModeEXT reductionMode)
563 : SamplerMagFilterTest (testContext, name, description, imageViewType, imageFormat, VK_FILTER_LINEAR)
564 , m_reductionCreaterInfo (getSamplerReductionCreateInfo(reductionMode))
565 , m_componentMapping (componentMapping)
566 {
567 }
568
getSamplerCreateInfo(void) const569 VkSamplerCreateInfo SamplerMagReduceFilterTest::getSamplerCreateInfo (void) const
570 {
571 VkSamplerCreateInfo samplerParams = SamplerMagFilterTest::getSamplerCreateInfo();
572
573 samplerParams.pNext = &m_reductionCreaterInfo;
574
575 return samplerParams;
576 }
577
getComponentMapping(void) const578 VkComponentMapping SamplerMagReduceFilterTest::getComponentMapping (void) const
579 {
580 return m_componentMapping;
581 }
582
583 // SamplerMinReduceFilterTest
584
SamplerMinReduceFilterTest(tcu::TestContext & testContext,const char * name,const char * description,VkImageViewType imageViewType,VkFormat imageFormat,VkComponentMapping componentMapping,VkSamplerReductionModeEXT reductionMode)585 SamplerMinReduceFilterTest::SamplerMinReduceFilterTest (tcu::TestContext& testContext,
586 const char* name,
587 const char* description,
588 VkImageViewType imageViewType,
589 VkFormat imageFormat,
590 VkComponentMapping componentMapping,
591 VkSamplerReductionModeEXT reductionMode)
592 : SamplerMinFilterTest (testContext, name, description, imageViewType, imageFormat, VK_FILTER_LINEAR)
593 , m_reductionCreaterInfo (getSamplerReductionCreateInfo(reductionMode))
594 , m_componentMapping (componentMapping)
595 {
596 }
597
getSamplerCreateInfo(void) const598 VkSamplerCreateInfo SamplerMinReduceFilterTest::getSamplerCreateInfo (void) const
599 {
600 VkSamplerCreateInfo samplerParams = SamplerMinFilterTest::getSamplerCreateInfo();
601
602 samplerParams.pNext = &m_reductionCreaterInfo;
603
604 return samplerParams;
605 }
606
getComponentMapping(void) const607 VkComponentMapping SamplerMinReduceFilterTest::getComponentMapping (void) const
608 {
609 return m_componentMapping;
610 }
611
612 // SamplerLodTest
613
SamplerLodTest(tcu::TestContext & testContext,const char * name,const char * description,VkImageViewType imageViewType,VkFormat imageFormat,VkSamplerMipmapMode mipmapMode,float minLod,float maxLod,float mipLodBias,float samplerLod)614 SamplerLodTest::SamplerLodTest (tcu::TestContext& testContext,
615 const char* name,
616 const char* description,
617 VkImageViewType imageViewType,
618 VkFormat imageFormat,
619 VkSamplerMipmapMode mipmapMode,
620 float minLod,
621 float maxLod,
622 float mipLodBias,
623 float samplerLod)
624 : SamplerTest (testContext, name, description, imageViewType, imageFormat, 32, samplerLod)
625 , m_mipmapMode (mipmapMode)
626 , m_minLod (minLod)
627 , m_maxLod (maxLod)
628 , m_mipLodBias (mipLodBias)
629 {
630 }
631
getSamplerCreateInfo(void) const632 VkSamplerCreateInfo SamplerLodTest::getSamplerCreateInfo (void) const
633 {
634 VkSamplerCreateInfo samplerParams = SamplerTest::getSamplerCreateInfo();
635
636 samplerParams.mipmapMode = m_mipmapMode;
637 samplerParams.minLod = m_minLod;
638 samplerParams.maxLod = m_maxLod;
639 samplerParams.mipLodBias = m_mipLodBias;
640
641 return samplerParams;
642 }
643
644
645 // SamplerAddressModesTest
646
SamplerAddressModesTest(tcu::TestContext & testContext,const char * name,const char * description,VkImageViewType imageViewType,VkFormat imageFormat,VkSamplerAddressMode addressU,VkSamplerAddressMode addressV,VkSamplerAddressMode addressW,VkBorderColor borderColor)647 SamplerAddressModesTest::SamplerAddressModesTest (tcu::TestContext& testContext,
648 const char* name,
649 const char* description,
650 VkImageViewType imageViewType,
651 VkFormat imageFormat,
652 VkSamplerAddressMode addressU,
653 VkSamplerAddressMode addressV,
654 VkSamplerAddressMode addressW,
655 VkBorderColor borderColor)
656 : SamplerTest (testContext, name, description, imageViewType, imageFormat, 8, 0.0f)
657 , m_addressU (addressU)
658 , m_addressV (addressV)
659 , m_addressW (addressW)
660 , m_borderColor (borderColor)
661 {
662 }
663
getRenderSize(VkImageViewType viewType) const664 tcu::UVec2 SamplerAddressModesTest::getRenderSize (VkImageViewType viewType) const
665 {
666 return 4u * SamplerTest::getRenderSize(viewType);
667 }
668
createVertices(void) const669 std::vector<Vertex4Tex4> SamplerAddressModesTest::createVertices (void) const
670 {
671 std::vector<Vertex4Tex4> vertices = SamplerTest::createVertices();
672
673 switch (m_imageViewType)
674 {
675 case VK_IMAGE_VIEW_TYPE_1D: case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
676 for (size_t vertexNdx = 0; vertexNdx < vertices.size(); vertexNdx++)
677 vertices[vertexNdx].texCoord.x() = (vertices[vertexNdx].texCoord.x() - 0.5f) * 4.0f;
678
679 break;
680
681 case VK_IMAGE_VIEW_TYPE_2D:
682 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
683 for (size_t vertexNdx = 0; vertexNdx < vertices.size(); vertexNdx++)
684 vertices[vertexNdx].texCoord.xy() = (vertices[vertexNdx].texCoord.swizzle(0, 1) - tcu::Vec2(0.5f)) * 4.0f;
685
686 break;
687
688 case VK_IMAGE_VIEW_TYPE_3D:
689 for (size_t vertexNdx = 0; vertexNdx < vertices.size(); vertexNdx++)
690 vertices[vertexNdx].texCoord.xyz() = (vertices[vertexNdx].texCoord.swizzle(0, 1, 2) - tcu::Vec3(0.5f)) * 4.0f;
691
692 break;
693
694 case VK_IMAGE_VIEW_TYPE_CUBE:
695 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
696 break;
697
698 default:
699 DE_ASSERT(false);
700 }
701
702 return vertices;
703 }
704
getSamplerCreateInfo(void) const705 VkSamplerCreateInfo SamplerAddressModesTest::getSamplerCreateInfo (void) const
706 {
707 VkSamplerCreateInfo samplerParams = SamplerTest::getSamplerCreateInfo();
708 samplerParams.addressModeU = m_addressU;
709 samplerParams.addressModeV = m_addressV;
710 samplerParams.addressModeW = m_addressW;
711 samplerParams.borderColor = m_borderColor;
712
713 return samplerParams;
714 }
715
716
717 // Utilities to create test nodes
718
getFormatCaseName(const VkFormat format)719 std::string getFormatCaseName (const VkFormat format)
720 {
721 const std::string fullName = getFormatName(format);
722
723 DE_ASSERT(de::beginsWith(fullName, "VK_FORMAT_"));
724
725 return de::toLower(fullName.substr(10));
726 }
727
createSamplerMagFilterTests(tcu::TestContext & testCtx,VkImageViewType imageViewType,VkFormat imageFormat)728 MovePtr<tcu::TestCaseGroup> createSamplerMagFilterTests (tcu::TestContext& testCtx, VkImageViewType imageViewType, VkFormat imageFormat)
729 {
730 MovePtr<tcu::TestCaseGroup> samplerMagFilterTests (new tcu::TestCaseGroup(testCtx, "mag_filter", "Tests for magnification filter"));
731
732 if (isCompressedFormat(imageFormat) || (!isIntFormat(imageFormat) && !isUintFormat(imageFormat)))
733 samplerMagFilterTests->addChild(new SamplerMagFilterTest(testCtx, "linear", "Magnifies image using VK_FILTER_LINEAR", imageViewType, imageFormat, VK_FILTER_LINEAR));
734 samplerMagFilterTests->addChild(new SamplerMagFilterTest(testCtx, "nearest", "Magnifies image using VK_FILTER_NEAREST", imageViewType, imageFormat, VK_FILTER_NEAREST));
735
736 return samplerMagFilterTests;
737 }
738
createSamplerMinFilterTests(tcu::TestContext & testCtx,VkImageViewType imageViewType,VkFormat imageFormat)739 MovePtr<tcu::TestCaseGroup> createSamplerMinFilterTests (tcu::TestContext& testCtx, VkImageViewType imageViewType, VkFormat imageFormat)
740 {
741 MovePtr<tcu::TestCaseGroup> samplerMinFilterTests (new tcu::TestCaseGroup(testCtx, "min_filter", "Tests for minification filter"));
742
743 if (isCompressedFormat(imageFormat) || (!isIntFormat(imageFormat) && !isUintFormat(imageFormat)))
744 samplerMinFilterTests->addChild(new SamplerMinFilterTest(testCtx, "linear", "Minifies image using VK_FILTER_LINEAR", imageViewType, imageFormat, VK_FILTER_LINEAR));
745 samplerMinFilterTests->addChild(new SamplerMinFilterTest(testCtx, "nearest", "Minifies image using VK_FILTER_NEAREST", imageViewType, imageFormat, VK_FILTER_NEAREST));
746
747 return samplerMinFilterTests;
748 }
749
750 const VkComponentMapping reduceFilterComponentMappings[] =
751 {
752 // filterMinmaxImageComponentMapping == false - compatible mapping:
753 { VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_ZERO },
754
755 // other mappings
756 { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A },
757 { VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_A },
758 { VK_COMPONENT_SWIZZLE_ONE, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R },
759 };
760
getShortComponentSwizzleName(VkComponentSwizzle componentSwizzle)761 static std::string getShortComponentSwizzleName (VkComponentSwizzle componentSwizzle)
762 {
763 const std::string fullName = getComponentSwizzleName(componentSwizzle);
764 const char* prefix = "VK_COMPONENT_SWIZZLE_";
765
766 DE_ASSERT(de::beginsWith(fullName, prefix));
767
768 return de::toLower(fullName.substr(deStrnlen(prefix, -1)));
769 }
770
getComponentMappingGroupName(const VkComponentMapping & componentMapping)771 static std::string getComponentMappingGroupName (const VkComponentMapping& componentMapping)
772 {
773 std::ostringstream name;
774
775 name << "comp_";
776
777 name << getShortComponentSwizzleName(componentMapping.r) << "_"
778 << getShortComponentSwizzleName(componentMapping.g) << "_"
779 << getShortComponentSwizzleName(componentMapping.b) << "_"
780 << getShortComponentSwizzleName(componentMapping.a);
781
782 return name.str();
783 }
784
createSamplerMagReduceFilterTests(tcu::TestContext & testCtx,VkImageViewType imageViewType,VkFormat imageFormat)785 MovePtr<tcu::TestCaseGroup> createSamplerMagReduceFilterTests (tcu::TestContext& testCtx, VkImageViewType imageViewType, VkFormat imageFormat)
786 {
787 MovePtr<tcu::TestCaseGroup> samplerMagReduceFilterTests (new tcu::TestCaseGroup(testCtx, "mag_reduce", "Tests for magnification reduce filter"));
788
789 for (size_t i = 0; i < DE_LENGTH_OF_ARRAY(reduceFilterComponentMappings); ++i)
790 {
791 const VkComponentMapping& mapping = reduceFilterComponentMappings[i];
792
793 MovePtr<tcu::TestCaseGroup> componentGroup (new tcu::TestCaseGroup(testCtx, getComponentMappingGroupName(mapping).c_str(), "Group for given view component mapping"));
794
795 if (isCompressedFormat(imageFormat) || (!isIntFormat(imageFormat) && !isUintFormat(imageFormat)))
796 {
797 componentGroup->addChild(new SamplerMagReduceFilterTest(testCtx, "average", "Magnifies image using VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT", imageViewType, imageFormat, mapping, VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT));
798 }
799 componentGroup->addChild(new SamplerMagReduceFilterTest(testCtx, "min", "Magnifies and reduces image using VK_SAMPLER_REDUCTION_MODE_MIN_EXT", imageViewType, imageFormat, mapping, VK_SAMPLER_REDUCTION_MODE_MIN_EXT));
800 componentGroup->addChild(new SamplerMagReduceFilterTest(testCtx, "max", "Magnifies and reduces image using VK_SAMPLER_REDUCTION_MODE_MAX_EXT", imageViewType, imageFormat, mapping, VK_SAMPLER_REDUCTION_MODE_MAX_EXT));
801 samplerMagReduceFilterTests->addChild(componentGroup.release());
802 }
803 return samplerMagReduceFilterTests;
804 }
805
createSamplerMinReduceFilterTests(tcu::TestContext & testCtx,VkImageViewType imageViewType,VkFormat imageFormat)806 MovePtr<tcu::TestCaseGroup> createSamplerMinReduceFilterTests (tcu::TestContext& testCtx, VkImageViewType imageViewType, VkFormat imageFormat)
807 {
808 MovePtr<tcu::TestCaseGroup> samplerMinReduceFilterTests (new tcu::TestCaseGroup(testCtx, "min_reduce", "Tests for minification reduce filter"));
809
810 for (size_t i = 0; i < DE_LENGTH_OF_ARRAY(reduceFilterComponentMappings); ++i)
811 {
812 const VkComponentMapping& mapping = reduceFilterComponentMappings[i];
813
814 MovePtr<tcu::TestCaseGroup> componentGroup (new tcu::TestCaseGroup(testCtx, getComponentMappingGroupName(mapping).c_str(), "Group for given view component mapping"));
815
816 if (isCompressedFormat(imageFormat) || (!isIntFormat(imageFormat) && !isUintFormat(imageFormat)))
817 {
818 componentGroup->addChild(new SamplerMinReduceFilterTest(testCtx, "average", "Minifies image using VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT", imageViewType, imageFormat, mapping, VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT));
819 }
820 componentGroup->addChild(new SamplerMinReduceFilterTest(testCtx, "min", "Minifies and reduces image using VK_SAMPLER_REDUCTION_MODE_MIN_EXT", imageViewType, imageFormat, mapping, VK_SAMPLER_REDUCTION_MODE_MIN_EXT));
821 componentGroup->addChild(new SamplerMinReduceFilterTest(testCtx, "max", "Minifies and reduces image using VK_SAMPLER_REDUCTION_MODE_MAX_EXT", imageViewType, imageFormat, mapping, VK_SAMPLER_REDUCTION_MODE_MAX_EXT));
822 samplerMinReduceFilterTests->addChild(componentGroup.release());
823 }
824 return samplerMinReduceFilterTests;
825 }
826
createSamplerLodTests(tcu::TestContext & testCtx,VkImageViewType imageViewType,VkFormat imageFormat,VkSamplerMipmapMode mipmapMode)827 MovePtr<tcu::TestCaseGroup> createSamplerLodTests (tcu::TestContext& testCtx, VkImageViewType imageViewType, VkFormat imageFormat, VkSamplerMipmapMode mipmapMode)
828 {
829 struct TestCaseConfig
830 {
831 const char* name;
832 const char* description;
833 float minLod;
834 float maxLod;
835 float mipLodBias;
836 float lod;
837 };
838
839 TestCaseConfig testCaseConfigs [] =
840 {
841 { "equal_min_3_max_3", "minLod = 3, maxLod = 3, mipLodBias = 0, lod = 0", 3.0f, 3.0f, 0.0f, 0.0f },
842 { "select_min_1", "minLod = 1, maxLod = 5, mipLodBias = 0, lod = 0", 1.0f, 5.0f, 0.0f, 0.0f },
843 { "select_max_4", "minLod = 0, maxLod = 4, mipLodBias = 0, lod = 5", 0.0f, 4.0f, 0.0f, 5.0f },
844 { "select_bias_2_1", "minLod = 0, maxLod = 2.1, mipLodBias = 5.0, lod = 0", 0.0f, 2.1f, 5.0f, 0.0f },
845 { "select_bias_2_5", "minLod = 0, maxLod = 5, mipLodBias = 2.5, lod = 0", 0.0f, 5.0f, 2.5f, 0.00001f },
846 { "select_bias_3_1", "minLod = 0, maxLod = 5, mipLodBias = -0.9, lod = 4.0", 0.0f, 5.0f, -0.9f, 4.0f },
847 { "select_bias_3_7", "minLod = 0, maxLod = 5, mipLodBias = 3.0, lod = 0.7", 0.0f, 5.0f, 3.0f, 0.7f },
848 };
849
850 MovePtr<tcu::TestCaseGroup> samplerLodTests (new tcu::TestCaseGroup(testCtx, "lod", "Tests for sampler LOD"));
851
852 for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testCaseConfigs); configNdx++)
853 {
854 const TestCaseConfig& config = testCaseConfigs[configNdx];
855
856 samplerLodTests->addChild(new SamplerLodTest(testCtx, config.name, config.description, imageViewType, imageFormat, mipmapMode, config.minLod, config.maxLod, config.mipLodBias, config.lod));
857 }
858
859 return samplerLodTests;
860 }
861
createSamplerMipmapTests(tcu::TestContext & testCtx,VkImageViewType imageViewType,VkFormat imageFormat)862 MovePtr<tcu::TestCaseGroup> createSamplerMipmapTests (tcu::TestContext& testCtx, VkImageViewType imageViewType, VkFormat imageFormat)
863 {
864 MovePtr<tcu::TestCaseGroup> samplerMipmapTests (new tcu::TestCaseGroup(testCtx, "mipmap", "Tests for mipmap modes"));
865
866 // Mipmap mode: nearest
867 MovePtr<tcu::TestCaseGroup> mipmapNearestTests (new tcu::TestCaseGroup(testCtx, "nearest", "Uses VK_TEX_MIPMAP_MODE_NEAREST"));
868 mipmapNearestTests->addChild(createSamplerLodTests(testCtx, imageViewType, imageFormat, VK_SAMPLER_MIPMAP_MODE_NEAREST).release());
869 samplerMipmapTests->addChild(mipmapNearestTests.release());
870
871 // Mipmap mode: linear
872 if (isCompressedFormat(imageFormat) || (!isIntFormat(imageFormat) && !isUintFormat(imageFormat)))
873 {
874 MovePtr<tcu::TestCaseGroup> mipmapLinearTests(new tcu::TestCaseGroup(testCtx, "linear", "Uses VK_TEX_MIPMAP_MODE_LINEAR"));
875 mipmapLinearTests->addChild(createSamplerLodTests(testCtx, imageViewType, imageFormat, VK_SAMPLER_MIPMAP_MODE_LINEAR).release());
876 samplerMipmapTests->addChild(mipmapLinearTests.release());
877 }
878
879 return samplerMipmapTests;
880 }
881
getAddressModesCaseName(VkSamplerAddressMode u,VkSamplerAddressMode v,VkSamplerAddressMode w,BorderColor border)882 std::string getAddressModesCaseName (VkSamplerAddressMode u, VkSamplerAddressMode v, VkSamplerAddressMode w, BorderColor border)
883 {
884 static const char* borderColorNames[BORDER_COLOR_COUNT] =
885 {
886 "opaque_black",
887 "opaque_white",
888 "transparent_black",
889 };
890
891 std::ostringstream caseName;
892
893 if (u == v && v == w)
894 {
895 const std::string fullName = getSamplerAddressModeName(u);
896 DE_ASSERT(de::beginsWith(fullName, "VK_SAMPLER_ADDRESS_"));
897
898 caseName << "all_";
899 caseName << de::toLower(fullName.substr(19));
900
901 if (u == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER)
902 {
903 caseName << "_" << borderColorNames[border];
904 }
905 }
906 else
907 {
908 const std::string fullNameU = getSamplerAddressModeName(u);
909 const std::string fullNameV = getSamplerAddressModeName(v);
910 const std::string fullNameW = getSamplerAddressModeName(w);
911
912 DE_ASSERT(de::beginsWith(fullNameU, "VK_SAMPLER_ADDRESS_"));
913 DE_ASSERT(de::beginsWith(fullNameV, "VK_SAMPLER_ADDRESS_"));
914 DE_ASSERT(de::beginsWith(fullNameW, "VK_SAMPLER_ADDRESS_"));
915
916 caseName << "uvw"
917 << "_" << de::toLower(fullNameU.substr(19))
918 << "_" << de::toLower(fullNameV.substr(19))
919 << "_" << de::toLower(fullNameW.substr(19));
920 }
921
922 return caseName.str();
923 }
924
createSamplerAddressModesTests(tcu::TestContext & testCtx,VkImageViewType imageViewType,VkFormat imageFormat)925 MovePtr<tcu::TestCaseGroup> createSamplerAddressModesTests (tcu::TestContext& testCtx, VkImageViewType imageViewType, VkFormat imageFormat)
926 {
927 struct TestCaseConfig
928 {
929 VkSamplerAddressMode u;
930 VkSamplerAddressMode v;
931 VkSamplerAddressMode w;
932 BorderColor border;
933 };
934
935 const TestCaseConfig testCaseConfigs[] =
936 {
937 // All address modes equal
938 { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, BORDER_COLOR_TRANSPARENT_BLACK },
939 { VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_REPEAT, BORDER_COLOR_TRANSPARENT_BLACK },
940 { VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, BORDER_COLOR_TRANSPARENT_BLACK },
941 { VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, BORDER_COLOR_TRANSPARENT_BLACK },
942
943 // All address modes equal using border color
944 { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, BORDER_COLOR_TRANSPARENT_BLACK },
945 { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, BORDER_COLOR_OPAQUE_BLACK },
946 { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, BORDER_COLOR_OPAQUE_WHITE },
947
948 // Pairwise combinations of address modes not covered by previous tests
949 { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_REPEAT, BORDER_COLOR_OPAQUE_WHITE},
950 { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, BORDER_COLOR_OPAQUE_WHITE },
951 { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, BORDER_COLOR_OPAQUE_WHITE },
952 { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, BORDER_COLOR_OPAQUE_WHITE },
953 { VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, BORDER_COLOR_OPAQUE_WHITE },
954 { VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, BORDER_COLOR_OPAQUE_WHITE },
955 { VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, VK_SAMPLER_ADDRESS_MODE_REPEAT, BORDER_COLOR_OPAQUE_WHITE },
956 { VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, BORDER_COLOR_OPAQUE_WHITE },
957 { VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, BORDER_COLOR_OPAQUE_WHITE },
958 { VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, BORDER_COLOR_OPAQUE_WHITE },
959 { VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, BORDER_COLOR_OPAQUE_WHITE },
960 { VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, BORDER_COLOR_OPAQUE_WHITE },
961 { VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_REPEAT, BORDER_COLOR_OPAQUE_WHITE },
962 { VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, BORDER_COLOR_OPAQUE_WHITE },
963 { VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, BORDER_COLOR_OPAQUE_WHITE },
964 { VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, BORDER_COLOR_OPAQUE_WHITE },
965 { VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, BORDER_COLOR_OPAQUE_WHITE },
966 { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, BORDER_COLOR_OPAQUE_WHITE },
967 { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_REPEAT, BORDER_COLOR_OPAQUE_WHITE },
968 { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, BORDER_COLOR_OPAQUE_WHITE },
969 { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, BORDER_COLOR_OPAQUE_WHITE },
970 { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, BORDER_COLOR_OPAQUE_WHITE },
971 };
972
973 MovePtr<tcu::TestCaseGroup> samplerAddressModesTests (new tcu::TestCaseGroup(testCtx, "address_modes", "Tests for address modes"));
974
975 for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testCaseConfigs); configNdx++)
976 {
977 const TestCaseConfig& config = testCaseConfigs[configNdx];
978
979 samplerAddressModesTests->addChild(new SamplerAddressModesTest(testCtx,
980 getAddressModesCaseName(config.u, config.v, config.w, config.border).c_str(),
981 "",
982 imageViewType,
983 imageFormat,
984 config.u, config.v, config.w,
985 getFormatBorderColor(config.border, imageFormat)));
986 }
987
988 return samplerAddressModesTests;
989 }
990
991 } // anonymous
992
createSamplerTests(tcu::TestContext & testCtx)993 tcu::TestCaseGroup* createSamplerTests (tcu::TestContext& testCtx)
994 {
995 const struct
996 {
997 VkImageViewType type;
998 const char* name;
999 }
1000 imageViewTypes[] =
1001 {
1002 { VK_IMAGE_VIEW_TYPE_1D, "1d" },
1003 { VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array" },
1004 { VK_IMAGE_VIEW_TYPE_2D, "2d" },
1005 { VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array" },
1006 { VK_IMAGE_VIEW_TYPE_3D, "3d" },
1007 { VK_IMAGE_VIEW_TYPE_CUBE, "cube" },
1008 { VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array" }
1009 };
1010
1011 const VkFormat formats[] =
1012 {
1013 // Packed formats
1014 VK_FORMAT_R4G4_UNORM_PACK8,
1015 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
1016 VK_FORMAT_R5G6B5_UNORM_PACK16,
1017 VK_FORMAT_R5G5B5A1_UNORM_PACK16,
1018 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
1019 VK_FORMAT_A2R10G10B10_UINT_PACK32,
1020 VK_FORMAT_B10G11R11_UFLOAT_PACK32,
1021 VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
1022 VK_FORMAT_B4G4R4A4_UNORM_PACK16,
1023 VK_FORMAT_B5G5R5A1_UNORM_PACK16,
1024
1025 // Pairwise combinations of 8-bit channel formats, UNORM/SNORM/SINT/UINT/SRGB type x 1-to-4 channels x RGBA/BGRA order
1026 VK_FORMAT_R8_SRGB,
1027 VK_FORMAT_R8G8B8_UINT,
1028 VK_FORMAT_B8G8R8A8_SINT,
1029 VK_FORMAT_R8G8_UNORM,
1030 VK_FORMAT_B8G8R8_SNORM,
1031 VK_FORMAT_R8G8B8A8_SNORM,
1032 VK_FORMAT_R8G8_UINT,
1033 VK_FORMAT_R8_SINT,
1034 VK_FORMAT_R8G8B8A8_SRGB,
1035 VK_FORMAT_R8G8B8A8_UNORM,
1036 VK_FORMAT_B8G8R8A8_UNORM,
1037 VK_FORMAT_B8G8R8_SRGB,
1038 VK_FORMAT_R8G8_SRGB,
1039 VK_FORMAT_R8_UINT,
1040 VK_FORMAT_R8G8B8A8_UINT,
1041 VK_FORMAT_R8G8_SINT,
1042 VK_FORMAT_R8_SNORM,
1043 VK_FORMAT_B8G8R8_SINT,
1044 VK_FORMAT_R8G8_SNORM,
1045 VK_FORMAT_B8G8R8_UNORM,
1046 VK_FORMAT_R8_UNORM,
1047
1048 // Pairwise combinations of 16/32-bit channel formats x SINT/UINT/SFLOAT type x 1-to-4 channels
1049 VK_FORMAT_R32G32_SFLOAT,
1050 VK_FORMAT_R32G32B32_UINT,
1051 VK_FORMAT_R16G16B16A16_SFLOAT,
1052 VK_FORMAT_R16G16_UINT,
1053 VK_FORMAT_R32G32B32A32_SINT,
1054 VK_FORMAT_R16G16B16_SINT,
1055 VK_FORMAT_R16_SFLOAT,
1056 VK_FORMAT_R32_SINT,
1057 VK_FORMAT_R32_UINT,
1058 VK_FORMAT_R16G16B16_SFLOAT,
1059 VK_FORMAT_R16G16_SINT,
1060
1061 // More 16/32-bit formats required for testing VK_EXT_sampler_filter_minmax
1062 VK_FORMAT_R16_SNORM,
1063 VK_FORMAT_R32_SFLOAT,
1064
1065 // Scaled formats
1066 VK_FORMAT_R8G8B8A8_SSCALED,
1067 VK_FORMAT_A2R10G10B10_USCALED_PACK32,
1068
1069 // Compressed formats
1070 VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
1071 VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
1072 VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
1073 VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
1074 VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
1075 VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
1076 VK_FORMAT_EAC_R11_UNORM_BLOCK,
1077 VK_FORMAT_EAC_R11_SNORM_BLOCK,
1078 VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
1079 VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
1080 VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
1081 VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
1082 VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
1083 VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
1084 VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
1085 VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
1086 VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
1087 VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
1088 VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
1089 VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
1090
1091 // Depth formats required for testing VK_EXT_sampler_filter_minmax
1092 VK_FORMAT_D16_UNORM,
1093 VK_FORMAT_X8_D24_UNORM_PACK32,
1094 VK_FORMAT_D32_SFLOAT,
1095 VK_FORMAT_D16_UNORM_S8_UINT,
1096 VK_FORMAT_D24_UNORM_S8_UINT,
1097 VK_FORMAT_D32_SFLOAT_S8_UINT,
1098 };
1099
1100 de::MovePtr<tcu::TestCaseGroup> samplerTests (new tcu::TestCaseGroup(testCtx, "sampler", "Sampler tests"));
1101 de::MovePtr<tcu::TestCaseGroup> viewTypeTests (new tcu::TestCaseGroup(testCtx, "view_type", ""));
1102
1103 for (int viewTypeNdx = 0; viewTypeNdx < DE_LENGTH_OF_ARRAY(imageViewTypes); viewTypeNdx++)
1104 {
1105 const VkImageViewType viewType = imageViewTypes[viewTypeNdx].type;
1106 de::MovePtr<tcu::TestCaseGroup> viewTypeGroup (new tcu::TestCaseGroup(testCtx, imageViewTypes[viewTypeNdx].name, (std::string("Uses a ") + imageViewTypes[viewTypeNdx].name + " view").c_str()));
1107 de::MovePtr<tcu::TestCaseGroup> formatTests (new tcu::TestCaseGroup(testCtx, "format", "Tests samplable formats"));
1108
1109 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
1110 {
1111 const VkFormat format = formats[formatNdx];
1112 const bool isCompressed = isCompressedFormat(format);
1113
1114 if (isCompressed)
1115 {
1116 // Do not use compressed formats with 1D and 1D array textures.
1117 if (viewType == VK_IMAGE_VIEW_TYPE_1D || viewType == VK_IMAGE_VIEW_TYPE_1D_ARRAY)
1118 break;
1119 }
1120
1121 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx,
1122 getFormatCaseName(format).c_str(),
1123 (std::string("Samples a texture of format ") + getFormatName(format)).c_str()));
1124
1125 if (!isCompressed)
1126 {
1127 // Do not include minFilter tests with compressed formats.
1128 // Randomly generated compressed textures are too noisy and will derive in false positives.
1129 de::MovePtr<tcu::TestCaseGroup> minFilterTests = createSamplerMinFilterTests(testCtx, viewType, format);
1130 de::MovePtr<tcu::TestCaseGroup> minReduceFilterTests = createSamplerMinReduceFilterTests(testCtx, viewType, format);
1131 formatGroup->addChild(minFilterTests.release());
1132 formatGroup->addChild(minReduceFilterTests.release());
1133 }
1134
1135 de::MovePtr<tcu::TestCaseGroup> magFilterTests = createSamplerMagFilterTests(testCtx, viewType, format);
1136 de::MovePtr<tcu::TestCaseGroup> magReduceFilterTests = createSamplerMagReduceFilterTests(testCtx, viewType, format);
1137 de::MovePtr<tcu::TestCaseGroup> mipmapTests = createSamplerMipmapTests(testCtx, viewType, format);
1138
1139 formatGroup->addChild(magFilterTests.release());
1140 formatGroup->addChild(magReduceFilterTests.release());
1141 formatGroup->addChild(mipmapTests.release());
1142
1143 if (viewType != VK_IMAGE_VIEW_TYPE_CUBE && viewType != VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
1144 {
1145 de::MovePtr<tcu::TestCaseGroup> addressModesTests = createSamplerAddressModesTests(testCtx, viewType, format);
1146 formatGroup->addChild(addressModesTests.release());
1147 }
1148
1149 formatTests->addChild(formatGroup.release());
1150 }
1151
1152 viewTypeGroup->addChild(formatTests.release());
1153 viewTypeTests->addChild(viewTypeGroup.release());
1154 }
1155
1156 samplerTests->addChild(viewTypeTests.release());
1157
1158 return samplerTests.release();
1159 }
1160
1161 } // pipeline
1162 } // vkt
1163