1/*------------------------------------------------------------------------ 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2015 The Khronos Group Inc. 6 * Copyright (c) 2015 Imagination Technologies Ltd. 7 * Copyright (c) 2023 LunarG, Inc. 8 * Copyright (c) 2023 Nintendo 9 * 10 * Licensed under the Apache License, Version 2.0 (the "License"); 11 * you may not use this file except in compliance with the License. 12 * You may obtain a copy of the License at 13 * 14 * http://www.apache.org/licenses/LICENSE-2.0 15 * 16 * Unless required by applicable law or agreed to in writing, software 17 * distributed under the License is distributed on an "AS IS" BASIS, 18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 * See the License for the specific language governing permissions and 20 * limitations under the License. 21 * 22 *//*! 23 * \file 24 * \brief Image Tests 25 *//*--------------------------------------------------------------------*/ 26 27#include "vktPipelineImageTests.hpp" 28#include "vktPipelineImageSamplingInstance.hpp" 29#include "vktPipelineImageUtil.hpp" 30#include "vktPipelineVertexUtil.hpp" 31#include "vktTestCase.hpp" 32#include "vkImageUtil.hpp" 33#include "vkPrograms.hpp" 34#include "tcuTextureUtil.hpp" 35#include "deStringUtil.hpp" 36 37#include <sstream> 38#include <vector> 39 40namespace vkt 41{ 42namespace pipeline 43{ 44 45using namespace vk; 46using de::MovePtr; 47 48namespace 49{ 50 51class ImageTest : public vkt::TestCase 52{ 53public: 54 ImageTest (tcu::TestContext& testContext, 55 const char* name, 56 AllocationKind allocationKind, 57 PipelineConstructionType pipelineConstructionType, 58 VkDescriptorType samplingType, 59 VkImageViewType imageViewType, 60 VkFormat imageFormat, 61 const tcu::IVec3& imageSize, 62 int imageCount, 63 int arraySize, 64 bool pipelineProtectedAccess, 65 bool pipelineProtectedFlag); 66 67 ImageSamplingInstanceParams getImageSamplingInstanceParams (AllocationKind allocationKind, 68 VkDescriptorType samplingType, 69 VkImageViewType imageViewType, 70 VkFormat imageFormat, 71 const tcu::IVec3& imageSize, 72 int imageCount, 73 int arraySize) const; 74 75 virtual void initPrograms (SourceCollections& sourceCollections) const; 76 virtual void checkSupport (Context& context) const; 77 virtual TestInstance* createInstance (Context& context) const; 78 static std::string getGlslSamplerType (const tcu::TextureFormat& format, VkImageViewType type); 79 static std::string getGlslTextureType (const tcu::TextureFormat& format, VkImageViewType type); 80 static std::string getGlslSamplerDecl (int imageCount); 81 static std::string getGlslTextureDecl (int imageCount); 82 static std::string getGlslFragColorDecl (int imageCount); 83 static std::string getGlslSampler (const tcu::TextureFormat& format, 84 VkImageViewType type, 85 VkDescriptorType samplingType, 86 int imageCount); 87 88private: 89 AllocationKind m_allocationKind; 90 PipelineConstructionType m_pipelineConstructionType; 91 VkDescriptorType m_samplingType; 92 VkImageViewType m_imageViewType; 93 VkFormat m_imageFormat; 94 tcu::IVec3 m_imageSize; 95 int m_imageCount; 96 int m_arraySize; 97 bool m_pipelineProtectedAccess; 98 bool m_pipelineProtectedFlag; 99}; 100 101ImageTest::ImageTest (tcu::TestContext& testContext, 102 const char* name, 103 AllocationKind allocationKind, 104 PipelineConstructionType pipelineConstructionType, 105 VkDescriptorType samplingType, 106 VkImageViewType imageViewType, 107 VkFormat imageFormat, 108 const tcu::IVec3& imageSize, 109 int imageCount, 110 int arraySize, 111 bool pipelineProtectedAccess, 112 bool pipelineProtectedFlag) 113 114 : vkt::TestCase (testContext, name) 115 , m_allocationKind (allocationKind) 116 , m_pipelineConstructionType (pipelineConstructionType) 117 , m_samplingType (samplingType) 118 , m_imageViewType (imageViewType) 119 , m_imageFormat (imageFormat) 120 , m_imageSize (imageSize) 121 , m_imageCount (imageCount) 122 , m_arraySize (arraySize) 123 , m_pipelineProtectedAccess (pipelineProtectedAccess) 124 , m_pipelineProtectedFlag (pipelineProtectedFlag) 125{ 126} 127 128void ImageTest::checkSupport (Context& context) const 129{ 130 // Using a loop to index into an array of images requires shaderSampledImageArrayDynamicIndexing 131 if (m_imageCount > 1) 132 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SHADER_SAMPLED_IMAGE_ARRAY_DYNAMIC_INDEXING); 133 134#ifndef CTS_USES_VULKANSC 135 if (m_imageFormat == VK_FORMAT_A8_UNORM_KHR || m_imageFormat == VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR) 136 context.requireDeviceFunctionality("VK_KHR_maintenance5"); 137#endif // CTS_USES_VULKANSC 138 139 checkPipelineConstructionRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), m_pipelineConstructionType); 140 checkSupportImageSamplingInstance(context, getImageSamplingInstanceParams(m_allocationKind, m_samplingType, m_imageViewType, m_imageFormat, m_imageSize, m_imageCount, m_arraySize)); 141 142 if (m_pipelineProtectedAccess) 143 { 144#ifndef CTS_USES_VULKANSC 145 context.requireDeviceFunctionality("VK_EXT_pipeline_protected_access"); 146 147 if (!context.getPipelineProtectedAccessFeaturesEXT().pipelineProtectedAccess) 148 { 149 throw tcu::NotSupportedError("pipelineProtectedAccess feature is not supported"); 150 } 151#else // CTS_USES_VULKANSC 152 throw tcu::NotSupportedError("pipeline protected access is not supported"); 153#endif // CTS_USES_VULKANSC 154 } 155} 156 157ImageSamplingInstanceParams ImageTest::getImageSamplingInstanceParams (AllocationKind allocationKind, 158 VkDescriptorType samplingType, 159 VkImageViewType imageViewType, 160 VkFormat imageFormat, 161 const tcu::IVec3& imageSize, 162 int imageCount, 163 int arraySize) const 164{ 165 tcu::UVec2 renderSize; 166 167 if (imageViewType == VK_IMAGE_VIEW_TYPE_1D || imageViewType == VK_IMAGE_VIEW_TYPE_2D) 168 { 169 renderSize = tcu::UVec2((deUint32)imageSize.x(), (deUint32)imageSize.y()); 170 } 171 else 172 { 173 // Draw a 3x2 grid of texture layers 174 renderSize = tcu::UVec2((deUint32)imageSize.x() * 3, (deUint32)imageSize.y() * 2); 175 } 176 177 const bool separateStencilUsage = false; 178 const std::vector<Vertex4Tex4> vertices = createTestQuadMosaic(imageViewType); 179 const VkComponentMapping componentMapping = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; 180 const VkImageSubresourceRange subresourceRange = 181 { 182 VK_IMAGE_ASPECT_COLOR_BIT, 183 0u, 184 (deUint32)deLog2Floor32(deMax32(imageSize.x(), deMax32(imageSize.y(), imageSize.z()))) + 1, 185 0u, 186 (deUint32)arraySize, 187 }; 188 189 const VkSamplerCreateInfo samplerParams = 190 { 191 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType; 192 DE_NULL, // const void* pNext; 193 0u, // VkSamplerCreateFlags flags; 194 VK_FILTER_NEAREST, // VkFilter magFilter; 195 VK_FILTER_NEAREST, // VkFilter minFilter; 196 VK_SAMPLER_MIPMAP_MODE_NEAREST, // VkSamplerMipmapMode mipmapMode; 197 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeU; 198 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeV; 199 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeW; 200 0.0f, // float mipLodBias; 201 VK_FALSE, // VkBool32 anisotropyEnable; 202 1.0f, // float maxAnisotropy; 203 false, // VkBool32 compareEnable; 204 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp; 205 0.0f, // float minLod; 206 (float)(subresourceRange.levelCount - 1), // float maxLod; 207 getFormatBorderColor(BORDER_COLOR_TRANSPARENT_BLACK, imageFormat, false), // VkBorderColor borderColor; 208 false // VkBool32 unnormalizedCoordinates; 209 }; 210 211#ifdef CTS_USES_VULKANSC 212 const vk::VkPipelineCreateFlags pipelineFlags = (vk::VkPipelineCreateFlagBits)0u; 213 (void)m_pipelineProtectedFlag; 214#else // CTS_USES_VULKANSC 215 const vk::VkPipelineCreateFlags pipelineFlags = m_pipelineProtectedFlag ? vk::VK_PIPELINE_CREATE_NO_PROTECTED_ACCESS_BIT_EXT : (vk::VkPipelineCreateFlagBits)0u; 216#endif // CTS_USES_VULKANSC 217 218 return ImageSamplingInstanceParams(m_pipelineConstructionType, renderSize, imageViewType, imageFormat, imageSize, arraySize, componentMapping, subresourceRange, samplerParams, 0.0f, vertices, separateStencilUsage, samplingType, imageCount, allocationKind, vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, pipelineFlags); 219} 220 221void ImageTest::initPrograms (SourceCollections& sourceCollections) const 222{ 223 std::ostringstream vertexSrc; 224 std::ostringstream fragmentSrc; 225 const char* texCoordSwizzle = DE_NULL; 226 const tcu::TextureFormat format = (isCompressedFormat(m_imageFormat)) ? tcu::getUncompressedFormat(mapVkCompressedFormat(m_imageFormat)) 227 : mapVkFormat(m_imageFormat); 228 229 tcu::Vec4 lookupScale; 230 tcu::Vec4 lookupBias; 231 232 getLookupScaleBias(m_imageFormat, lookupScale, lookupBias); 233 234 switch (m_imageViewType) 235 { 236 case VK_IMAGE_VIEW_TYPE_1D: 237 texCoordSwizzle = "x"; 238 break; 239 case VK_IMAGE_VIEW_TYPE_1D_ARRAY: 240 case VK_IMAGE_VIEW_TYPE_2D: 241 texCoordSwizzle = "xy"; 242 break; 243 case VK_IMAGE_VIEW_TYPE_2D_ARRAY: 244 case VK_IMAGE_VIEW_TYPE_3D: 245 case VK_IMAGE_VIEW_TYPE_CUBE: 246 texCoordSwizzle = "xyz"; 247 break; 248 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: 249 texCoordSwizzle = "xyzw"; 250 break; 251 default: 252 DE_ASSERT(false); 253 break; 254 } 255 256 vertexSrc << "#version 440\n" 257 << "layout(location = 0) in vec4 position;\n" 258 << "layout(location = 1) in vec4 texCoords;\n" 259 << "layout(location = 0) out highp vec4 vtxTexCoords;\n" 260 << "out gl_PerVertex {\n" 261 << " vec4 gl_Position;\n" 262 << "};\n" 263 << "void main (void)\n" 264 << "{\n" 265 << " gl_Position = position;\n" 266 << " vtxTexCoords = texCoords;\n" 267 << "}\n"; 268 269 fragmentSrc << "#version 440\n"; 270 switch (m_samplingType) 271 { 272 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: 273 fragmentSrc 274 << "layout(set = 0, binding = 0) uniform highp sampler texSampler;\n" 275 << "layout(set = 0, binding = 1) uniform highp " << getGlslTextureType(format, m_imageViewType) << " " << getGlslTextureDecl(m_imageCount) << ";\n"; 276 break; 277 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: 278 default: 279 fragmentSrc 280 << "layout(set = 0, binding = 0) uniform highp " << getGlslSamplerType(format, m_imageViewType) << " " << getGlslSamplerDecl(m_imageCount) << ";\n"; 281 } 282 fragmentSrc << "layout(location = 0) in highp vec4 vtxTexCoords;\n" 283 << "layout(location = 0) out highp vec4 " << getGlslFragColorDecl(m_imageCount) << ";\n" 284 << "void main (void)\n" 285 << "{\n"; 286 if (m_imageCount > 1) 287 fragmentSrc 288 << " for (uint i = 0; i < " << m_imageCount << "; ++i)\n" 289 << " fragColors[i] = (texture(" << getGlslSampler(format, m_imageViewType, m_samplingType, m_imageCount) << ", vtxTexCoords." << texCoordSwizzle << std::scientific << ") * vec4" << lookupScale << ") + vec4" << lookupBias << "; \n"; 290 else 291 fragmentSrc 292 << " fragColor = (texture(" << getGlslSampler(format, m_imageViewType, m_samplingType, m_imageCount) << ", vtxTexCoords." << texCoordSwizzle << std::scientific << ") * vec4" << lookupScale << ") + vec4" << lookupBias << "; \n"; 293 fragmentSrc << "}\n"; 294 295 sourceCollections.glslSources.add("tex_vert") << glu::VertexSource(vertexSrc.str()); 296 sourceCollections.glslSources.add("tex_frag") << glu::FragmentSource(fragmentSrc.str()); 297} 298 299TestInstance* ImageTest::createInstance (Context& context) const 300{ 301 return new ImageSamplingInstance(context, getImageSamplingInstanceParams(m_allocationKind, m_samplingType, m_imageViewType, m_imageFormat, m_imageSize, m_imageCount, m_arraySize)); 302} 303 304std::string ImageTest::getGlslSamplerType (const tcu::TextureFormat& format, VkImageViewType type) 305{ 306 std::ostringstream samplerType; 307 308 if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER) 309 samplerType << "u"; 310 else if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER) 311 samplerType << "i"; 312 313 switch (type) 314 { 315 case VK_IMAGE_VIEW_TYPE_1D: 316 samplerType << "sampler1D"; 317 break; 318 319 case VK_IMAGE_VIEW_TYPE_1D_ARRAY: 320 samplerType << "sampler1DArray"; 321 break; 322 323 case VK_IMAGE_VIEW_TYPE_2D: 324 samplerType << "sampler2D"; 325 break; 326 327 case VK_IMAGE_VIEW_TYPE_2D_ARRAY: 328 samplerType << "sampler2DArray"; 329 break; 330 331 case VK_IMAGE_VIEW_TYPE_3D: 332 samplerType << "sampler3D"; 333 break; 334 335 case VK_IMAGE_VIEW_TYPE_CUBE: 336 samplerType << "samplerCube"; 337 break; 338 339 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: 340 samplerType << "samplerCubeArray"; 341 break; 342 343 default: 344 DE_FATAL("Unknown image view type"); 345 break; 346 } 347 348 return samplerType.str(); 349} 350 351std::string ImageTest::getGlslTextureType (const tcu::TextureFormat& format, VkImageViewType type) 352{ 353 std::ostringstream textureType; 354 355 if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER) 356 textureType << "u"; 357 else if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER) 358 textureType << "i"; 359 360 switch (type) 361 { 362 case VK_IMAGE_VIEW_TYPE_1D: 363 textureType << "texture1D"; 364 break; 365 366 case VK_IMAGE_VIEW_TYPE_1D_ARRAY: 367 textureType << "texture1DArray"; 368 break; 369 370 case VK_IMAGE_VIEW_TYPE_2D: 371 textureType << "texture2D"; 372 break; 373 374 case VK_IMAGE_VIEW_TYPE_2D_ARRAY: 375 textureType << "texture2DArray"; 376 break; 377 378 case VK_IMAGE_VIEW_TYPE_3D: 379 textureType << "texture3D"; 380 break; 381 382 case VK_IMAGE_VIEW_TYPE_CUBE: 383 textureType << "textureCube"; 384 break; 385 386 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: 387 textureType << "textureCubeArray"; 388 break; 389 390 default: 391 DE_FATAL("Unknown image view type"); 392 } 393 394 return textureType.str(); 395} 396 397std::string ImageTest::getGlslSamplerDecl (int imageCount) 398{ 399 std::ostringstream samplerArray; 400 samplerArray << "texSamplers[" << imageCount << "]"; 401 402 return imageCount > 1 ? samplerArray.str() : "texSampler"; 403} 404 405std::string ImageTest::getGlslTextureDecl (int imageCount) 406{ 407 std::ostringstream textureArray; 408 textureArray << "texImages[" << imageCount << "]"; 409 410 return imageCount > 1 ? textureArray.str() : "texImage"; 411} 412 413std::string ImageTest::getGlslFragColorDecl (int imageCount) 414{ 415 std::ostringstream samplerArray; 416 samplerArray << "fragColors[" << imageCount << "]"; 417 418 return imageCount > 1 ? samplerArray.str() : "fragColor"; 419} 420 421std::string ImageTest::getGlslSampler (const tcu::TextureFormat& format, VkImageViewType type, VkDescriptorType samplingType, int imageCount) 422{ 423 std::string texSampler = imageCount > 1 ? "texSamplers[i]" : "texSampler"; 424 std::string texImage = imageCount > 1 ? "texImages[i]" : "texImage"; 425 426 switch (samplingType) 427 { 428 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: 429 return getGlslSamplerType(format, type) + "(" + texImage + ", texSampler)"; 430 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: 431 default: 432 return texSampler; 433 } 434} 435 436std::string getFormatCaseName (const VkFormat format) 437{ 438 const std::string fullName = getFormatName(format); 439 440 DE_ASSERT(de::beginsWith(fullName, "VK_FORMAT_")); 441 442 return de::toLower(fullName.substr(10)); 443} 444 445std::string getSizeName (VkImageViewType viewType, const tcu::IVec3& size, int arraySize, bool pipelineProtectedAccess, bool pipelineProtectedFlag) 446{ 447 std::ostringstream caseName; 448 449 if (pipelineProtectedAccess) { 450 caseName << "pipeline_protected_access_"; 451 } 452 if (pipelineProtectedFlag) { 453 caseName << "pipeline_protected_flag_"; 454 } 455 456 switch (viewType) 457 { 458 case VK_IMAGE_VIEW_TYPE_1D: 459 case VK_IMAGE_VIEW_TYPE_2D: 460 case VK_IMAGE_VIEW_TYPE_CUBE: 461 caseName << size.x() << "x" << size.y(); 462 break; 463 464 case VK_IMAGE_VIEW_TYPE_3D: 465 caseName << size.x() << "x" << size.y() << "x" << size.z(); 466 break; 467 468 case VK_IMAGE_VIEW_TYPE_1D_ARRAY: 469 case VK_IMAGE_VIEW_TYPE_2D_ARRAY: 470 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: 471 caseName << size.x() << "x" << size.y() << "_array_of_" << arraySize; 472 break; 473 474 default: 475 DE_ASSERT(false); 476 break; 477 } 478 479 return caseName.str(); 480} 481 482de::MovePtr<tcu::TestCaseGroup> createImageSizeTests (tcu::TestContext& testCtx, AllocationKind allocationKind, PipelineConstructionType pipelineConstructionType, VkDescriptorType samplingType, VkImageViewType imageViewType, VkFormat imageFormat, int imageCount) 483{ 484 using tcu::IVec3; 485 486 std::vector<IVec3> imageSizes; 487 std::vector<int> arraySizes; 488 de::MovePtr<tcu::TestCaseGroup> imageSizeTests (new tcu::TestCaseGroup(testCtx, "size")); 489 490 const bool pipelineProtectedAccess[] = { 491 false, 492#ifndef CTS_USES_VULKANSC 493 true, 494#endif 495 }; 496 const bool pipelineProtectedFlag[] = { 497 false, 498#ifndef CTS_USES_VULKANSC 499 true, 500#endif 501 }; 502 503 // Select image imageSizes 504 switch (imageViewType) 505 { 506 case VK_IMAGE_VIEW_TYPE_1D: 507 case VK_IMAGE_VIEW_TYPE_1D_ARRAY: 508 // POT 509 if (imageCount == 1) 510 { 511 imageSizes.push_back(IVec3(1, 1, 1)); 512 imageSizes.push_back(IVec3(2, 1, 1)); 513 imageSizes.push_back(IVec3(32, 1, 1)); 514 imageSizes.push_back(IVec3(128, 1, 1)); 515 } 516 imageSizes.push_back(IVec3(512, 1, 1)); 517 518 // NPOT 519 if (imageCount == 1) 520 { 521 imageSizes.push_back(IVec3(3, 1, 1)); 522 imageSizes.push_back(IVec3(13, 1, 1)); 523 imageSizes.push_back(IVec3(127, 1, 1)); 524 } 525 imageSizes.push_back(IVec3(443, 1, 1)); 526 break; 527 528 case VK_IMAGE_VIEW_TYPE_2D: 529 case VK_IMAGE_VIEW_TYPE_2D_ARRAY: 530 if (imageCount == 1) 531 { 532 // POT 533 imageSizes.push_back(IVec3(1, 1, 1)); 534 imageSizes.push_back(IVec3(2, 2, 1)); 535 imageSizes.push_back(IVec3(32, 32, 1)); 536 537 // NPOT 538 imageSizes.push_back(IVec3(3, 3, 1)); 539 imageSizes.push_back(IVec3(13, 13, 1)); 540 } 541 542 // POT rectangular 543 if (imageCount == 1) 544 imageSizes.push_back(IVec3(8, 16, 1)); 545 imageSizes.push_back(IVec3(32, 16, 1)); 546 547 // NPOT rectangular 548 imageSizes.push_back(IVec3(13, 23, 1)); 549 if (imageCount == 1) 550 imageSizes.push_back(IVec3(23, 8, 1)); 551 break; 552 553 case VK_IMAGE_VIEW_TYPE_3D: 554 // POT cube 555 if (imageCount == 1) 556 { 557 imageSizes.push_back(IVec3(1, 1, 1)); 558 imageSizes.push_back(IVec3(2, 2, 2)); 559 } 560 imageSizes.push_back(IVec3(16, 16, 16)); 561 562 // NPOT cube 563 if (imageCount == 1) 564 { 565 imageSizes.push_back(IVec3(3, 3, 3)); 566 imageSizes.push_back(IVec3(5, 5, 5)); 567 } 568 imageSizes.push_back(IVec3(11, 11, 11)); 569 570 // POT non-cube 571 if (imageCount == 1) 572 imageSizes.push_back(IVec3(32, 16, 8)); 573 imageSizes.push_back(IVec3(8, 16, 32)); 574 575 // NPOT non-cube 576 imageSizes.push_back(IVec3(17, 11, 5)); 577 if (imageCount == 1) 578 imageSizes.push_back(IVec3(5, 11, 17)); 579 break; 580 581 case VK_IMAGE_VIEW_TYPE_CUBE: 582 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: 583 // POT 584 imageSizes.push_back(IVec3(32, 32, 1)); 585 586 // NPOT 587 imageSizes.push_back(IVec3(13, 13, 1)); 588 break; 589 590 default: 591 DE_ASSERT(false); 592 break; 593 } 594 595 // Select array sizes 596 switch (imageViewType) 597 { 598 case VK_IMAGE_VIEW_TYPE_1D_ARRAY: 599 case VK_IMAGE_VIEW_TYPE_2D_ARRAY: 600 if (imageCount == 1) 601 arraySizes.push_back(3); 602 arraySizes.push_back(6); 603 break; 604 605 case VK_IMAGE_VIEW_TYPE_CUBE: 606 arraySizes.push_back(6); 607 break; 608 609 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: 610 if (imageCount == 1) 611 arraySizes.push_back(6); 612 arraySizes.push_back(6 * 6); 613 break; 614 615 default: 616 arraySizes.push_back(1); 617 break; 618 } 619 620 for (size_t protectedNdx = 0; protectedNdx < DE_LENGTH_OF_ARRAY(pipelineProtectedAccess); ++protectedNdx) { 621 for (size_t flagNdx = 0; flagNdx < DE_LENGTH_OF_ARRAY(pipelineProtectedAccess); ++flagNdx) { 622 if (!pipelineProtectedAccess[protectedNdx] && pipelineProtectedFlag[flagNdx]) continue; 623 624 for (size_t sizeNdx = 0; sizeNdx < imageSizes.size(); sizeNdx++) 625 { 626 for (size_t arraySizeNdx = 0; arraySizeNdx < arraySizes.size(); arraySizeNdx++) 627 { 628 imageSizeTests->addChild(new ImageTest(testCtx, 629 getSizeName(imageViewType, imageSizes[sizeNdx], arraySizes[arraySizeNdx], pipelineProtectedAccess[protectedNdx], pipelineProtectedFlag[flagNdx]).c_str(), 630 allocationKind, 631 pipelineConstructionType, 632 samplingType, 633 imageViewType, 634 imageFormat, 635 imageSizes[sizeNdx], 636 imageCount, 637 arraySizes[arraySizeNdx], 638 pipelineProtectedAccess[protectedNdx], 639 pipelineProtectedFlag[flagNdx])); 640 } 641 } 642 } 643 } 644 645 return imageSizeTests; 646} 647 648void createImageCountTests (tcu::TestCaseGroup* parentGroup, tcu::TestContext& testCtx, AllocationKind allocationKind, PipelineConstructionType pipelineConstructionType, VkDescriptorType samplingType, VkImageViewType imageViewType, VkFormat imageFormat) 649{ 650 const int coreImageCounts[] = { 1, 4, 8 }; 651 const int dedicatedAllocationImageCounts[] = { 1 }; 652 const int* imageCounts = (allocationKind == ALLOCATION_KIND_DEDICATED) 653 ? dedicatedAllocationImageCounts 654 : coreImageCounts; 655 const size_t imageCountsLength = (allocationKind == ALLOCATION_KIND_DEDICATED) 656 ? DE_LENGTH_OF_ARRAY(dedicatedAllocationImageCounts) 657 : DE_LENGTH_OF_ARRAY(coreImageCounts); 658 659 for (size_t countNdx = 0; countNdx < imageCountsLength; countNdx++) 660 { 661 std::ostringstream caseName; 662 caseName << "count_" << imageCounts[countNdx]; 663 de::MovePtr<tcu::TestCaseGroup> countGroup(new tcu::TestCaseGroup(testCtx, caseName.str().c_str())); 664 de::MovePtr<tcu::TestCaseGroup> sizeTests = createImageSizeTests(testCtx, allocationKind, pipelineConstructionType, samplingType, imageViewType, imageFormat, imageCounts[countNdx]); 665 666 countGroup->addChild(sizeTests.release()); 667 parentGroup->addChild(countGroup.release()); 668 } 669} 670 671de::MovePtr<tcu::TestCaseGroup> createImageFormatTests (tcu::TestContext& testCtx, AllocationKind allocationKind, PipelineConstructionType pipelineConstructionType, VkDescriptorType samplingType, VkImageViewType imageViewType) 672{ 673 // All supported dEQP formats that are not intended for depth or stencil. 674 const VkFormat coreFormats[] = 675 { 676 VK_FORMAT_R4G4_UNORM_PACK8, 677 VK_FORMAT_R4G4B4A4_UNORM_PACK16, 678 VK_FORMAT_R5G6B5_UNORM_PACK16, 679 VK_FORMAT_R5G5B5A1_UNORM_PACK16, 680 VK_FORMAT_R8_UNORM, 681 VK_FORMAT_R8_SNORM, 682 VK_FORMAT_R8_USCALED, 683 VK_FORMAT_R8_SSCALED, 684 VK_FORMAT_R8_UINT, 685 VK_FORMAT_R8_SINT, 686 VK_FORMAT_R8_SRGB, 687 VK_FORMAT_R8G8_UNORM, 688 VK_FORMAT_R8G8_SNORM, 689 VK_FORMAT_R8G8_USCALED, 690 VK_FORMAT_R8G8_SSCALED, 691 VK_FORMAT_R8G8_UINT, 692 VK_FORMAT_R8G8_SINT, 693 VK_FORMAT_R8G8_SRGB, 694 VK_FORMAT_R8G8B8_UNORM, 695 VK_FORMAT_R8G8B8_SNORM, 696 VK_FORMAT_R8G8B8_USCALED, 697 VK_FORMAT_R8G8B8_SSCALED, 698 VK_FORMAT_R8G8B8_UINT, 699 VK_FORMAT_R8G8B8_SINT, 700 VK_FORMAT_R8G8B8_SRGB, 701 VK_FORMAT_R8G8B8A8_UNORM, 702 VK_FORMAT_R8G8B8A8_SNORM, 703 VK_FORMAT_R8G8B8A8_USCALED, 704 VK_FORMAT_R8G8B8A8_SSCALED, 705 VK_FORMAT_R8G8B8A8_UINT, 706 VK_FORMAT_R8G8B8A8_SINT, 707 VK_FORMAT_R8G8B8A8_SRGB, 708 VK_FORMAT_A2R10G10B10_UNORM_PACK32, 709 VK_FORMAT_A2R10G10B10_UINT_PACK32, 710 VK_FORMAT_A2R10G10B10_USCALED_PACK32, 711 VK_FORMAT_A2B10G10R10_UNORM_PACK32, 712 VK_FORMAT_A2B10G10R10_UINT_PACK32, 713 VK_FORMAT_A1R5G5B5_UNORM_PACK16, 714#ifndef CTS_USES_VULKANSC 715 VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR, 716#endif // CTS_USES_VULKANSC 717 VK_FORMAT_R16_UNORM, 718 VK_FORMAT_R16_SNORM, 719 VK_FORMAT_R16_USCALED, 720 VK_FORMAT_R16_SSCALED, 721 VK_FORMAT_R16_UINT, 722 VK_FORMAT_R16_SINT, 723 VK_FORMAT_R16_SFLOAT, 724 VK_FORMAT_R16G16_UNORM, 725 VK_FORMAT_R16G16_SNORM, 726 VK_FORMAT_R16G16_USCALED, 727 VK_FORMAT_R16G16_SSCALED, 728 VK_FORMAT_R16G16_UINT, 729 VK_FORMAT_R16G16_SINT, 730 VK_FORMAT_R16G16_SFLOAT, 731 VK_FORMAT_R16G16B16_UNORM, 732 VK_FORMAT_R16G16B16_SNORM, 733 VK_FORMAT_R16G16B16_USCALED, 734 VK_FORMAT_R16G16B16_SSCALED, 735 VK_FORMAT_R16G16B16_UINT, 736 VK_FORMAT_R16G16B16_SINT, 737 VK_FORMAT_R16G16B16_SFLOAT, 738 VK_FORMAT_R16G16B16A16_UNORM, 739 VK_FORMAT_R16G16B16A16_SNORM, 740 VK_FORMAT_R16G16B16A16_USCALED, 741 VK_FORMAT_R16G16B16A16_SSCALED, 742 VK_FORMAT_R16G16B16A16_UINT, 743 VK_FORMAT_R16G16B16A16_SINT, 744 VK_FORMAT_R16G16B16A16_SFLOAT, 745 VK_FORMAT_R32_UINT, 746 VK_FORMAT_R32_SINT, 747 VK_FORMAT_R32_SFLOAT, 748 VK_FORMAT_R32G32_UINT, 749 VK_FORMAT_R32G32_SINT, 750 VK_FORMAT_R32G32_SFLOAT, 751 VK_FORMAT_R32G32B32_UINT, 752 VK_FORMAT_R32G32B32_SINT, 753 VK_FORMAT_R32G32B32_SFLOAT, 754 VK_FORMAT_R32G32B32A32_UINT, 755 VK_FORMAT_R32G32B32A32_SINT, 756 VK_FORMAT_R32G32B32A32_SFLOAT, 757 VK_FORMAT_B10G11R11_UFLOAT_PACK32, 758 VK_FORMAT_E5B9G9R9_UFLOAT_PACK32, 759 VK_FORMAT_B4G4R4A4_UNORM_PACK16, 760 VK_FORMAT_B5G5R5A1_UNORM_PACK16, 761 VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT, 762 VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT, 763#ifndef CTS_USES_VULKANSC 764 VK_FORMAT_A8_UNORM_KHR, 765#endif // CTS_USES_VULKANSC 766 767 // Compressed formats 768 VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, 769 VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK, 770 VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK, 771 VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK, 772 VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, 773 VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK, 774 VK_FORMAT_EAC_R11_UNORM_BLOCK, 775 VK_FORMAT_EAC_R11_SNORM_BLOCK, 776 VK_FORMAT_EAC_R11G11_UNORM_BLOCK, 777 VK_FORMAT_EAC_R11G11_SNORM_BLOCK, 778 VK_FORMAT_ASTC_4x4_UNORM_BLOCK, 779 VK_FORMAT_ASTC_4x4_SRGB_BLOCK, 780 VK_FORMAT_ASTC_5x4_UNORM_BLOCK, 781 VK_FORMAT_ASTC_5x4_SRGB_BLOCK, 782 VK_FORMAT_ASTC_5x5_UNORM_BLOCK, 783 VK_FORMAT_ASTC_5x5_SRGB_BLOCK, 784 VK_FORMAT_ASTC_6x5_UNORM_BLOCK, 785 VK_FORMAT_ASTC_6x5_SRGB_BLOCK, 786 VK_FORMAT_ASTC_6x6_UNORM_BLOCK, 787 VK_FORMAT_ASTC_6x6_SRGB_BLOCK, 788 VK_FORMAT_ASTC_8x5_UNORM_BLOCK, 789 VK_FORMAT_ASTC_8x5_SRGB_BLOCK, 790 VK_FORMAT_ASTC_8x6_UNORM_BLOCK, 791 VK_FORMAT_ASTC_8x6_SRGB_BLOCK, 792 VK_FORMAT_ASTC_8x8_UNORM_BLOCK, 793 VK_FORMAT_ASTC_8x8_SRGB_BLOCK, 794 VK_FORMAT_ASTC_10x5_UNORM_BLOCK, 795 VK_FORMAT_ASTC_10x5_SRGB_BLOCK, 796 VK_FORMAT_ASTC_10x6_UNORM_BLOCK, 797 VK_FORMAT_ASTC_10x6_SRGB_BLOCK, 798 VK_FORMAT_ASTC_10x8_UNORM_BLOCK, 799 VK_FORMAT_ASTC_10x8_SRGB_BLOCK, 800 VK_FORMAT_ASTC_10x10_UNORM_BLOCK, 801 VK_FORMAT_ASTC_10x10_SRGB_BLOCK, 802 VK_FORMAT_ASTC_12x10_UNORM_BLOCK, 803 VK_FORMAT_ASTC_12x10_SRGB_BLOCK, 804 VK_FORMAT_ASTC_12x12_UNORM_BLOCK, 805 VK_FORMAT_ASTC_12x12_SRGB_BLOCK, 806 }; 807 // Formats to test with dedicated allocation 808 const VkFormat dedicatedAllocationFormats[] = 809 { 810 VK_FORMAT_R8G8B8A8_UNORM, 811 VK_FORMAT_R16_SFLOAT, 812 }; 813 const VkFormat* formats = (allocationKind == ALLOCATION_KIND_DEDICATED) 814 ? dedicatedAllocationFormats 815 : coreFormats; 816 const size_t formatsLength = (allocationKind == ALLOCATION_KIND_DEDICATED) 817 ? DE_LENGTH_OF_ARRAY(dedicatedAllocationFormats) 818 : DE_LENGTH_OF_ARRAY(coreFormats); 819 820 de::MovePtr<tcu::TestCaseGroup> imageFormatTests(new tcu::TestCaseGroup(testCtx, "format")); 821 822 for (size_t formatNdx = 0; formatNdx < formatsLength; formatNdx++) 823 { 824 const VkFormat format = formats[formatNdx]; 825 826 if (isCompressedFormat(format)) 827 { 828 // Do not use compressed formats with 1D and 1D array textures. 829 if (imageViewType == VK_IMAGE_VIEW_TYPE_1D || imageViewType == VK_IMAGE_VIEW_TYPE_1D_ARRAY) 830 break; 831 } 832 833 de::MovePtr<tcu::TestCaseGroup> formatGroup(new tcu::TestCaseGroup(testCtx, 834 getFormatCaseName(format).c_str(), 835 (std::string("Samples a texture of format ") + getFormatName(format)).c_str())); 836 createImageCountTests(formatGroup.get(), testCtx, allocationKind, pipelineConstructionType, samplingType, imageViewType, format); 837 838 imageFormatTests->addChild(formatGroup.release()); 839 } 840 841 return imageFormatTests; 842} 843 844de::MovePtr<tcu::TestCaseGroup> createImageViewTypeTests (tcu::TestContext& testCtx, AllocationKind allocationKind, PipelineConstructionType pipelineConstructionType, VkDescriptorType samplingType) 845{ 846 const struct 847 { 848 VkImageViewType type; 849 const char* name; 850 } 851 imageViewTypes[] = 852 { 853 { VK_IMAGE_VIEW_TYPE_1D, "1d" }, 854 { VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array" }, 855 { VK_IMAGE_VIEW_TYPE_2D, "2d" }, 856 { VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array" }, 857 { VK_IMAGE_VIEW_TYPE_3D, "3d" }, 858 { VK_IMAGE_VIEW_TYPE_CUBE, "cube" }, 859 { VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array" } 860 }; 861 862 de::MovePtr<tcu::TestCaseGroup> imageViewTypeTests(new tcu::TestCaseGroup(testCtx, "view_type")); 863 864 for (int viewTypeNdx = 0; viewTypeNdx < DE_LENGTH_OF_ARRAY(imageViewTypes); viewTypeNdx++) 865 { 866 const VkImageViewType viewType = imageViewTypes[viewTypeNdx].type; 867 de::MovePtr<tcu::TestCaseGroup> viewTypeGroup(new tcu::TestCaseGroup(testCtx, imageViewTypes[viewTypeNdx].name)); 868 de::MovePtr<tcu::TestCaseGroup> formatTests = createImageFormatTests(testCtx, allocationKind, pipelineConstructionType, samplingType, viewType); 869 870 viewTypeGroup->addChild(formatTests.release()); 871 imageViewTypeTests->addChild(viewTypeGroup.release()); 872 } 873 874 return imageViewTypeTests; 875} 876 877de::MovePtr<tcu::TestCaseGroup> createImageSamplingTypeTests (tcu::TestContext& testCtx, AllocationKind allocationKind, PipelineConstructionType pipelineConstructionType) 878{ 879 VkDescriptorType samplingTypes[] = 880 { 881 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 882 VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE 883 }; 884 885 de::MovePtr<tcu::TestCaseGroup> imageSamplingTypeTests(new tcu::TestCaseGroup(testCtx, "sampling_type")); 886 887 for (int smpTypeNdx = 0; smpTypeNdx < DE_LENGTH_OF_ARRAY(samplingTypes); smpTypeNdx++) 888 { 889 const char* smpTypeName = samplingTypes[smpTypeNdx] == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER ? "combined" : "separate"; 890 de::MovePtr<tcu::TestCaseGroup> samplingTypeGroup(new tcu::TestCaseGroup(testCtx, smpTypeName)); 891 de::MovePtr<tcu::TestCaseGroup> viewTypeTests = createImageViewTypeTests(testCtx, allocationKind, pipelineConstructionType, samplingTypes[smpTypeNdx]); 892 893 samplingTypeGroup->addChild(viewTypeTests.release()); 894 imageSamplingTypeTests->addChild(samplingTypeGroup.release()); 895 } 896 897 return imageSamplingTypeTests; 898} 899 900de::MovePtr<tcu::TestCaseGroup> createSuballocationTests(tcu::TestContext& testCtx, PipelineConstructionType pipelineConstructionType) 901{ 902 de::MovePtr<tcu::TestCaseGroup> suballocationTestsGroup(new tcu::TestCaseGroup(testCtx, "suballocation")); 903 de::MovePtr<tcu::TestCaseGroup> samplingTypeTests = createImageSamplingTypeTests(testCtx, ALLOCATION_KIND_SUBALLOCATED, pipelineConstructionType); 904 905 suballocationTestsGroup->addChild(samplingTypeTests.release()); 906 907 return suballocationTestsGroup; 908} 909 910de::MovePtr<tcu::TestCaseGroup> createDedicatedAllocationTests(tcu::TestContext& testCtx, PipelineConstructionType pipelineConstructionType) 911{ 912 de::MovePtr<tcu::TestCaseGroup> dedicatedAllocationTestsGroup(new tcu::TestCaseGroup(testCtx, "dedicated_allocation")); 913 de::MovePtr<tcu::TestCaseGroup> samplingTypeTests = createImageSamplingTypeTests(testCtx, ALLOCATION_KIND_DEDICATED, pipelineConstructionType); 914 915 dedicatedAllocationTestsGroup->addChild(samplingTypeTests.release()); 916 917 return dedicatedAllocationTestsGroup; 918} 919} // anonymous 920 921tcu::TestCaseGroup* createImageTests (tcu::TestContext& testCtx, PipelineConstructionType pipelineConstructionType) 922{ 923 de::MovePtr<tcu::TestCaseGroup> imageTests(new tcu::TestCaseGroup(testCtx, "image")); 924 de::MovePtr<tcu::TestCaseGroup> imageSuballocationTests = createSuballocationTests(testCtx, pipelineConstructionType); 925 de::MovePtr<tcu::TestCaseGroup> imageDedicatedAllocationTests = createDedicatedAllocationTests(testCtx, pipelineConstructionType); 926 927 imageTests->addChild(imageSuballocationTests.release()); 928 imageTests->addChild(imageDedicatedAllocationTests.release()); 929 930 return imageTests.release(); 931} 932 933} // pipeline 934} // vkt 935