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);
106 // \note We don't want to perform normalization on any compressed formats.
107 // In case of non-sRGB LDR ASTC it would lead to lack of coverage
108 // as uncompressed format for that is f16 but values will be in range
110 const tcu::TextureFormatInfo formatInfo = (!isCompressedFormat(m_imageFormat) ? tcu::getTextureFormatInfo(format)
111 : tcu::getTextureFormatInfo(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)));
113 switch (m_imageViewType)
115 case VK_IMAGE_VIEW_TYPE_1D:
116 texCoordSwizzle = "x";
118 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
119 case VK_IMAGE_VIEW_TYPE_2D:
120 texCoordSwizzle = "xy";
122 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
123 case VK_IMAGE_VIEW_TYPE_3D:
124 case VK_IMAGE_VIEW_TYPE_CUBE:
125 texCoordSwizzle = "xyz";
127 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
128 texCoordSwizzle = "xyzw";
135 vertexSrc << "#version 440\n"
136 << "layout(location = 0) in vec4 position;\n"
137 << "layout(location = 1) in vec4 texCoords;\n"
138 << "layout(location = 0) out highp vec4 vtxTexCoords;\n"
139 << "out gl_PerVertex {\n"
140 << " vec4 gl_Position;\n"
142 << "void main (void)\n"
144 << " gl_Position = position;\n"
145 << " vtxTexCoords = texCoords;\n"
148 fragmentSrc << "#version 440\n"
149 << "layout(set = 0, binding = 0) uniform highp " << getGlslSamplerType(format, m_imageViewType) << " texSampler;\n"
150 << "layout(location = 0) in highp vec4 vtxTexCoords;\n"
151 << "layout(location = 0) out highp vec4 fragColor;\n"
152 << "void main (void)\n"
154 << " fragColor = (texture(texSampler, vtxTexCoords." << texCoordSwizzle << std::scientific << ") * vec4" << formatInfo.lookupScale << ") + vec4" << formatInfo.lookupBias << ";\n"
157 sourceCollections.glslSources.add("tex_vert") << glu::VertexSource(vertexSrc.str());
158 sourceCollections.glslSources.add("tex_frag") << glu::FragmentSource(fragmentSrc.str());
161 TestInstance* ImageTest::createInstance (Context& context) const
163 tcu::UVec2 renderSize;
165 if (m_imageViewType == VK_IMAGE_VIEW_TYPE_1D || m_imageViewType == VK_IMAGE_VIEW_TYPE_2D)
167 renderSize = tcu::UVec2((deUint32)m_imageSize.x(), (deUint32)m_imageSize.y());
171 // Draw a 3x2 grid of texture layers
172 renderSize = tcu::UVec2((deUint32)m_imageSize.x() * 3, (deUint32)m_imageSize.y() * 2);
175 const std::vector<Vertex4Tex4> vertices = createTestQuadMosaic(m_imageViewType);
176 const VkComponentMapping componentMapping = getFormatComponentMapping(m_imageFormat);
177 const VkImageSubresourceRange subresourceRange =
179 VK_IMAGE_ASPECT_COLOR_BIT,
181 (deUint32)deLog2Floor32(deMax32(m_imageSize.x(), deMax32(m_imageSize.y(), m_imageSize.z()))) + 1,
183 (deUint32)m_arraySize,
186 const VkSamplerCreateInfo samplerParams =
188 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType;
189 DE_NULL, // const void* pNext;
190 0u, // VkSamplerCreateFlags flags;
191 VK_FILTER_NEAREST, // VkFilter magFilter;
192 VK_FILTER_NEAREST, // VkFilter minFilter;
193 VK_SAMPLER_MIPMAP_MODE_NEAREST, // VkSamplerMipmapMode mipmapMode;
194 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeU;
195 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeV;
196 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeW;
197 0.0f, // float mipLodBias;
198 VK_FALSE, // VkBool32 anisotropyEnable;
199 1.0f, // float maxAnisotropy;
200 false, // VkBool32 compareEnable;
201 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp;
202 0.0f, // float minLod;
203 (float)(subresourceRange.levelCount - 1), // float maxLod;
204 getFormatBorderColor(BORDER_COLOR_TRANSPARENT_BLACK, m_imageFormat), // VkBorderColor borderColor;
205 false // VkBool32 unnormalizedCoordinates;
208 return new ImageSamplingInstance(context, renderSize, m_imageViewType, m_imageFormat, m_imageSize, m_arraySize, componentMapping, subresourceRange, samplerParams, 0.0f, vertices);
211 std::string ImageTest::getGlslSamplerType (const tcu::TextureFormat& format, VkImageViewType type)
213 std::ostringstream samplerType;
215 if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
217 else if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
222 case VK_IMAGE_VIEW_TYPE_1D:
223 samplerType << "sampler1D";
226 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
227 samplerType << "sampler1DArray";
230 case VK_IMAGE_VIEW_TYPE_2D:
231 samplerType << "sampler2D";
234 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
235 samplerType << "sampler2DArray";
238 case VK_IMAGE_VIEW_TYPE_3D:
239 samplerType << "sampler3D";
242 case VK_IMAGE_VIEW_TYPE_CUBE:
243 samplerType << "samplerCube";
246 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
247 samplerType << "samplerCubeArray";
251 DE_FATAL("Unknown image view type");
255 return samplerType.str();
258 std::string getFormatCaseName (const VkFormat format)
260 const std::string fullName = getFormatName(format);
262 DE_ASSERT(de::beginsWith(fullName, "VK_FORMAT_"));
264 return de::toLower(fullName.substr(10));
267 std::string getSizeName (VkImageViewType viewType, const tcu::IVec3& size, int arraySize)
269 std::ostringstream caseName;
273 case VK_IMAGE_VIEW_TYPE_1D:
274 case VK_IMAGE_VIEW_TYPE_2D:
275 case VK_IMAGE_VIEW_TYPE_CUBE:
276 caseName << size.x() << "x" << size.y();
279 case VK_IMAGE_VIEW_TYPE_3D:
280 caseName << size.x() << "x" << size.y() << "x" << size.z();
283 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
284 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
285 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
286 caseName << size.x() << "x" << size.y() << "_array_of_" << arraySize;
294 return caseName.str();
297 de::MovePtr<tcu::TestCaseGroup> createImageSizeTests (tcu::TestContext& testCtx, VkImageViewType imageViewType, VkFormat imageFormat)
301 std::vector<IVec3> imageSizes;
302 std::vector<int> arraySizes;
303 de::MovePtr<tcu::TestCaseGroup> imageSizeTests (new tcu::TestCaseGroup(testCtx, "size", ""));
305 // Select image imageSizes
306 switch (imageViewType)
308 case VK_IMAGE_VIEW_TYPE_1D:
309 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
311 imageSizes.push_back(IVec3(1, 1, 1));
312 imageSizes.push_back(IVec3(2, 1, 1));
313 imageSizes.push_back(IVec3(32, 1, 1));
314 imageSizes.push_back(IVec3(128, 1, 1));
315 imageSizes.push_back(IVec3(512, 1, 1));
318 imageSizes.push_back(IVec3(3, 1, 1));
319 imageSizes.push_back(IVec3(13, 1, 1));
320 imageSizes.push_back(IVec3(127, 1, 1));
321 imageSizes.push_back(IVec3(443, 1, 1));
324 case VK_IMAGE_VIEW_TYPE_2D:
325 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
327 imageSizes.push_back(IVec3(1, 1, 1));
328 imageSizes.push_back(IVec3(2, 2, 1));
329 imageSizes.push_back(IVec3(32, 32, 1));
332 imageSizes.push_back(IVec3(3, 3, 1));
333 imageSizes.push_back(IVec3(13, 13, 1));
336 imageSizes.push_back(IVec3(8, 16, 1));
337 imageSizes.push_back(IVec3(32, 16, 1));
340 imageSizes.push_back(IVec3(13, 23, 1));
341 imageSizes.push_back(IVec3(23, 8, 1));
344 case VK_IMAGE_VIEW_TYPE_3D:
346 imageSizes.push_back(IVec3(1, 1, 1));
347 imageSizes.push_back(IVec3(2, 2, 2));
348 imageSizes.push_back(IVec3(16, 16, 16));
351 imageSizes.push_back(IVec3(32, 16, 8));
352 imageSizes.push_back(IVec3(8, 16, 32));
355 case VK_IMAGE_VIEW_TYPE_CUBE:
356 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
358 imageSizes.push_back(IVec3(32, 32, 1));
361 imageSizes.push_back(IVec3(13, 13, 1));
369 // Select array sizes
370 switch (imageViewType)
372 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
373 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
374 arraySizes.push_back(3);
375 arraySizes.push_back(6);
378 case VK_IMAGE_VIEW_TYPE_CUBE:
379 arraySizes.push_back(6);
382 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
383 arraySizes.push_back(6);
384 arraySizes.push_back(6 * 6);
388 arraySizes.push_back(1);
392 for (size_t sizeNdx = 0; sizeNdx < imageSizes.size(); sizeNdx++)
394 for (size_t arraySizeNdx = 0; arraySizeNdx < arraySizes.size(); arraySizeNdx++)
396 imageSizeTests->addChild(new ImageTest(testCtx,
397 getSizeName(imageViewType, imageSizes[sizeNdx], arraySizes[arraySizeNdx]).c_str(),
402 arraySizes[arraySizeNdx]));
406 return imageSizeTests;
411 tcu::TestCaseGroup* createImageTests (tcu::TestContext& testCtx)
415 VkImageViewType type;
420 { VK_IMAGE_VIEW_TYPE_1D, "1d" },
421 { VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array" },
422 { VK_IMAGE_VIEW_TYPE_2D, "2d" },
423 { VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array" },
424 { VK_IMAGE_VIEW_TYPE_3D, "3d" },
425 { VK_IMAGE_VIEW_TYPE_CUBE, "cube" },
426 { VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array" }
429 // All supported dEQP formats that are not intended for depth or stencil.
430 const VkFormat formats[] =
432 VK_FORMAT_R4G4_UNORM_PACK8,
433 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
434 VK_FORMAT_R5G6B5_UNORM_PACK16,
435 VK_FORMAT_R5G5B5A1_UNORM_PACK16,
438 VK_FORMAT_R8_USCALED,
439 VK_FORMAT_R8_SSCALED,
443 VK_FORMAT_R8G8_UNORM,
444 VK_FORMAT_R8G8_SNORM,
445 VK_FORMAT_R8G8_USCALED,
446 VK_FORMAT_R8G8_SSCALED,
450 VK_FORMAT_R8G8B8_UNORM,
451 VK_FORMAT_R8G8B8_SNORM,
452 VK_FORMAT_R8G8B8_USCALED,
453 VK_FORMAT_R8G8B8_SSCALED,
454 VK_FORMAT_R8G8B8_UINT,
455 VK_FORMAT_R8G8B8_SINT,
456 VK_FORMAT_R8G8B8_SRGB,
457 VK_FORMAT_R8G8B8A8_UNORM,
458 VK_FORMAT_R8G8B8A8_SNORM,
459 VK_FORMAT_R8G8B8A8_USCALED,
460 VK_FORMAT_R8G8B8A8_SSCALED,
461 VK_FORMAT_R8G8B8A8_UINT,
462 VK_FORMAT_R8G8B8A8_SINT,
463 VK_FORMAT_R8G8B8A8_SRGB,
464 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
465 VK_FORMAT_A2R10G10B10_UINT_PACK32,
466 VK_FORMAT_A2R10G10B10_USCALED_PACK32,
469 VK_FORMAT_R16_USCALED,
470 VK_FORMAT_R16_SSCALED,
473 VK_FORMAT_R16_SFLOAT,
474 VK_FORMAT_R16G16_UNORM,
475 VK_FORMAT_R16G16_SNORM,
476 VK_FORMAT_R16G16_USCALED,
477 VK_FORMAT_R16G16_SSCALED,
478 VK_FORMAT_R16G16_UINT,
479 VK_FORMAT_R16G16_SINT,
480 VK_FORMAT_R16G16_SFLOAT,
481 VK_FORMAT_R16G16B16_UNORM,
482 VK_FORMAT_R16G16B16_SNORM,
483 VK_FORMAT_R16G16B16_USCALED,
484 VK_FORMAT_R16G16B16_SSCALED,
485 VK_FORMAT_R16G16B16_UINT,
486 VK_FORMAT_R16G16B16_SINT,
487 VK_FORMAT_R16G16B16_SFLOAT,
488 VK_FORMAT_R16G16B16A16_UNORM,
489 VK_FORMAT_R16G16B16A16_SNORM,
490 VK_FORMAT_R16G16B16A16_USCALED,
491 VK_FORMAT_R16G16B16A16_SSCALED,
492 VK_FORMAT_R16G16B16A16_UINT,
493 VK_FORMAT_R16G16B16A16_SINT,
494 VK_FORMAT_R16G16B16A16_SFLOAT,
497 VK_FORMAT_R32_SFLOAT,
498 VK_FORMAT_R32G32_UINT,
499 VK_FORMAT_R32G32_SINT,
500 VK_FORMAT_R32G32_SFLOAT,
501 VK_FORMAT_R32G32B32_UINT,
502 VK_FORMAT_R32G32B32_SINT,
503 VK_FORMAT_R32G32B32_SFLOAT,
504 VK_FORMAT_R32G32B32A32_UINT,
505 VK_FORMAT_R32G32B32A32_SINT,
506 VK_FORMAT_R32G32B32A32_SFLOAT,
507 VK_FORMAT_B10G11R11_UFLOAT_PACK32,
508 VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
509 VK_FORMAT_B4G4R4A4_UNORM_PACK16,
510 VK_FORMAT_B5G5R5A1_UNORM_PACK16,
512 // Compressed formats
513 VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
514 VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
515 VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
516 VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
517 VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
518 VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
519 VK_FORMAT_EAC_R11_UNORM_BLOCK,
520 VK_FORMAT_EAC_R11_SNORM_BLOCK,
521 VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
522 VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
523 VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
524 VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
525 VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
526 VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
527 VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
528 VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
529 VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
530 VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
531 VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
532 VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
533 VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
534 VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
535 VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
536 VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
537 VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
538 VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
539 VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
540 VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
541 VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
542 VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
543 VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
544 VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
545 VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
546 VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
547 VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
548 VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
549 VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
550 VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
553 de::MovePtr<tcu::TestCaseGroup> imageTests (new tcu::TestCaseGroup(testCtx, "image", "Image tests"));
554 de::MovePtr<tcu::TestCaseGroup> viewTypeTests (new tcu::TestCaseGroup(testCtx, "view_type", ""));
556 for (int viewTypeNdx = 0; viewTypeNdx < DE_LENGTH_OF_ARRAY(imageViewTypes); viewTypeNdx++)
558 const VkImageViewType viewType = imageViewTypes[viewTypeNdx].type;
559 de::MovePtr<tcu::TestCaseGroup> viewTypeGroup (new tcu::TestCaseGroup(testCtx, imageViewTypes[viewTypeNdx].name, (std::string("Uses a ") + imageViewTypes[viewTypeNdx].name + " view").c_str()));
560 de::MovePtr<tcu::TestCaseGroup> formatTests (new tcu::TestCaseGroup(testCtx, "format", "Tests samplable formats"));
562 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
564 const VkFormat format = formats[formatNdx];
566 if (isCompressedFormat(format))
568 // Do not use compressed formats with 1D and 1D array textures.
569 if (viewType == VK_IMAGE_VIEW_TYPE_1D || viewType == VK_IMAGE_VIEW_TYPE_1D_ARRAY)
572 // 3D ASTC textures are not supported.
573 if (tcu::isAstcFormat(mapVkCompressedFormat(format)) && viewType == VK_IMAGE_VIEW_TYPE_3D)
577 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx,
578 getFormatCaseName(format).c_str(),
579 (std::string("Samples a texture of format ") + getFormatName(format)).c_str()));
581 de::MovePtr<tcu::TestCaseGroup> sizeTests = createImageSizeTests(testCtx, viewType, format);
583 formatGroup->addChild(sizeTests.release());
584 formatTests->addChild(formatGroup.release());
587 viewTypeGroup->addChild(formatTests.release());
588 viewTypeTests->addChild(viewTypeGroup.release());
591 imageTests->addChild(viewTypeTests.release());
593 return imageTests.release();