1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Imagination Technologies Ltd.
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and/or associated documentation files (the
10 * "Materials"), to deal in the Materials without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sublicense, and/or sell copies of the Materials, and to
13 * permit persons to whom the Materials are furnished to do so, subject to
14 * the following conditions:
16 * The above copyright notice(s) and this permission notice shall be included
17 * in all copies or substantial portions of the Materials.
19 * The Materials are Confidential Information as defined by the
20 * Khronos Membership Agreement until designated non-confidential by Khronos,
21 * at which point this condition clause shall be removed.
23 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
26 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
27 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
28 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
29 * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
34 *//*--------------------------------------------------------------------*/
36 #include "vktPipelineImageTests.hpp"
37 #include "vktPipelineImageSamplingInstance.hpp"
38 #include "vktPipelineImageUtil.hpp"
39 #include "vktPipelineVertexUtil.hpp"
40 #include "vktTestCase.hpp"
41 #include "vkImageUtil.hpp"
42 #include "vkPrograms.hpp"
43 #include "tcuTextureUtil.hpp"
44 #include "deStringUtil.hpp"
60 class ImageTest : public vkt::TestCase
63 ImageTest (tcu::TestContext& testContext,
65 const char* description,
66 VkImageViewType imageViewType,
68 const tcu::IVec3& imageSize,
71 virtual void initPrograms (SourceCollections& sourceCollections) const;
72 virtual TestInstance* createInstance (Context& context) const;
73 static std::string getGlslSamplerType (const tcu::TextureFormat& format, VkImageViewType type);
76 VkImageViewType m_imageViewType;
77 VkFormat m_imageFormat;
78 tcu::IVec3 m_imageSize;
82 ImageTest::ImageTest (tcu::TestContext& testContext,
84 const char* description,
85 VkImageViewType imageViewType,
87 const tcu::IVec3& imageSize,
90 : vkt::TestCase (testContext, name, description)
91 , m_imageViewType (imageViewType)
92 , m_imageFormat (imageFormat)
93 , m_imageSize (imageSize)
94 , m_arraySize (arraySize)
98 void ImageTest::initPrograms (SourceCollections& sourceCollections) const
100 std::ostringstream vertexSrc;
101 std::ostringstream fragmentSrc;
102 const char* texCoordSwizzle = DE_NULL;
103 const tcu::TextureFormat format = (isCompressedFormat(m_imageFormat)) ? tcu::getUncompressedFormat(mapVkCompressedFormat(m_imageFormat))
104 : mapVkFormat(m_imageFormat);
105 const tcu::TextureFormatInfo formatInfo = tcu::getTextureFormatInfo(format);
107 switch (m_imageViewType)
109 case VK_IMAGE_VIEW_TYPE_1D:
110 texCoordSwizzle = "x";
112 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
113 case VK_IMAGE_VIEW_TYPE_2D:
114 texCoordSwizzle = "xy";
116 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
117 case VK_IMAGE_VIEW_TYPE_3D:
118 case VK_IMAGE_VIEW_TYPE_CUBE:
119 texCoordSwizzle = "xyz";
121 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
122 texCoordSwizzle = "xyzw";
129 vertexSrc << "#version 440\n"
130 << "layout(location = 0) in vec4 position;\n"
131 << "layout(location = 1) in vec4 texCoords;\n"
132 << "layout(location = 0) out highp vec4 vtxTexCoords;\n"
133 << "out gl_PerVertex {\n"
134 << " vec4 gl_Position;\n"
136 << "void main (void)\n"
138 << " gl_Position = position;\n"
139 << " vtxTexCoords = texCoords;\n"
142 fragmentSrc << "#version 440\n"
143 << "layout(set = 0, binding = 0) uniform highp " << getGlslSamplerType(format, m_imageViewType) << " texSampler;\n"
144 << "layout(location = 0) in highp vec4 vtxTexCoords;\n"
145 << "layout(location = 0) out highp vec4 fragColor;\n"
146 << "void main (void)\n"
148 << " fragColor = (texture(texSampler, vtxTexCoords." << texCoordSwizzle << std::scientific << ") * vec4" << formatInfo.lookupScale << ") + vec4" << formatInfo.lookupBias << ";\n"
151 sourceCollections.glslSources.add("tex_vert") << glu::VertexSource(vertexSrc.str());
152 sourceCollections.glslSources.add("tex_frag") << glu::FragmentSource(fragmentSrc.str());
155 TestInstance* ImageTest::createInstance (Context& context) const
157 tcu::UVec2 renderSize;
159 if (m_imageViewType == VK_IMAGE_VIEW_TYPE_1D || m_imageViewType == VK_IMAGE_VIEW_TYPE_2D)
161 renderSize = tcu::UVec2((deUint32)m_imageSize.x(), (deUint32)m_imageSize.y());
165 // Draw a 3x2 grid of texture layers
166 renderSize = tcu::UVec2((deUint32)m_imageSize.x() * 3, (deUint32)m_imageSize.y() * 2);
169 const std::vector<Vertex4Tex4> vertices = createTestQuadMosaic(m_imageViewType);
170 const VkComponentMapping componentMapping = getFormatComponentMapping(m_imageFormat);
171 const VkImageSubresourceRange subresourceRange =
173 VK_IMAGE_ASPECT_COLOR_BIT,
175 (deUint32)deLog2Floor32(deMax32(m_imageSize.x(), deMax32(m_imageSize.y(), m_imageSize.z()))) + 1,
177 (deUint32)m_arraySize,
180 const VkSamplerCreateInfo samplerParams =
182 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType;
183 DE_NULL, // const void* pNext;
184 0u, // VkSamplerCreateFlags flags;
185 VK_FILTER_NEAREST, // VkFilter magFilter;
186 VK_FILTER_NEAREST, // VkFilter minFilter;
187 VK_SAMPLER_MIPMAP_MODE_NEAREST, // VkSamplerMipmapMode mipmapMode;
188 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeU;
189 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeV;
190 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeW;
191 0.0f, // float mipLodBias;
192 VK_FALSE, // VkBool32 anisotropyEnable;
193 1.0f, // float maxAnisotropy;
194 false, // VkBool32 compareEnable;
195 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp;
196 0.0f, // float minLod;
197 (float)(subresourceRange.levelCount - 1), // float maxLod;
198 getFormatBorderColor(BORDER_COLOR_TRANSPARENT_BLACK, m_imageFormat), // VkBorderColor borderColor;
199 false // VkBool32 unnormalizedCoordinates;
202 return new ImageSamplingInstance(context, renderSize, m_imageViewType, m_imageFormat, m_imageSize, m_arraySize, componentMapping, subresourceRange, samplerParams, 0.0f, vertices);
205 std::string ImageTest::getGlslSamplerType (const tcu::TextureFormat& format, VkImageViewType type)
207 std::ostringstream samplerType;
209 if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
211 else if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
216 case VK_IMAGE_VIEW_TYPE_1D:
217 samplerType << "sampler1D";
220 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
221 samplerType << "sampler1DArray";
224 case VK_IMAGE_VIEW_TYPE_2D:
225 samplerType << "sampler2D";
228 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
229 samplerType << "sampler2DArray";
232 case VK_IMAGE_VIEW_TYPE_3D:
233 samplerType << "sampler3D";
236 case VK_IMAGE_VIEW_TYPE_CUBE:
237 samplerType << "samplerCube";
240 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
241 samplerType << "samplerCubeArray";
245 DE_FATAL("Unknown image view type");
249 return samplerType.str();
252 std::string getFormatCaseName (const VkFormat format)
254 const std::string fullName = getFormatName(format);
256 DE_ASSERT(de::beginsWith(fullName, "VK_FORMAT_"));
258 return de::toLower(fullName.substr(10));
261 std::string getSizeName (VkImageViewType viewType, const tcu::IVec3& size, int arraySize)
263 std::ostringstream caseName;
267 case VK_IMAGE_VIEW_TYPE_1D:
268 case VK_IMAGE_VIEW_TYPE_2D:
269 case VK_IMAGE_VIEW_TYPE_CUBE:
270 caseName << size.x() << "x" << size.y();
273 case VK_IMAGE_VIEW_TYPE_3D:
274 caseName << size.x() << "x" << size.y() << "x" << size.z();
277 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
278 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
279 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
280 caseName << size.x() << "x" << size.y() << "_array_of_" << arraySize;
288 return caseName.str();
291 de::MovePtr<tcu::TestCaseGroup> createImageSizeTests (tcu::TestContext& testCtx, VkImageViewType imageViewType, VkFormat imageFormat)
295 std::vector<IVec3> imageSizes;
296 std::vector<int> arraySizes;
297 de::MovePtr<tcu::TestCaseGroup> imageSizeTests (new tcu::TestCaseGroup(testCtx, "size", ""));
299 // Select image imageSizes
300 switch (imageViewType)
302 case VK_IMAGE_VIEW_TYPE_1D:
303 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
305 imageSizes.push_back(IVec3(1, 1, 1));
306 imageSizes.push_back(IVec3(2, 1, 1));
307 imageSizes.push_back(IVec3(32, 1, 1));
308 imageSizes.push_back(IVec3(128, 1, 1));
309 imageSizes.push_back(IVec3(512, 1, 1));
312 imageSizes.push_back(IVec3(3, 1, 1));
313 imageSizes.push_back(IVec3(13, 1, 1));
314 imageSizes.push_back(IVec3(127, 1, 1));
315 imageSizes.push_back(IVec3(443, 1, 1));
318 case VK_IMAGE_VIEW_TYPE_2D:
319 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
321 imageSizes.push_back(IVec3(1, 1, 1));
322 imageSizes.push_back(IVec3(2, 2, 1));
323 imageSizes.push_back(IVec3(32, 32, 1));
326 imageSizes.push_back(IVec3(3, 3, 1));
327 imageSizes.push_back(IVec3(13, 13, 1));
330 imageSizes.push_back(IVec3(8, 16, 1));
331 imageSizes.push_back(IVec3(32, 16, 1));
334 imageSizes.push_back(IVec3(13, 23, 1));
335 imageSizes.push_back(IVec3(23, 8, 1));
338 case VK_IMAGE_VIEW_TYPE_3D:
340 imageSizes.push_back(IVec3(1, 1, 1));
341 imageSizes.push_back(IVec3(2, 2, 2));
342 imageSizes.push_back(IVec3(16, 16, 16));
345 imageSizes.push_back(IVec3(32, 16, 8));
346 imageSizes.push_back(IVec3(8, 16, 32));
349 case VK_IMAGE_VIEW_TYPE_CUBE:
350 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
352 imageSizes.push_back(IVec3(32, 32, 1));
355 imageSizes.push_back(IVec3(13, 13, 1));
363 // Select array sizes
364 switch (imageViewType)
366 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
367 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
368 arraySizes.push_back(3);
369 arraySizes.push_back(6);
372 case VK_IMAGE_VIEW_TYPE_CUBE:
373 arraySizes.push_back(6);
376 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
377 arraySizes.push_back(6);
378 arraySizes.push_back(6 * 6);
382 arraySizes.push_back(1);
386 for (size_t sizeNdx = 0; sizeNdx < imageSizes.size(); sizeNdx++)
388 for (size_t arraySizeNdx = 0; arraySizeNdx < arraySizes.size(); arraySizeNdx++)
390 imageSizeTests->addChild(new ImageTest(testCtx,
391 getSizeName(imageViewType, imageSizes[sizeNdx], arraySizes[arraySizeNdx]).c_str(),
396 arraySizes[arraySizeNdx]));
400 return imageSizeTests;
405 tcu::TestCaseGroup* createImageTests (tcu::TestContext& testCtx)
409 VkImageViewType type;
414 { VK_IMAGE_VIEW_TYPE_1D, "1d" },
415 { VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array" },
416 { VK_IMAGE_VIEW_TYPE_2D, "2d" },
417 { VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array" },
418 { VK_IMAGE_VIEW_TYPE_3D, "3d" },
419 { VK_IMAGE_VIEW_TYPE_CUBE, "cube" },
420 { VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array" }
423 // All supported dEQP formats that are not intended for depth or stencil.
424 const VkFormat formats[] =
426 VK_FORMAT_R4G4_UNORM_PACK8,
427 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
428 VK_FORMAT_R5G6B5_UNORM_PACK16,
429 VK_FORMAT_R5G5B5A1_UNORM_PACK16,
432 VK_FORMAT_R8_USCALED,
433 VK_FORMAT_R8_SSCALED,
437 VK_FORMAT_R8G8_UNORM,
438 VK_FORMAT_R8G8_SNORM,
439 VK_FORMAT_R8G8_USCALED,
440 VK_FORMAT_R8G8_SSCALED,
444 VK_FORMAT_R8G8B8_UNORM,
445 VK_FORMAT_R8G8B8_SNORM,
446 VK_FORMAT_R8G8B8_USCALED,
447 VK_FORMAT_R8G8B8_SSCALED,
448 VK_FORMAT_R8G8B8_UINT,
449 VK_FORMAT_R8G8B8_SINT,
450 VK_FORMAT_R8G8B8_SRGB,
451 VK_FORMAT_R8G8B8A8_UNORM,
452 VK_FORMAT_R8G8B8A8_SNORM,
453 VK_FORMAT_R8G8B8A8_USCALED,
454 VK_FORMAT_R8G8B8A8_SSCALED,
455 VK_FORMAT_R8G8B8A8_UINT,
456 VK_FORMAT_R8G8B8A8_SINT,
457 VK_FORMAT_R8G8B8A8_SRGB,
458 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
459 VK_FORMAT_A2R10G10B10_UINT_PACK32,
460 VK_FORMAT_A2R10G10B10_USCALED_PACK32,
463 VK_FORMAT_R16_USCALED,
464 VK_FORMAT_R16_SSCALED,
467 VK_FORMAT_R16_SFLOAT,
468 VK_FORMAT_R16G16_UNORM,
469 VK_FORMAT_R16G16_SNORM,
470 VK_FORMAT_R16G16_USCALED,
471 VK_FORMAT_R16G16_SSCALED,
472 VK_FORMAT_R16G16_UINT,
473 VK_FORMAT_R16G16_SINT,
474 VK_FORMAT_R16G16_SFLOAT,
475 VK_FORMAT_R16G16B16_UNORM,
476 VK_FORMAT_R16G16B16_SNORM,
477 VK_FORMAT_R16G16B16_USCALED,
478 VK_FORMAT_R16G16B16_SSCALED,
479 VK_FORMAT_R16G16B16_UINT,
480 VK_FORMAT_R16G16B16_SINT,
481 VK_FORMAT_R16G16B16_SFLOAT,
482 VK_FORMAT_R16G16B16A16_UNORM,
483 VK_FORMAT_R16G16B16A16_SNORM,
484 VK_FORMAT_R16G16B16A16_USCALED,
485 VK_FORMAT_R16G16B16A16_SSCALED,
486 VK_FORMAT_R16G16B16A16_UINT,
487 VK_FORMAT_R16G16B16A16_SINT,
488 VK_FORMAT_R16G16B16A16_SFLOAT,
491 VK_FORMAT_R32_SFLOAT,
492 VK_FORMAT_R32G32_UINT,
493 VK_FORMAT_R32G32_SINT,
494 VK_FORMAT_R32G32_SFLOAT,
495 VK_FORMAT_R32G32B32_UINT,
496 VK_FORMAT_R32G32B32_SINT,
497 VK_FORMAT_R32G32B32_SFLOAT,
498 VK_FORMAT_R32G32B32A32_UINT,
499 VK_FORMAT_R32G32B32A32_SINT,
500 VK_FORMAT_R32G32B32A32_SFLOAT,
501 VK_FORMAT_B10G11R11_UFLOAT_PACK32,
502 VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
503 VK_FORMAT_B4G4R4A4_UNORM_PACK16,
504 VK_FORMAT_B5G5R5A1_UNORM_PACK16,
506 // Compressed formats
507 VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
508 VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
509 VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
510 VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
511 VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
512 VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
513 VK_FORMAT_EAC_R11_UNORM_BLOCK,
514 VK_FORMAT_EAC_R11_SNORM_BLOCK,
515 VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
516 VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
517 VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
518 VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
519 VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
520 VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
521 VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
522 VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
523 VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
524 VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
525 VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
526 VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
527 VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
528 VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
529 VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
530 VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
531 VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
532 VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
533 VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
534 VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
535 VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
536 VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
537 VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
538 VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
539 VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
540 VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
541 VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
542 VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
543 VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
544 VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
547 de::MovePtr<tcu::TestCaseGroup> imageTests (new tcu::TestCaseGroup(testCtx, "image", "Image tests"));
548 de::MovePtr<tcu::TestCaseGroup> viewTypeTests (new tcu::TestCaseGroup(testCtx, "view_type", ""));
550 for (int viewTypeNdx = 0; viewTypeNdx < DE_LENGTH_OF_ARRAY(imageViewTypes); viewTypeNdx++)
552 const VkImageViewType viewType = imageViewTypes[viewTypeNdx].type;
553 de::MovePtr<tcu::TestCaseGroup> viewTypeGroup (new tcu::TestCaseGroup(testCtx, imageViewTypes[viewTypeNdx].name, (std::string("Uses a ") + imageViewTypes[viewTypeNdx].name + " view").c_str()));
554 de::MovePtr<tcu::TestCaseGroup> formatTests (new tcu::TestCaseGroup(testCtx, "format", "Tests samplable formats"));
556 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
558 const VkFormat format = formats[formatNdx];
560 if (isCompressedFormat(format))
562 // Do not use compressed formats with 1D and 1D array textures.
563 if (viewType == VK_IMAGE_VIEW_TYPE_1D || viewType == VK_IMAGE_VIEW_TYPE_1D_ARRAY)
566 // 3D ASTC textures are not supported.
567 if (tcu::isAstcFormat(mapVkCompressedFormat(format)) && viewType == VK_IMAGE_VIEW_TYPE_3D)
571 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx,
572 getFormatCaseName(format).c_str(),
573 (std::string("Samples a texture of format ") + getFormatName(format)).c_str()));
575 de::MovePtr<tcu::TestCaseGroup> sizeTests = createImageSizeTests(testCtx, viewType, format);
577 formatGroup->addChild(sizeTests.release());
578 formatTests->addChild(formatGroup.release());
581 viewTypeGroup->addChild(formatTests.release());
582 viewTypeTests->addChild(viewTypeGroup.release());
585 imageTests->addChild(viewTypeTests.release());
587 return imageTests.release();