1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Imagination Technologies Ltd.
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 * \brief Sampler Tests
23 *//*--------------------------------------------------------------------*/
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"
52 class SamplerTest : public vkt::TestCase
55 SamplerTest (tcu::TestContext& testContext,
57 const char* description,
58 VkImageViewType imageViewType,
62 virtual ~SamplerTest (void) {}
64 virtual void initPrograms (SourceCollections& sourceCollections) const;
65 virtual TestInstance* createInstance (Context& context) const;
66 virtual tcu::UVec2 getRenderSize (VkImageViewType viewType) const;
67 virtual std::vector<Vertex4Tex4> createVertices (void) const;
68 virtual VkSamplerCreateInfo getSamplerCreateInfo (void) const;
70 static std::string getGlslSamplerType (const tcu::TextureFormat& format, VkImageViewType type);
71 static tcu::IVec3 getImageSize (VkImageViewType viewType, int size);
72 static int getArraySize (VkImageViewType viewType);
75 VkImageViewType m_imageViewType;
76 VkFormat m_imageFormat;
78 VkImageViewCreateInfo m_imageViewParams;
79 VkSamplerCreateInfo m_samplerParams;
83 class SamplerMagFilterTest : public SamplerTest
86 SamplerMagFilterTest (tcu::TestContext& testContext,
88 const char* description,
89 VkImageViewType imageViewType,
92 virtual ~SamplerMagFilterTest (void) {}
93 virtual VkSamplerCreateInfo getSamplerCreateInfo (void) const;
99 class SamplerMinFilterTest : public SamplerTest
102 SamplerMinFilterTest (tcu::TestContext& testContext,
104 const char* description,
105 VkImageViewType imageViewType,
106 VkFormat imageFormat,
108 virtual ~SamplerMinFilterTest (void) {}
109 virtual VkSamplerCreateInfo getSamplerCreateInfo (void) const;
112 VkFilter m_minFilter;
115 class SamplerLodTest : public SamplerTest
118 SamplerLodTest (tcu::TestContext& testContext,
120 const char* description,
121 VkImageViewType imageViewType,
122 VkFormat imageFormat,
123 VkSamplerMipmapMode mipmapMode,
128 virtual ~SamplerLodTest (void) {}
129 virtual VkSamplerCreateInfo getSamplerCreateInfo (void) const;
132 VkSamplerMipmapMode m_mipmapMode;
138 class SamplerAddressModesTest : public SamplerTest
141 SamplerAddressModesTest (tcu::TestContext& testContext,
143 const char* description,
144 VkImageViewType imageViewType,
145 VkFormat imageFormat,
146 VkSamplerAddressMode addressU,
147 VkSamplerAddressMode addressV,
148 VkSamplerAddressMode addressW,
149 VkBorderColor borderColor);
150 virtual ~SamplerAddressModesTest (void) {}
151 virtual tcu::UVec2 getRenderSize (VkImageViewType viewType) const;
152 virtual std::vector<Vertex4Tex4> createVertices (void) const;
153 virtual VkSamplerCreateInfo getSamplerCreateInfo (void) const;
156 VkSamplerAddressMode m_addressU;
157 VkSamplerAddressMode m_addressV;
158 VkSamplerAddressMode m_addressW;
159 VkBorderColor m_borderColor;
165 SamplerTest::SamplerTest (tcu::TestContext& testContext,
167 const char* description,
168 VkImageViewType imageViewType,
169 VkFormat imageFormat,
172 : vkt::TestCase (testContext, name, description)
173 , m_imageViewType (imageViewType)
174 , m_imageFormat (imageFormat)
175 , m_imageSize (imageSize)
176 , m_samplerLod (samplerLod)
180 void SamplerTest::initPrograms (SourceCollections& sourceCollections) const
182 std::ostringstream vertexSrc;
183 std::ostringstream fragmentSrc;
184 const char* texCoordSwizzle = DE_NULL;
185 tcu::TextureFormat format = (isCompressedFormat(m_imageFormat)) ? tcu::getUncompressedFormat(mapVkCompressedFormat(m_imageFormat))
186 : mapVkFormat(m_imageFormat);
187 tcu::Vec4 lookupScale;
188 tcu::Vec4 lookupBias;
190 getLookupScaleBias(m_imageFormat, lookupScale, lookupBias);
192 switch (m_imageViewType)
194 case VK_IMAGE_VIEW_TYPE_1D:
195 texCoordSwizzle = "x";
197 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
198 case VK_IMAGE_VIEW_TYPE_2D:
199 texCoordSwizzle = "xy";
201 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
202 case VK_IMAGE_VIEW_TYPE_3D:
203 case VK_IMAGE_VIEW_TYPE_CUBE:
204 texCoordSwizzle = "xyz";
206 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
207 texCoordSwizzle = "xyzw";
214 vertexSrc << "#version 440\n"
215 << "layout(location = 0) in vec4 position;\n"
216 << "layout(location = 1) in vec4 texCoords;\n"
217 << "layout(location = 0) out highp vec4 vtxTexCoords;\n"
218 << "out gl_PerVertex {\n"
219 << " vec4 gl_Position;\n"
221 << "void main (void)\n"
223 << " gl_Position = position;\n"
224 << " vtxTexCoords = texCoords;\n"
227 fragmentSrc << "#version 440\n"
228 << "layout(set = 0, binding = 0) uniform highp " << getGlslSamplerType(format, m_imageViewType) << " texSampler;\n"
229 << "layout(location = 0) in highp vec4 vtxTexCoords;\n"
230 << "layout(location = 0) out highp vec4 fragColor;\n"
231 << "void main (void)\n"
235 if (m_samplerLod > 0.0f)
236 fragmentSrc << "textureLod(texSampler, vtxTexCoords." << texCoordSwizzle << ", " << std::fixed << m_samplerLod << ")";
238 fragmentSrc << "texture(texSampler, vtxTexCoords." << texCoordSwizzle << ")" << std::fixed;
240 fragmentSrc << " * vec4" << std::scientific << lookupScale << " + vec4" << lookupBias << ";\n"
243 sourceCollections.glslSources.add("tex_vert") << glu::VertexSource(vertexSrc.str());
244 sourceCollections.glslSources.add("tex_frag") << glu::FragmentSource(fragmentSrc.str());
247 TestInstance* SamplerTest::createInstance (Context& context) const
249 const tcu::UVec2 renderSize = getRenderSize(m_imageViewType);
250 const std::vector<Vertex4Tex4> vertices = createVertices();
251 const VkSamplerCreateInfo samplerParams = getSamplerCreateInfo();
252 const VkComponentMapping componentMapping = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
253 const VkImageSubresourceRange subresourceRange =
255 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
256 0u, // deUint32 baseMipLevel;
257 (deUint32)deLog2Floor32(m_imageSize) + 1, // deUint32 mipLevels;
258 0u, // deUint32 baseArrayLayer;
259 (deUint32)SamplerTest::getArraySize(m_imageViewType) // deUint32 arraySize;
264 return new ImageSamplingInstance(context, renderSize, m_imageViewType, m_imageFormat,
265 getImageSize(m_imageViewType, m_imageSize),
266 getArraySize(m_imageViewType),
267 componentMapping, subresourceRange,
268 samplerParams, m_samplerLod,vertices);
271 tcu::UVec2 SamplerTest::getRenderSize (VkImageViewType viewType) const
273 if (viewType == VK_IMAGE_VIEW_TYPE_1D || viewType == VK_IMAGE_VIEW_TYPE_2D)
275 return tcu::UVec2(16u, 16u);
279 return tcu::UVec2(16u * 3u, 16u * 2u);
283 std::vector<Vertex4Tex4> SamplerTest::createVertices (void) const
285 std::vector<Vertex4Tex4> vertices = createTestQuadMosaic(m_imageViewType);
286 // Adjust texture coordinate to avoid doing NEAREST filtering exactly on texel boundaries.
287 // TODO: Would be nice to base this on number of texels and subtexel precision. But this
289 for (unsigned int i = 0; i < vertices.size(); ++i) {
290 vertices[i].texCoord += tcu::Vec4(0.002f, 0.002f, 0.002f, 0.0f);
295 VkSamplerCreateInfo SamplerTest::getSamplerCreateInfo (void) const
297 const VkSamplerCreateInfo defaultSamplerParams =
299 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType;
300 DE_NULL, // const void* pNext;
301 0u, // VkSamplerCreateFlags flags;
302 VK_FILTER_NEAREST, // VkFilter magFilter;
303 VK_FILTER_NEAREST, // VkFilter minFilter;
304 VK_SAMPLER_MIPMAP_MODE_NEAREST, // VkSamplerMipmapMode mipmapMode;
305 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeU;
306 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeV;
307 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeW;
308 0.0f, // float mipLodBias;
309 VK_FALSE, // VkBool32 anisotropyEnable;
310 1.0f, // float maxAnisotropy;
311 false, // VkBool32 compareEnable;
312 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp;
313 0.0f, // float minLod;
314 0.25f, // float maxLod;
315 getFormatBorderColor(BORDER_COLOR_TRANSPARENT_BLACK, m_imageFormat), // VkBorderColor borderColor;
316 false // VkBool32 unnormalizedCoordinates;
319 return defaultSamplerParams;
322 std::string SamplerTest::getGlslSamplerType (const tcu::TextureFormat& format, VkImageViewType type)
324 std::ostringstream samplerType;
326 if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
328 else if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
333 case VK_IMAGE_VIEW_TYPE_1D:
334 samplerType << "sampler1D";
337 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
338 samplerType << "sampler1DArray";
341 case VK_IMAGE_VIEW_TYPE_2D:
342 samplerType << "sampler2D";
345 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
346 samplerType << "sampler2DArray";
349 case VK_IMAGE_VIEW_TYPE_3D:
350 samplerType << "sampler3D";
353 case VK_IMAGE_VIEW_TYPE_CUBE:
354 samplerType << "samplerCube";
357 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
358 samplerType << "samplerCubeArray";
362 DE_FATAL("Unknown image view type");
366 return samplerType.str();
369 tcu::IVec3 SamplerTest::getImageSize (VkImageViewType viewType, int size)
373 case VK_IMAGE_VIEW_TYPE_1D:
374 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
375 return tcu::IVec3(size, 1, 1);
377 case VK_IMAGE_VIEW_TYPE_3D:
378 return tcu::IVec3(size, size, 4);
384 return tcu::IVec3(size, size, 1);
387 int SamplerTest::getArraySize (VkImageViewType viewType)
391 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
392 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
393 case VK_IMAGE_VIEW_TYPE_CUBE:
396 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
407 // SamplerMagFilterTest
409 SamplerMagFilterTest::SamplerMagFilterTest (tcu::TestContext& testContext,
411 const char* description,
412 VkImageViewType imageViewType,
413 VkFormat imageFormat,
415 : SamplerTest (testContext, name, description, imageViewType, imageFormat, 8, 0.0f)
416 , m_magFilter (magFilter)
420 VkSamplerCreateInfo SamplerMagFilterTest::getSamplerCreateInfo (void) const
422 VkSamplerCreateInfo samplerParams = SamplerTest::getSamplerCreateInfo();
423 samplerParams.magFilter = m_magFilter;
425 return samplerParams;
429 // SamplerMinFilterTest
431 SamplerMinFilterTest::SamplerMinFilterTest (tcu::TestContext& testContext,
433 const char* description,
434 VkImageViewType imageViewType,
435 VkFormat imageFormat,
437 : SamplerTest (testContext, name, description, imageViewType, imageFormat, 32, 0.0f)
438 , m_minFilter (minFilter)
442 VkSamplerCreateInfo SamplerMinFilterTest::getSamplerCreateInfo (void) const
444 VkSamplerCreateInfo samplerParams = SamplerTest::getSamplerCreateInfo();
445 samplerParams.minFilter = m_minFilter;
446 // set minLod to epsilon, to force use of the minFilter
447 samplerParams.minLod = 0.01f;
449 return samplerParams;
455 SamplerLodTest::SamplerLodTest (tcu::TestContext& testContext,
457 const char* description,
458 VkImageViewType imageViewType,
459 VkFormat imageFormat,
460 VkSamplerMipmapMode mipmapMode,
465 : SamplerTest (testContext, name, description, imageViewType, imageFormat, 32, samplerLod)
466 , m_mipmapMode (mipmapMode)
469 , m_mipLodBias (mipLodBias)
473 VkSamplerCreateInfo SamplerLodTest::getSamplerCreateInfo (void) const
475 VkSamplerCreateInfo samplerParams = SamplerTest::getSamplerCreateInfo();
477 samplerParams.mipmapMode = m_mipmapMode;
478 samplerParams.minLod = m_minLod;
479 samplerParams.maxLod = m_maxLod;
480 samplerParams.mipLodBias = m_mipLodBias;
482 return samplerParams;
486 // SamplerAddressModesTest
488 SamplerAddressModesTest::SamplerAddressModesTest (tcu::TestContext& testContext,
490 const char* description,
491 VkImageViewType imageViewType,
492 VkFormat imageFormat,
493 VkSamplerAddressMode addressU,
494 VkSamplerAddressMode addressV,
495 VkSamplerAddressMode addressW,
496 VkBorderColor borderColor)
497 : SamplerTest (testContext, name, description, imageViewType, imageFormat, 8, 0.0f)
498 , m_addressU (addressU)
499 , m_addressV (addressV)
500 , m_addressW (addressW)
501 , m_borderColor (borderColor)
505 tcu::UVec2 SamplerAddressModesTest::getRenderSize (VkImageViewType viewType) const
507 return 4u * SamplerTest::getRenderSize(viewType);
510 std::vector<Vertex4Tex4> SamplerAddressModesTest::createVertices (void) const
512 std::vector<Vertex4Tex4> vertices = SamplerTest::createVertices();
514 switch (m_imageViewType)
516 case VK_IMAGE_VIEW_TYPE_1D: case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
517 for (size_t vertexNdx = 0; vertexNdx < vertices.size(); vertexNdx++)
518 vertices[vertexNdx].texCoord.x() = (vertices[vertexNdx].texCoord.x() - 0.5f) * 4.0f;
522 case VK_IMAGE_VIEW_TYPE_2D:
523 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
524 for (size_t vertexNdx = 0; vertexNdx < vertices.size(); vertexNdx++)
525 vertices[vertexNdx].texCoord.xy() = (vertices[vertexNdx].texCoord.swizzle(0, 1) - tcu::Vec2(0.5f)) * 4.0f;
529 case VK_IMAGE_VIEW_TYPE_3D:
530 for (size_t vertexNdx = 0; vertexNdx < vertices.size(); vertexNdx++)
531 vertices[vertexNdx].texCoord.xyz() = (vertices[vertexNdx].texCoord.swizzle(0, 1, 2) - tcu::Vec3(0.5f)) * 4.0f;
535 case VK_IMAGE_VIEW_TYPE_CUBE:
536 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
546 VkSamplerCreateInfo SamplerAddressModesTest::getSamplerCreateInfo (void) const
548 VkSamplerCreateInfo samplerParams = SamplerTest::getSamplerCreateInfo();
549 samplerParams.addressModeU = m_addressU;
550 samplerParams.addressModeV = m_addressV;
551 samplerParams.addressModeW = m_addressW;
552 samplerParams.borderColor = m_borderColor;
554 return samplerParams;
558 // Utilities to create test nodes
560 std::string getFormatCaseName (const VkFormat format)
562 const std::string fullName = getFormatName(format);
564 DE_ASSERT(de::beginsWith(fullName, "VK_FORMAT_"));
566 return de::toLower(fullName.substr(10));
569 MovePtr<tcu::TestCaseGroup> createSamplerMagFilterTests (tcu::TestContext& testCtx, VkImageViewType imageViewType, VkFormat imageFormat)
571 MovePtr<tcu::TestCaseGroup> samplerMagFilterTests (new tcu::TestCaseGroup(testCtx, "mag_filter", "Tests for magnification filter"));
573 if (isCompressedFormat(imageFormat) || (!isIntFormat(imageFormat) && !isUintFormat(imageFormat)))
574 samplerMagFilterTests->addChild(new SamplerMagFilterTest(testCtx, "linear", "Magnifies image using VK_TEX_FILTER_LINEAR", imageViewType, imageFormat, VK_FILTER_LINEAR));
575 samplerMagFilterTests->addChild(new SamplerMagFilterTest(testCtx, "nearest", "Magnifies image using VK_TEX_FILTER_NEAREST", imageViewType, imageFormat, VK_FILTER_NEAREST));
577 return samplerMagFilterTests;
580 MovePtr<tcu::TestCaseGroup> createSamplerMinFilterTests (tcu::TestContext& testCtx, VkImageViewType imageViewType, VkFormat imageFormat)
582 MovePtr<tcu::TestCaseGroup> samplerMinFilterTests (new tcu::TestCaseGroup(testCtx, "min_filter", "Tests for minification filter"));
584 if (isCompressedFormat(imageFormat) || (!isIntFormat(imageFormat) && !isUintFormat(imageFormat)))
585 samplerMinFilterTests->addChild(new SamplerMinFilterTest(testCtx, "linear", "Minifies image using VK_TEX_FILTER_LINEAR", imageViewType, imageFormat, VK_FILTER_LINEAR));
586 samplerMinFilterTests->addChild(new SamplerMinFilterTest(testCtx, "nearest", "Minifies image using VK_TEX_FILTER_NEAREST", imageViewType, imageFormat, VK_FILTER_NEAREST));
588 return samplerMinFilterTests;
591 MovePtr<tcu::TestCaseGroup> createSamplerLodTests (tcu::TestContext& testCtx, VkImageViewType imageViewType, VkFormat imageFormat, VkSamplerMipmapMode mipmapMode)
593 struct TestCaseConfig
596 const char* description;
603 TestCaseConfig testCaseConfigs [] =
605 { "equal_min_3_max_3", "minLod = 3, maxLod = 3, mipLodBias = 0, lod = 0", 3.0f, 3.0f, 0.0f, 0.0f },
606 { "select_min_1", "minLod = 1, maxLod = 5, mipLodBias = 0, lod = 0", 1.0f, 5.0f, 0.0f, 0.0f },
607 { "select_max_4", "minLod = 0, maxLod = 4, mipLodBias = 0, lod = 5", 0.0f, 4.0f, 0.0f, 5.0f },
608 { "select_bias_2_1", "minLod = 0, maxLod = 2.1, mipLodBias = 5.0, lod = 0", 0.0f, 2.1f, 5.0f, 0.0f },
609 { "select_bias_2_5", "minLod = 0, maxLod = 5, mipLodBias = 2.5, lod = 0", 0.0f, 5.0f, 2.5f, 0.00001f },
610 { "select_bias_3_1", "minLod = 0, maxLod = 5, mipLodBias = -0.9, lod = 4.0", 0.0f, 5.0f, -0.9f, 4.0f },
611 { "select_bias_3_7", "minLod = 0, maxLod = 5, mipLodBias = 3.0, lod = 0.7", 0.0f, 5.0f, 3.0f, 0.7f },
614 MovePtr<tcu::TestCaseGroup> samplerLodTests (new tcu::TestCaseGroup(testCtx, "lod", "Tests for sampler LOD"));
616 for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testCaseConfigs); configNdx++)
618 const TestCaseConfig& config = testCaseConfigs[configNdx];
620 samplerLodTests->addChild(new SamplerLodTest(testCtx, config.name, config.description, imageViewType, imageFormat, mipmapMode, config.minLod, config.maxLod, config.mipLodBias, config.lod));
623 return samplerLodTests;
626 MovePtr<tcu::TestCaseGroup> createSamplerMipmapTests (tcu::TestContext& testCtx, VkImageViewType imageViewType, VkFormat imageFormat)
628 MovePtr<tcu::TestCaseGroup> samplerMipmapTests (new tcu::TestCaseGroup(testCtx, "mipmap", "Tests for mipmap modes"));
630 // Mipmap mode: nearest
631 MovePtr<tcu::TestCaseGroup> mipmapNearestTests (new tcu::TestCaseGroup(testCtx, "nearest", "Uses VK_TEX_MIPMAP_MODE_NEAREST"));
632 mipmapNearestTests->addChild(createSamplerLodTests(testCtx, imageViewType, imageFormat, VK_SAMPLER_MIPMAP_MODE_NEAREST).release());
633 samplerMipmapTests->addChild(mipmapNearestTests.release());
635 // Mipmap mode: linear
636 if (isCompressedFormat(imageFormat) || (!isIntFormat(imageFormat) && !isUintFormat(imageFormat)))
638 MovePtr<tcu::TestCaseGroup> mipmapLinearTests(new tcu::TestCaseGroup(testCtx, "linear", "Uses VK_TEX_MIPMAP_MODE_LINEAR"));
639 mipmapLinearTests->addChild(createSamplerLodTests(testCtx, imageViewType, imageFormat, VK_SAMPLER_MIPMAP_MODE_LINEAR).release());
640 samplerMipmapTests->addChild(mipmapLinearTests.release());
643 return samplerMipmapTests;
646 std::string getAddressModesCaseName (VkSamplerAddressMode u, VkSamplerAddressMode v, VkSamplerAddressMode w, BorderColor border)
648 static const char* borderColorNames[BORDER_COLOR_COUNT] =
655 std::ostringstream caseName;
657 if (u == v && v == w)
659 const std::string fullName = getSamplerAddressModeName(u);
660 DE_ASSERT(de::beginsWith(fullName, "VK_SAMPLER_ADDRESS_"));
663 caseName << de::toLower(fullName.substr(19));
665 if (u == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER)
667 caseName << "_" << borderColorNames[border];
672 const std::string fullNameU = getSamplerAddressModeName(u);
673 const std::string fullNameV = getSamplerAddressModeName(v);
674 const std::string fullNameW = getSamplerAddressModeName(w);
676 DE_ASSERT(de::beginsWith(fullNameU, "VK_SAMPLER_ADDRESS_"));
677 DE_ASSERT(de::beginsWith(fullNameV, "VK_SAMPLER_ADDRESS_"));
678 DE_ASSERT(de::beginsWith(fullNameW, "VK_SAMPLER_ADDRESS_"));
681 << "_" << de::toLower(fullNameU.substr(19))
682 << "_" << de::toLower(fullNameV.substr(19))
683 << "_" << de::toLower(fullNameW.substr(19));
686 return caseName.str();
689 MovePtr<tcu::TestCaseGroup> createSamplerAddressModesTests (tcu::TestContext& testCtx, VkImageViewType imageViewType, VkFormat imageFormat)
691 struct TestCaseConfig
693 VkSamplerAddressMode u;
694 VkSamplerAddressMode v;
695 VkSamplerAddressMode w;
699 const TestCaseConfig testCaseConfigs[] =
701 // All address modes equal
702 { 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 },
703 { VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_REPEAT, BORDER_COLOR_TRANSPARENT_BLACK },
704 { VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, BORDER_COLOR_TRANSPARENT_BLACK },
705 { 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 },
707 // All address modes equal using border color
708 { 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 },
709 { 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 },
710 { 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 },
712 // Pairwise combinations of address modes not covered by previous tests
713 { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_REPEAT, BORDER_COLOR_OPAQUE_WHITE},
714 { 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 },
715 { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, BORDER_COLOR_OPAQUE_WHITE },
716 { 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 },
717 { 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 },
718 { 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 },
719 { VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, VK_SAMPLER_ADDRESS_MODE_REPEAT, BORDER_COLOR_OPAQUE_WHITE },
720 { 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 },
721 { VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, BORDER_COLOR_OPAQUE_WHITE },
722 { 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 },
723 { 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 },
724 { VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, BORDER_COLOR_OPAQUE_WHITE },
725 { VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_REPEAT, BORDER_COLOR_OPAQUE_WHITE },
726 { VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, BORDER_COLOR_OPAQUE_WHITE },
727 { VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, BORDER_COLOR_OPAQUE_WHITE },
728 { VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, BORDER_COLOR_OPAQUE_WHITE },
729 { 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 },
730 { 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 },
731 { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_REPEAT, BORDER_COLOR_OPAQUE_WHITE },
732 { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, BORDER_COLOR_OPAQUE_WHITE },
733 { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, BORDER_COLOR_OPAQUE_WHITE },
734 { 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 },
737 MovePtr<tcu::TestCaseGroup> samplerAddressModesTests (new tcu::TestCaseGroup(testCtx, "address_modes", "Tests for address modes"));
739 for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testCaseConfigs); configNdx++)
741 const TestCaseConfig& config = testCaseConfigs[configNdx];
743 samplerAddressModesTests->addChild(new SamplerAddressModesTest(testCtx,
744 getAddressModesCaseName(config.u, config.v, config.w, config.border).c_str(),
748 config.u, config.v, config.w,
749 getFormatBorderColor(config.border, imageFormat)));
752 return samplerAddressModesTests;
757 tcu::TestCaseGroup* createSamplerTests (tcu::TestContext& testCtx)
761 VkImageViewType type;
766 { VK_IMAGE_VIEW_TYPE_1D, "1d" },
767 { VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array" },
768 { VK_IMAGE_VIEW_TYPE_2D, "2d" },
769 { VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array" },
770 { VK_IMAGE_VIEW_TYPE_3D, "3d" },
771 { VK_IMAGE_VIEW_TYPE_CUBE, "cube" },
772 { VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array" }
775 const VkFormat formats[] =
778 VK_FORMAT_R4G4_UNORM_PACK8,
779 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
780 VK_FORMAT_R5G6B5_UNORM_PACK16,
781 VK_FORMAT_R5G5B5A1_UNORM_PACK16,
782 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
783 VK_FORMAT_A2R10G10B10_UINT_PACK32,
784 VK_FORMAT_B10G11R11_UFLOAT_PACK32,
785 VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
786 VK_FORMAT_B4G4R4A4_UNORM_PACK16,
787 VK_FORMAT_B5G5R5A1_UNORM_PACK16,
789 // Pairwise combinations of 8-bit channel formats, UNORM/SNORM/SINT/UINT/SRGB type x 1-to-4 channels x RGBA/BGRA order
791 VK_FORMAT_R8G8B8_UINT,
792 VK_FORMAT_B8G8R8A8_SINT,
793 VK_FORMAT_R8G8_UNORM,
794 VK_FORMAT_B8G8R8_SNORM,
795 VK_FORMAT_R8G8B8A8_SNORM,
798 VK_FORMAT_R8G8B8A8_SRGB,
799 VK_FORMAT_R8G8B8A8_UNORM,
800 VK_FORMAT_B8G8R8A8_UNORM,
801 VK_FORMAT_B8G8R8_SRGB,
804 VK_FORMAT_R8G8B8A8_UINT,
807 VK_FORMAT_B8G8R8_SINT,
808 VK_FORMAT_R8G8_SNORM,
809 VK_FORMAT_B8G8R8_UNORM,
812 // Pairwise combinations of 16/32-bit channel formats x SINT/UINT/SFLOAT type x 1-to-4 channels
813 VK_FORMAT_R32G32_SFLOAT,
814 VK_FORMAT_R32G32B32_UINT,
815 VK_FORMAT_R16G16B16A16_SFLOAT,
816 VK_FORMAT_R16G16_UINT,
817 VK_FORMAT_R32G32B32A32_SINT,
818 VK_FORMAT_R16G16B16_SINT,
819 VK_FORMAT_R16_SFLOAT,
822 VK_FORMAT_R16G16B16_SFLOAT,
823 VK_FORMAT_R16G16_SINT,
826 VK_FORMAT_R8G8B8A8_SSCALED,
827 VK_FORMAT_A2R10G10B10_USCALED_PACK32,
829 // Compressed formats
830 VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
831 VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
832 VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
833 VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
834 VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
835 VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
836 VK_FORMAT_EAC_R11_UNORM_BLOCK,
837 VK_FORMAT_EAC_R11_SNORM_BLOCK,
838 VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
839 VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
840 VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
841 VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
842 VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
843 VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
844 VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
845 VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
846 VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
847 VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
848 VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
849 VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
852 de::MovePtr<tcu::TestCaseGroup> samplerTests (new tcu::TestCaseGroup(testCtx, "sampler", "Sampler tests"));
853 de::MovePtr<tcu::TestCaseGroup> viewTypeTests (new tcu::TestCaseGroup(testCtx, "view_type", ""));
855 for (int viewTypeNdx = 0; viewTypeNdx < DE_LENGTH_OF_ARRAY(imageViewTypes); viewTypeNdx++)
857 const VkImageViewType viewType = imageViewTypes[viewTypeNdx].type;
858 de::MovePtr<tcu::TestCaseGroup> viewTypeGroup (new tcu::TestCaseGroup(testCtx, imageViewTypes[viewTypeNdx].name, (std::string("Uses a ") + imageViewTypes[viewTypeNdx].name + " view").c_str()));
859 de::MovePtr<tcu::TestCaseGroup> formatTests (new tcu::TestCaseGroup(testCtx, "format", "Tests samplable formats"));
861 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
863 const VkFormat format = formats[formatNdx];
864 const bool isCompressed = isCompressedFormat(format);
868 // Do not use compressed formats with 1D and 1D array textures.
869 if (viewType == VK_IMAGE_VIEW_TYPE_1D || viewType == VK_IMAGE_VIEW_TYPE_1D_ARRAY)
873 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx,
874 getFormatCaseName(format).c_str(),
875 (std::string("Samples a texture of format ") + getFormatName(format)).c_str()));
879 // Do not include minFilter tests with compressed formats.
880 // Randomly generated compressed textures are too noisy and will derive in false positives.
881 de::MovePtr<tcu::TestCaseGroup> minFilterTests = createSamplerMinFilterTests(testCtx, viewType, format);
882 formatGroup->addChild(minFilterTests.release());
885 de::MovePtr<tcu::TestCaseGroup> magFilterTests = createSamplerMagFilterTests(testCtx, viewType, format);
886 de::MovePtr<tcu::TestCaseGroup> mipmapTests = createSamplerMipmapTests(testCtx, viewType, format);
888 formatGroup->addChild(magFilterTests.release());
889 formatGroup->addChild(mipmapTests.release());
891 if (viewType != VK_IMAGE_VIEW_TYPE_CUBE && viewType != VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
893 de::MovePtr<tcu::TestCaseGroup> addressModesTests = createSamplerAddressModesTests(testCtx, viewType, format);
894 formatGroup->addChild(addressModesTests.release());
897 formatTests->addChild(formatGroup.release());
900 viewTypeGroup->addChild(formatTests.release());
901 viewTypeTests->addChild(viewTypeGroup.release());
904 samplerTests->addChild(viewTypeTests.release());
906 return samplerTests.release();