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);
188 // \note We don't want to perform normalization on any compressed formats.
189 // In case of non-sRGB LDR ASTC it would lead to lack of coverage
190 // as uncompressed format for that is f16 but values will be in range
192 const tcu::TextureFormatInfo formatInfo = (!isCompressedFormat(m_imageFormat) ? tcu::getTextureFormatInfo(format)
193 : tcu::getTextureFormatInfo(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)));
195 switch (m_imageViewType)
197 case VK_IMAGE_VIEW_TYPE_1D:
198 texCoordSwizzle = "x";
200 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
201 case VK_IMAGE_VIEW_TYPE_2D:
202 texCoordSwizzle = "xy";
204 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
205 case VK_IMAGE_VIEW_TYPE_3D:
206 case VK_IMAGE_VIEW_TYPE_CUBE:
207 texCoordSwizzle = "xyz";
209 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
210 texCoordSwizzle = "xyzw";
217 vertexSrc << "#version 440\n"
218 << "layout(location = 0) in vec4 position;\n"
219 << "layout(location = 1) in vec4 texCoords;\n"
220 << "layout(location = 0) out highp vec4 vtxTexCoords;\n"
221 << "out gl_PerVertex {\n"
222 << " vec4 gl_Position;\n"
224 << "void main (void)\n"
226 << " gl_Position = position;\n"
227 << " vtxTexCoords = texCoords;\n"
230 fragmentSrc << "#version 440\n"
231 << "layout(set = 0, binding = 0) uniform highp " << getGlslSamplerType(format, m_imageViewType) << " texSampler;\n"
232 << "layout(location = 0) in highp vec4 vtxTexCoords;\n"
233 << "layout(location = 0) out highp vec4 fragColor;\n"
234 << "void main (void)\n"
238 if (m_samplerLod > 0.0f)
239 fragmentSrc << "textureLod(texSampler, vtxTexCoords." << texCoordSwizzle << ", " << std::fixed << m_samplerLod << ")";
241 fragmentSrc << "texture(texSampler, vtxTexCoords." << texCoordSwizzle << ")" << std::fixed;
243 fragmentSrc << " * vec4" << std::scientific << formatInfo.lookupScale << " + vec4" << formatInfo.lookupBias << ";\n"
246 sourceCollections.glslSources.add("tex_vert") << glu::VertexSource(vertexSrc.str());
247 sourceCollections.glslSources.add("tex_frag") << glu::FragmentSource(fragmentSrc.str());
250 TestInstance* SamplerTest::createInstance (Context& context) const
252 const tcu::UVec2 renderSize = getRenderSize(m_imageViewType);
253 const std::vector<Vertex4Tex4> vertices = createVertices();
254 const VkSamplerCreateInfo samplerParams = getSamplerCreateInfo();
255 const VkComponentMapping componentMapping = getFormatComponentMapping(m_imageFormat);
256 const VkImageSubresourceRange subresourceRange =
258 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
259 0u, // deUint32 baseMipLevel;
260 (deUint32)deLog2Floor32(m_imageSize) + 1, // deUint32 mipLevels;
261 0u, // deUint32 baseArrayLayer;
262 (deUint32)SamplerTest::getArraySize(m_imageViewType) // deUint32 arraySize;
267 return new ImageSamplingInstance(context, renderSize, m_imageViewType, m_imageFormat,
268 getImageSize(m_imageViewType, m_imageSize),
269 getArraySize(m_imageViewType),
270 componentMapping, subresourceRange,
271 samplerParams, m_samplerLod,vertices);
274 tcu::UVec2 SamplerTest::getRenderSize (VkImageViewType viewType) const
276 if (viewType == VK_IMAGE_VIEW_TYPE_1D || viewType == VK_IMAGE_VIEW_TYPE_2D)
278 return tcu::UVec2(16u, 16u);
282 return tcu::UVec2(16u * 3u, 16u * 2u);
286 std::vector<Vertex4Tex4> SamplerTest::createVertices (void) const
288 std::vector<Vertex4Tex4> vertices = createTestQuadMosaic(m_imageViewType);
289 // Adjust texture coordinate to avoid doing NEAREST filtering exactly on texel boundaries.
290 // TODO: Would be nice to base this on number of texels and subtexel precision. But this
292 for (unsigned int i = 0; i < vertices.size(); ++i) {
293 vertices[i].texCoord += tcu::Vec4(0.002f, 0.002f, 0.002f, 0.0f);
298 VkSamplerCreateInfo SamplerTest::getSamplerCreateInfo (void) const
300 const VkSamplerCreateInfo defaultSamplerParams =
302 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType;
303 DE_NULL, // const void* pNext;
304 0u, // VkSamplerCreateFlags flags;
305 VK_FILTER_NEAREST, // VkFilter magFilter;
306 VK_FILTER_NEAREST, // VkFilter minFilter;
307 VK_SAMPLER_MIPMAP_MODE_NEAREST, // VkSamplerMipmapMode mipmapMode;
308 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeU;
309 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeV;
310 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeW;
311 0.0f, // float mipLodBias;
312 VK_FALSE, // VkBool32 anisotropyEnable;
313 1.0f, // float maxAnisotropy;
314 false, // VkBool32 compareEnable;
315 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp;
316 0.0f, // float minLod;
317 0.25f, // float maxLod;
318 getFormatBorderColor(BORDER_COLOR_TRANSPARENT_BLACK, m_imageFormat), // VkBorderColor borderColor;
319 false // VkBool32 unnormalizedCoordinates;
322 return defaultSamplerParams;
325 std::string SamplerTest::getGlslSamplerType (const tcu::TextureFormat& format, VkImageViewType type)
327 std::ostringstream samplerType;
329 if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
331 else if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
336 case VK_IMAGE_VIEW_TYPE_1D:
337 samplerType << "sampler1D";
340 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
341 samplerType << "sampler1DArray";
344 case VK_IMAGE_VIEW_TYPE_2D:
345 samplerType << "sampler2D";
348 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
349 samplerType << "sampler2DArray";
352 case VK_IMAGE_VIEW_TYPE_3D:
353 samplerType << "sampler3D";
356 case VK_IMAGE_VIEW_TYPE_CUBE:
357 samplerType << "samplerCube";
360 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
361 samplerType << "samplerCubeArray";
365 DE_FATAL("Unknown image view type");
369 return samplerType.str();
372 tcu::IVec3 SamplerTest::getImageSize (VkImageViewType viewType, int size)
376 case VK_IMAGE_VIEW_TYPE_1D:
377 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
378 return tcu::IVec3(size, 1, 1);
380 case VK_IMAGE_VIEW_TYPE_3D:
381 return tcu::IVec3(size, size, 4);
387 return tcu::IVec3(size, size, 1);
390 int SamplerTest::getArraySize (VkImageViewType viewType)
394 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
395 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
396 case VK_IMAGE_VIEW_TYPE_CUBE:
399 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
410 // SamplerMagFilterTest
412 SamplerMagFilterTest::SamplerMagFilterTest (tcu::TestContext& testContext,
414 const char* description,
415 VkImageViewType imageViewType,
416 VkFormat imageFormat,
418 : SamplerTest (testContext, name, description, imageViewType, imageFormat, 8, 0.0f)
419 , m_magFilter (magFilter)
423 VkSamplerCreateInfo SamplerMagFilterTest::getSamplerCreateInfo (void) const
425 VkSamplerCreateInfo samplerParams = SamplerTest::getSamplerCreateInfo();
426 samplerParams.magFilter = m_magFilter;
428 return samplerParams;
432 // SamplerMinFilterTest
434 SamplerMinFilterTest::SamplerMinFilterTest (tcu::TestContext& testContext,
436 const char* description,
437 VkImageViewType imageViewType,
438 VkFormat imageFormat,
440 : SamplerTest (testContext, name, description, imageViewType, imageFormat, 32, 0.0f)
441 , m_minFilter (minFilter)
445 VkSamplerCreateInfo SamplerMinFilterTest::getSamplerCreateInfo (void) const
447 VkSamplerCreateInfo samplerParams = SamplerTest::getSamplerCreateInfo();
448 samplerParams.minFilter = m_minFilter;
449 // set minLod to epsilon, to force use of the minFilter
450 samplerParams.minLod = 0.01f;
452 return samplerParams;
458 SamplerLodTest::SamplerLodTest (tcu::TestContext& testContext,
460 const char* description,
461 VkImageViewType imageViewType,
462 VkFormat imageFormat,
463 VkSamplerMipmapMode mipmapMode,
468 : SamplerTest (testContext, name, description, imageViewType, imageFormat, 32, samplerLod)
469 , m_mipmapMode (mipmapMode)
472 , m_mipLodBias (mipLodBias)
476 VkSamplerCreateInfo SamplerLodTest::getSamplerCreateInfo (void) const
478 VkSamplerCreateInfo samplerParams = SamplerTest::getSamplerCreateInfo();
480 samplerParams.mipmapMode = m_mipmapMode;
481 samplerParams.minLod = m_minLod;
482 samplerParams.maxLod = m_maxLod;
483 samplerParams.mipLodBias = m_mipLodBias;
485 return samplerParams;
489 // SamplerAddressModesTest
491 SamplerAddressModesTest::SamplerAddressModesTest (tcu::TestContext& testContext,
493 const char* description,
494 VkImageViewType imageViewType,
495 VkFormat imageFormat,
496 VkSamplerAddressMode addressU,
497 VkSamplerAddressMode addressV,
498 VkSamplerAddressMode addressW,
499 VkBorderColor borderColor)
500 : SamplerTest (testContext, name, description, imageViewType, imageFormat, 8, 0.0f)
501 , m_addressU (addressU)
502 , m_addressV (addressV)
503 , m_addressW (addressW)
504 , m_borderColor (borderColor)
508 tcu::UVec2 SamplerAddressModesTest::getRenderSize (VkImageViewType viewType) const
510 return 4u * SamplerTest::getRenderSize(viewType);
513 std::vector<Vertex4Tex4> SamplerAddressModesTest::createVertices (void) const
515 std::vector<Vertex4Tex4> vertices = SamplerTest::createVertices();
517 switch (m_imageViewType)
519 case VK_IMAGE_VIEW_TYPE_1D: case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
520 for (size_t vertexNdx = 0; vertexNdx < vertices.size(); vertexNdx++)
521 vertices[vertexNdx].texCoord.x() = (vertices[vertexNdx].texCoord.x() - 0.5f) * 4.0f;
525 case VK_IMAGE_VIEW_TYPE_2D:
526 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
527 for (size_t vertexNdx = 0; vertexNdx < vertices.size(); vertexNdx++)
528 vertices[vertexNdx].texCoord.xy() = (vertices[vertexNdx].texCoord.swizzle(0, 1) - tcu::Vec2(0.5f)) * 4.0f;
532 case VK_IMAGE_VIEW_TYPE_3D:
533 for (size_t vertexNdx = 0; vertexNdx < vertices.size(); vertexNdx++)
534 vertices[vertexNdx].texCoord.xyz() = (vertices[vertexNdx].texCoord.swizzle(0, 1, 2) - tcu::Vec3(0.5f)) * 4.0f;
538 case VK_IMAGE_VIEW_TYPE_CUBE:
539 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
549 VkSamplerCreateInfo SamplerAddressModesTest::getSamplerCreateInfo (void) const
551 VkSamplerCreateInfo samplerParams = SamplerTest::getSamplerCreateInfo();
552 samplerParams.addressModeU = m_addressU;
553 samplerParams.addressModeV = m_addressV;
554 samplerParams.addressModeW = m_addressW;
555 samplerParams.borderColor = m_borderColor;
557 return samplerParams;
561 // Utilities to create test nodes
563 std::string getFormatCaseName (const VkFormat format)
565 const std::string fullName = getFormatName(format);
567 DE_ASSERT(de::beginsWith(fullName, "VK_FORMAT_"));
569 return de::toLower(fullName.substr(10));
572 MovePtr<tcu::TestCaseGroup> createSamplerMagFilterTests (tcu::TestContext& testCtx, VkImageViewType imageViewType, VkFormat imageFormat)
574 MovePtr<tcu::TestCaseGroup> samplerMagFilterTests (new tcu::TestCaseGroup(testCtx, "mag_filter", "Tests for magnification filter"));
576 if (isCompressedFormat(imageFormat) || (!isIntFormat(imageFormat) && !isUintFormat(imageFormat)))
577 samplerMagFilterTests->addChild(new SamplerMagFilterTest(testCtx, "linear", "Magnifies image using VK_TEX_FILTER_LINEAR", imageViewType, imageFormat, VK_FILTER_LINEAR));
578 samplerMagFilterTests->addChild(new SamplerMagFilterTest(testCtx, "nearest", "Magnifies image using VK_TEX_FILTER_NEAREST", imageViewType, imageFormat, VK_FILTER_NEAREST));
580 return samplerMagFilterTests;
583 MovePtr<tcu::TestCaseGroup> createSamplerMinFilterTests (tcu::TestContext& testCtx, VkImageViewType imageViewType, VkFormat imageFormat)
585 MovePtr<tcu::TestCaseGroup> samplerMinFilterTests (new tcu::TestCaseGroup(testCtx, "min_filter", "Tests for minification filter"));
587 if (isCompressedFormat(imageFormat) || (!isIntFormat(imageFormat) && !isUintFormat(imageFormat)))
588 samplerMinFilterTests->addChild(new SamplerMinFilterTest(testCtx, "linear", "Minifies image using VK_TEX_FILTER_LINEAR", imageViewType, imageFormat, VK_FILTER_LINEAR));
589 samplerMinFilterTests->addChild(new SamplerMinFilterTest(testCtx, "nearest", "Minifies image using VK_TEX_FILTER_NEAREST", imageViewType, imageFormat, VK_FILTER_NEAREST));
591 return samplerMinFilterTests;
594 MovePtr<tcu::TestCaseGroup> createSamplerLodTests (tcu::TestContext& testCtx, VkImageViewType imageViewType, VkFormat imageFormat, VkSamplerMipmapMode mipmapMode)
596 struct TestCaseConfig
599 const char* description;
606 TestCaseConfig testCaseConfigs [] =
608 { "equal_min_3_max_3", "minLod = 3, maxLod = 3, mipLodBias = 0, lod = 0", 3.0f, 3.0f, 0.0f, 0.0f },
609 { "select_min_1", "minLod = 1, maxLod = 5, mipLodBias = 0, lod = 0", 1.0f, 5.0f, 0.0f, 0.0f },
610 { "select_max_4", "minLod = 0, maxLod = 4, mipLodBias = 0, lod = 5", 0.0f, 4.0f, 0.0f, 5.0f },
611 { "select_bias_2_1", "minLod = 0, maxLod = 2.1, mipLodBias = 5.0, lod = 0", 0.0f, 2.1f, 5.0f, 0.0f },
612 { "select_bias_2_5", "minLod = 0, maxLod = 5, mipLodBias = 2.5, lod = 0", 0.0f, 5.0f, 2.5f, 0.00001f },
613 { "select_bias_3_1", "minLod = 0, maxLod = 5, mipLodBias = -0.9, lod = 4.0", 0.0f, 5.0f, -0.9f, 4.0f },
614 { "select_bias_3_7", "minLod = 0, maxLod = 5, mipLodBias = 3.0, lod = 0.7", 0.0f, 5.0f, 3.0f, 0.7f },
617 MovePtr<tcu::TestCaseGroup> samplerLodTests (new tcu::TestCaseGroup(testCtx, "lod", "Tests for sampler LOD"));
619 for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testCaseConfigs); configNdx++)
621 const TestCaseConfig& config = testCaseConfigs[configNdx];
623 samplerLodTests->addChild(new SamplerLodTest(testCtx, config.name, config.description, imageViewType, imageFormat, mipmapMode, config.minLod, config.maxLod, config.mipLodBias, config.lod));
626 return samplerLodTests;
629 MovePtr<tcu::TestCaseGroup> createSamplerMipmapTests (tcu::TestContext& testCtx, VkImageViewType imageViewType, VkFormat imageFormat)
631 MovePtr<tcu::TestCaseGroup> samplerMipmapTests (new tcu::TestCaseGroup(testCtx, "mipmap", "Tests for mipmap modes"));
633 // Mipmap mode: nearest
634 MovePtr<tcu::TestCaseGroup> mipmapNearestTests (new tcu::TestCaseGroup(testCtx, "nearest", "Uses VK_TEX_MIPMAP_MODE_NEAREST"));
635 mipmapNearestTests->addChild(createSamplerLodTests(testCtx, imageViewType, imageFormat, VK_SAMPLER_MIPMAP_MODE_NEAREST).release());
636 samplerMipmapTests->addChild(mipmapNearestTests.release());
638 // Mipmap mode: linear
639 if (isCompressedFormat(imageFormat) || (!isIntFormat(imageFormat) && !isUintFormat(imageFormat)))
641 MovePtr<tcu::TestCaseGroup> mipmapLinearTests(new tcu::TestCaseGroup(testCtx, "linear", "Uses VK_TEX_MIPMAP_MODE_LINEAR"));
642 mipmapLinearTests->addChild(createSamplerLodTests(testCtx, imageViewType, imageFormat, VK_SAMPLER_MIPMAP_MODE_LINEAR).release());
643 samplerMipmapTests->addChild(mipmapLinearTests.release());
646 return samplerMipmapTests;
649 std::string getAddressModesCaseName (VkSamplerAddressMode u, VkSamplerAddressMode v, VkSamplerAddressMode w, BorderColor border)
651 static const char* borderColorNames[BORDER_COLOR_COUNT] =
658 std::ostringstream caseName;
660 if (u == v && v == w)
662 const std::string fullName = getSamplerAddressModeName(u);
663 DE_ASSERT(de::beginsWith(fullName, "VK_SAMPLER_ADDRESS_"));
666 caseName << de::toLower(fullName.substr(19));
668 if (u == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER)
670 caseName << "_" << borderColorNames[border];
675 const std::string fullNameU = getSamplerAddressModeName(u);
676 const std::string fullNameV = getSamplerAddressModeName(v);
677 const std::string fullNameW = getSamplerAddressModeName(w);
679 DE_ASSERT(de::beginsWith(fullNameU, "VK_SAMPLER_ADDRESS_"));
680 DE_ASSERT(de::beginsWith(fullNameV, "VK_SAMPLER_ADDRESS_"));
681 DE_ASSERT(de::beginsWith(fullNameW, "VK_SAMPLER_ADDRESS_"));
684 << "_" << de::toLower(fullNameU.substr(19))
685 << "_" << de::toLower(fullNameV.substr(19))
686 << "_" << de::toLower(fullNameW.substr(19));
689 return caseName.str();
692 MovePtr<tcu::TestCaseGroup> createSamplerAddressModesTests (tcu::TestContext& testCtx, VkImageViewType imageViewType, VkFormat imageFormat)
694 struct TestCaseConfig
696 VkSamplerAddressMode u;
697 VkSamplerAddressMode v;
698 VkSamplerAddressMode w;
702 const TestCaseConfig testCaseConfigs[] =
704 // All address modes equal
705 { 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 },
706 { VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_REPEAT, BORDER_COLOR_TRANSPARENT_BLACK },
707 { VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, BORDER_COLOR_TRANSPARENT_BLACK },
708 { 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 },
710 // All address modes equal using border color
711 { 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 },
712 { 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 },
713 { 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 },
715 // Pairwise combinations of address modes not covered by previous tests
716 { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_REPEAT, BORDER_COLOR_OPAQUE_WHITE},
717 { 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 },
718 { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, BORDER_COLOR_OPAQUE_WHITE },
719 { 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 },
720 { 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 },
721 { 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 },
722 { VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, VK_SAMPLER_ADDRESS_MODE_REPEAT, BORDER_COLOR_OPAQUE_WHITE },
723 { 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 },
724 { VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, BORDER_COLOR_OPAQUE_WHITE },
725 { 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 },
726 { 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 },
727 { VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, BORDER_COLOR_OPAQUE_WHITE },
728 { VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_REPEAT, BORDER_COLOR_OPAQUE_WHITE },
729 { VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, BORDER_COLOR_OPAQUE_WHITE },
730 { VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, BORDER_COLOR_OPAQUE_WHITE },
731 { VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, BORDER_COLOR_OPAQUE_WHITE },
732 { 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 },
733 { 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 },
734 { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_REPEAT, BORDER_COLOR_OPAQUE_WHITE },
735 { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, BORDER_COLOR_OPAQUE_WHITE },
736 { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, BORDER_COLOR_OPAQUE_WHITE },
737 { 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 },
740 MovePtr<tcu::TestCaseGroup> samplerAddressModesTests (new tcu::TestCaseGroup(testCtx, "address_modes", "Tests for address modes"));
742 for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testCaseConfigs); configNdx++)
744 const TestCaseConfig& config = testCaseConfigs[configNdx];
746 samplerAddressModesTests->addChild(new SamplerAddressModesTest(testCtx,
747 getAddressModesCaseName(config.u, config.v, config.w, config.border).c_str(),
751 config.u, config.v, config.w,
752 getFormatBorderColor(config.border, imageFormat)));
755 return samplerAddressModesTests;
760 tcu::TestCaseGroup* createSamplerTests (tcu::TestContext& testCtx)
764 VkImageViewType type;
769 { VK_IMAGE_VIEW_TYPE_1D, "1d" },
770 { VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array" },
771 { VK_IMAGE_VIEW_TYPE_2D, "2d" },
772 { VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array" },
773 { VK_IMAGE_VIEW_TYPE_3D, "3d" },
774 { VK_IMAGE_VIEW_TYPE_CUBE, "cube" },
775 { VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array" }
778 const VkFormat formats[] =
781 VK_FORMAT_R4G4_UNORM_PACK8,
782 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
783 VK_FORMAT_R5G6B5_UNORM_PACK16,
784 VK_FORMAT_R5G5B5A1_UNORM_PACK16,
785 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
786 VK_FORMAT_A2R10G10B10_UINT_PACK32,
787 VK_FORMAT_B10G11R11_UFLOAT_PACK32,
788 VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
789 VK_FORMAT_B4G4R4A4_UNORM_PACK16,
790 VK_FORMAT_B5G5R5A1_UNORM_PACK16,
792 // Pairwise combinations of 8-bit channel formats, UNORM/SNORM/SINT/UINT/SRGB type x 1-to-4 channels x RGBA/BGRA order
794 VK_FORMAT_R8G8B8_UINT,
795 VK_FORMAT_B8G8R8A8_SINT,
796 VK_FORMAT_R8G8_UNORM,
797 VK_FORMAT_B8G8R8_SNORM,
798 VK_FORMAT_R8G8B8A8_SNORM,
801 VK_FORMAT_R8G8B8A8_SRGB,
802 VK_FORMAT_R8G8B8A8_UNORM,
803 VK_FORMAT_B8G8R8A8_UNORM,
804 VK_FORMAT_B8G8R8_SRGB,
807 VK_FORMAT_R8G8B8A8_UINT,
810 VK_FORMAT_B8G8R8_SINT,
811 VK_FORMAT_R8G8_SNORM,
812 VK_FORMAT_B8G8R8_UNORM,
815 // Pairwise combinations of 16/32-bit channel formats x SINT/UINT/SFLOAT type x 1-to-4 channels
816 VK_FORMAT_R32G32_SFLOAT,
817 VK_FORMAT_R32G32B32_UINT,
818 VK_FORMAT_R16G16B16A16_SFLOAT,
819 VK_FORMAT_R16G16_UINT,
820 VK_FORMAT_R32G32B32A32_SINT,
821 VK_FORMAT_R16G16B16_SINT,
822 VK_FORMAT_R16_SFLOAT,
825 VK_FORMAT_R16G16B16_SFLOAT,
826 VK_FORMAT_R16G16_SINT,
829 VK_FORMAT_R8G8B8A8_SSCALED,
830 VK_FORMAT_A2R10G10B10_USCALED_PACK32,
832 // Compressed formats
833 VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
834 VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
835 VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
836 VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
837 VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
838 VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
839 VK_FORMAT_EAC_R11_UNORM_BLOCK,
840 VK_FORMAT_EAC_R11_SNORM_BLOCK,
841 VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
842 VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
843 VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
844 VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
845 VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
846 VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
847 VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
848 VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
849 VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
850 VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
851 VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
852 VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
855 de::MovePtr<tcu::TestCaseGroup> samplerTests (new tcu::TestCaseGroup(testCtx, "sampler", "Sampler tests"));
856 de::MovePtr<tcu::TestCaseGroup> viewTypeTests (new tcu::TestCaseGroup(testCtx, "view_type", ""));
858 for (int viewTypeNdx = 0; viewTypeNdx < DE_LENGTH_OF_ARRAY(imageViewTypes); viewTypeNdx++)
860 const VkImageViewType viewType = imageViewTypes[viewTypeNdx].type;
861 de::MovePtr<tcu::TestCaseGroup> viewTypeGroup (new tcu::TestCaseGroup(testCtx, imageViewTypes[viewTypeNdx].name, (std::string("Uses a ") + imageViewTypes[viewTypeNdx].name + " view").c_str()));
862 de::MovePtr<tcu::TestCaseGroup> formatTests (new tcu::TestCaseGroup(testCtx, "format", "Tests samplable formats"));
864 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
866 const VkFormat format = formats[formatNdx];
867 const bool isCompressed = isCompressedFormat(format);
871 // Do not use compressed formats with 1D and 1D array textures.
872 if (viewType == VK_IMAGE_VIEW_TYPE_1D || viewType == VK_IMAGE_VIEW_TYPE_1D_ARRAY)
876 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx,
877 getFormatCaseName(format).c_str(),
878 (std::string("Samples a texture of format ") + getFormatName(format)).c_str()));
882 // Do not include minFilter tests with compressed formats.
883 // Randomly generated compressed textures are too noisy and will derive in false positives.
884 de::MovePtr<tcu::TestCaseGroup> minFilterTests = createSamplerMinFilterTests(testCtx, viewType, format);
885 formatGroup->addChild(minFilterTests.release());
888 de::MovePtr<tcu::TestCaseGroup> magFilterTests = createSamplerMagFilterTests(testCtx, viewType, format);
889 de::MovePtr<tcu::TestCaseGroup> mipmapTests = createSamplerMipmapTests(testCtx, viewType, format);
891 formatGroup->addChild(magFilterTests.release());
892 formatGroup->addChild(mipmapTests.release());
894 if (viewType != VK_IMAGE_VIEW_TYPE_CUBE && viewType != VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
896 de::MovePtr<tcu::TestCaseGroup> addressModesTests = createSamplerAddressModesTests(testCtx, viewType, format);
897 formatGroup->addChild(addressModesTests.release());
900 formatTests->addChild(formatGroup.release());
903 viewTypeGroup->addChild(formatTests.release());
904 viewTypeTests->addChild(viewTypeGroup.release());
907 samplerTests->addChild(viewTypeTests.release());
909 return samplerTests.release();