1 /*------------------------------------------------------------------------ 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2015 The Khronos Group Inc. 6 * Copyright (c) 2015 Imagination Technologies Ltd. 7 * 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 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 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. 19 * 20 *//*! 21 * \file 22 * \brief Image View Tests 23 *//*--------------------------------------------------------------------*/ 24 25 #include "vktPipelineImageViewTests.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" 35 #include "deMemory.h" 36 37 #include <sstream> 38 #include <vector> 39 40 namespace vkt 41 { 42 namespace pipeline 43 { 44 45 using namespace vk; 46 using de::MovePtr; 47 48 namespace 49 { 50 51 52 class ImageViewTest : public vkt::TestCase 53 { 54 public: 55 ImageViewTest (tcu::TestContext& testContext, 56 const char* name, 57 const char* description, 58 VkImageViewType imageViewType, 59 VkFormat imageFormat, 60 float samplerLod, 61 const VkComponentMapping& componentMapping, 62 const VkImageSubresourceRange& subresourceRange); 63 virtual ~ImageViewTest (void) {} 64 65 virtual void initPrograms (SourceCollections& sourceCollections) const; 66 virtual TestInstance* createInstance (Context& context) const; 67 static std::string getGlslSamplerType (const tcu::TextureFormat& format, 68 VkImageViewType type); 69 static tcu::UVec2 getRenderSize (VkImageViewType viewType); 70 static tcu::IVec3 getImageSize (VkImageViewType viewType); 71 static int getArraySize (VkImageViewType viewType); 72 static int getNumLevels (VkImageViewType viewType); 73 static tcu::Vec4 swizzle (tcu::Vec4 inputData, 74 VkComponentMapping componentMapping); 75 private: 76 VkImageViewType m_imageViewType; 77 VkFormat m_imageFormat; 78 float m_samplerLod; 79 VkComponentMapping m_componentMapping; 80 VkImageSubresourceRange m_subresourceRange; 81 }; 82 83 ImageViewTest::ImageViewTest (tcu::TestContext& testContext, 84 const char* name, 85 const char* description, 86 VkImageViewType imageViewType, 87 VkFormat imageFormat, 88 float samplerLod, 89 const VkComponentMapping& componentMapping, 90 const VkImageSubresourceRange& subresourceRange) 91 92 : vkt::TestCase (testContext, name, description) 93 , m_imageViewType (imageViewType) 94 , m_imageFormat (imageFormat) 95 , m_samplerLod (samplerLod) 96 , m_componentMapping (componentMapping) 97 , m_subresourceRange (subresourceRange) 98 { 99 } 100 101 tcu::Vec4 ImageViewTest::swizzle (tcu::Vec4 inputData, VkComponentMapping componentMapping) 102 { 103 // array map with enum VkComponentSwizzle 104 const float channelValues[] = 105 { 106 -1.0f, 107 0.0f, 108 1.0f, 109 inputData.x(), 110 inputData.y(), 111 inputData.z(), 112 inputData.w(), 113 -1.0f 114 }; 115 116 return tcu::Vec4(channelValues[componentMapping.r], 117 channelValues[componentMapping.g], 118 channelValues[componentMapping.b], 119 channelValues[componentMapping.a]); 120 } 121 122 void ImageViewTest::initPrograms (SourceCollections& sourceCollections) const 123 { 124 std::ostringstream vertexSrc; 125 std::ostringstream fragmentSrc; 126 const char* texCoordSwizzle = DE_NULL; 127 const tcu::TextureFormat format = (isCompressedFormat(m_imageFormat)) ? tcu::getUncompressedFormat(mapVkCompressedFormat(m_imageFormat)) 128 : mapVkFormat(m_imageFormat); 129 130 tcu::Vec4 lookupScale; 131 tcu::Vec4 lookupBias; 132 133 getLookupScaleBias(m_imageFormat, lookupScale, lookupBias); 134 135 tcu::Vec4 swizzledScale = swizzle(lookupScale, m_componentMapping); 136 tcu::Vec4 swizzledBias = swizzle(lookupBias, m_componentMapping); 137 138 switch (m_imageViewType) 139 { 140 case VK_IMAGE_VIEW_TYPE_1D: 141 texCoordSwizzle = "x"; 142 break; 143 case VK_IMAGE_VIEW_TYPE_1D_ARRAY: 144 case VK_IMAGE_VIEW_TYPE_2D: 145 texCoordSwizzle = "xy"; 146 break; 147 case VK_IMAGE_VIEW_TYPE_2D_ARRAY: 148 case VK_IMAGE_VIEW_TYPE_3D: 149 case VK_IMAGE_VIEW_TYPE_CUBE: 150 texCoordSwizzle = "xyz"; 151 break; 152 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: 153 texCoordSwizzle = "xyzw"; 154 break; 155 default: 156 DE_ASSERT(false); 157 break; 158 } 159 160 vertexSrc << "#version 440\n" 161 << "layout(location = 0) in vec4 position;\n" 162 << "layout(location = 1) in vec4 texCoords;\n" 163 << "layout(location = 0) out highp vec4 vtxTexCoords;\n" 164 << "out gl_PerVertex {\n" 165 << " vec4 gl_Position;\n" 166 << "};\n" 167 << "void main (void)\n" 168 << "{\n" 169 << " gl_Position = position;\n" 170 << " vtxTexCoords = texCoords;\n" 171 << "}\n"; 172 173 fragmentSrc << "#version 440\n" 174 << "layout(set = 0, binding = 0) uniform highp " << getGlslSamplerType(format, m_imageViewType) << " texSampler;\n" 175 << "layout(location = 0) in highp vec4 vtxTexCoords;\n" 176 << "layout(location = 0) out highp vec4 fragColor;\n" 177 << "void main (void)\n" 178 << "{\n" 179 << " fragColor = "; 180 181 if (m_samplerLod > 0.0f) 182 fragmentSrc << "textureLod(texSampler, vtxTexCoords." << texCoordSwizzle << ", " << std::fixed << m_samplerLod << ")"; 183 else 184 fragmentSrc << "texture(texSampler, vtxTexCoords." << texCoordSwizzle << ")" << std::fixed; 185 186 fragmentSrc << " * vec4" << std::scientific << swizzledScale << " + vec4" << swizzledBias << ";\n" 187 << "}\n"; 188 189 sourceCollections.glslSources.add("tex_vert") << glu::VertexSource(vertexSrc.str()); 190 sourceCollections.glslSources.add("tex_frag") << glu::FragmentSource(fragmentSrc.str()); 191 } 192 193 TestInstance* ImageViewTest::createInstance (Context& context) const 194 { 195 const tcu::UVec2 renderSize = getRenderSize(m_imageViewType); 196 const tcu::IVec3 imageSize = getImageSize(m_imageViewType); 197 const int arraySize = getArraySize(m_imageViewType); 198 const std::vector<Vertex4Tex4> vertices = createTestQuadMosaic(m_imageViewType); 199 200 const VkSamplerCreateInfo samplerParams = 201 { 202 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType; 203 DE_NULL, // const void* pNext; 204 0u, // VkSamplerCreateFlags flags; 205 VK_FILTER_NEAREST, // VkFilter magFilter; 206 VK_FILTER_NEAREST, // VkFilter minFilter; 207 VK_SAMPLER_MIPMAP_MODE_NEAREST, // VkSamplerMipmapMode mipmapMode; 208 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeU; 209 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeV; 210 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeW; 211 0.0f, // float mipLodBias; 212 VK_FALSE, // VkBool32 anisotropyEnable; 213 1.0f, // float maxAnisotropy; 214 false, // VkBool32 compareEnable; 215 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp; 216 0.0f, // float minLod; 217 (float)(m_subresourceRange.levelCount - 1), // float maxLod; 218 getFormatBorderColor(BORDER_COLOR_TRANSPARENT_BLACK, m_imageFormat), // VkBorderColor borderColor; 219 false // VkBool32 unnormalizedCoordinates; 220 }; 221 222 return new ImageSamplingInstance(context, renderSize, m_imageViewType, m_imageFormat, imageSize, arraySize, m_componentMapping, m_subresourceRange, samplerParams, m_samplerLod, vertices); 223 } 224 225 std::string ImageViewTest::getGlslSamplerType (const tcu::TextureFormat& format, VkImageViewType type) 226 { 227 std::ostringstream samplerType; 228 229 if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER) 230 samplerType << "u"; 231 else if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER) 232 samplerType << "i"; 233 234 switch (type) 235 { 236 case VK_IMAGE_VIEW_TYPE_1D: 237 samplerType << "sampler1D"; 238 break; 239 240 case VK_IMAGE_VIEW_TYPE_1D_ARRAY: 241 samplerType << "sampler1DArray"; 242 break; 243 244 case VK_IMAGE_VIEW_TYPE_2D: 245 samplerType << "sampler2D"; 246 break; 247 248 case VK_IMAGE_VIEW_TYPE_2D_ARRAY: 249 samplerType << "sampler2DArray"; 250 break; 251 252 case VK_IMAGE_VIEW_TYPE_3D: 253 samplerType << "sampler3D"; 254 break; 255 256 case VK_IMAGE_VIEW_TYPE_CUBE: 257 samplerType << "samplerCube"; 258 break; 259 260 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: 261 samplerType << "samplerCubeArray"; 262 break; 263 264 default: 265 DE_FATAL("Unknown image view type"); 266 break; 267 } 268 269 return samplerType.str(); 270 } 271 272 tcu::UVec2 ImageViewTest::getRenderSize (VkImageViewType viewType) 273 { 274 if (viewType == VK_IMAGE_VIEW_TYPE_1D || viewType == VK_IMAGE_VIEW_TYPE_2D) 275 return tcu::UVec2(16u, 16u); 276 else 277 return tcu::UVec2(16u * 3u, 16u * 2u); 278 } 279 280 tcu::IVec3 ImageViewTest::getImageSize (VkImageViewType viewType) 281 { 282 switch (viewType) 283 { 284 case VK_IMAGE_VIEW_TYPE_1D: 285 case VK_IMAGE_VIEW_TYPE_1D_ARRAY: 286 return tcu::IVec3(16, 1, 1); 287 288 case VK_IMAGE_VIEW_TYPE_3D: 289 return tcu::IVec3(16); 290 291 default: 292 break; 293 } 294 295 return tcu::IVec3(16, 16, 1); 296 } 297 298 int ImageViewTest::getArraySize (VkImageViewType viewType) 299 { 300 switch (viewType) 301 { 302 case VK_IMAGE_VIEW_TYPE_3D: 303 return 1; 304 305 case VK_IMAGE_VIEW_TYPE_CUBE: 306 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: 307 return 18; 308 309 default: 310 break; 311 } 312 313 return 6; 314 } 315 316 int ImageViewTest::getNumLevels (VkImageViewType viewType) 317 { 318 const tcu::IVec3 imageSize = getImageSize(viewType); 319 320 return deLog2Floor32(deMax32(imageSize.x(), deMax32(imageSize.y(), imageSize.z()))) + 1; 321 } 322 323 static std::string getFormatCaseName (const VkFormat format) 324 { 325 const std::string fullName = getFormatName(format); 326 327 DE_ASSERT(de::beginsWith(fullName, "VK_FORMAT_")); 328 329 return de::toLower(fullName.substr(10)); 330 } 331 332 static de::MovePtr<tcu::TestCaseGroup> createSubresourceRangeTests(tcu::TestContext& testCtx, VkImageViewType viewType, VkFormat imageFormat) 333 { 334 struct TestCaseConfig 335 { 336 const char* name; 337 float samplerLod; 338 VkImageSubresourceRange subresourceRange; 339 }; 340 341 const deUint32 numLevels = ImageViewTest::getNumLevels(viewType); 342 const deUint32 arraySize = ImageViewTest::getArraySize(viewType); 343 const VkImageAspectFlags imageAspectFlags = VK_IMAGE_ASPECT_COLOR_BIT; 344 const VkComponentMapping componentMapping = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; 345 346 de::MovePtr<tcu::TestCaseGroup> rangeTests (new tcu::TestCaseGroup(testCtx, "subresource_range", "")); 347 348 #define ADD_SUBRESOURCE_RANGE_TESTS(TEST_CASES) \ 349 do { \ 350 for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(TEST_CASES); configNdx++) \ 351 { \ 352 std::ostringstream desc; \ 353 const TestCaseConfig config = (TEST_CASES)[configNdx]; \ 354 desc << "Samples level " << config.samplerLod << " with :\n" << config.subresourceRange; \ 355 rangeTests->addChild(new ImageViewTest(testCtx, config.name, desc.str().c_str(), viewType, \ 356 imageFormat, config.samplerLod, componentMapping, \ 357 config.subresourceRange)); \ 358 } \ 359 } while (deGetFalse()) 360 361 if (viewType == VK_IMAGE_VIEW_TYPE_1D_ARRAY || viewType == VK_IMAGE_VIEW_TYPE_2D_ARRAY) 362 { 363 const TestCaseConfig mipLevelRangeCases[] = 364 { 365 // name samplerLod subresourceRange (aspectMask, baseMipLevel, mipLevels, baseArrayLayer, arraySize) 366 { "lod_base_mip_level", 0.0f, { imageAspectFlags, 2u, numLevels - 2u, 0u, arraySize } }, 367 { "lod_mip_levels", 4.0f, { imageAspectFlags, 0u, 3u, 0u, arraySize } }, 368 }; 369 370 const TestCaseConfig arrayRangeCases[] = 371 { 372 // name samplerLod subresourceRange (aspectMask, baseMipLevel, mipLevels, baseArrayLayer, arraySize) 373 { "base_array_layer", 0.0f, { imageAspectFlags, 0u, numLevels, 1u, arraySize - 1u } }, 374 { "array_size", 0.0f, { imageAspectFlags, 0u, numLevels, 0u, 4u } }, 375 { "array_base_and_size", 0.0f, { imageAspectFlags, 0u, numLevels, 2u, 3u } }, 376 }; 377 378 const TestCaseConfig mipLevelAndArrayRangeCases[] = 379 { 380 // name samplerLod subresourceRange (aspectMask, baseMipLevel, mipLevels, baseArrayLayer, arraySize) 381 { "lod_base_mip_level_base_array_layer", 0.0f, { imageAspectFlags, 2u, numLevels - 2u, 1u, 5u } }, 382 { "lod_mip_levels_base_array_layer", 4.0f, { imageAspectFlags, 0u, 3u, 1u, 5u } }, 383 384 { "lod_base_mip_level_array_size", 0.0f, { imageAspectFlags, 2u, numLevels - 2u, 0u, 4u } }, 385 { "lod_mip_levels_array_size", 4.0f, { imageAspectFlags, 0u, 3u, 0u, 4u } }, 386 387 { "lod_base_mip_level_array_base_and_size", 0.0f, { imageAspectFlags, 2u, numLevels - 2u, 2u, 3u } }, 388 { "lod_mip_levels_array_base_and_size", 4.0f, { imageAspectFlags, 0u, 3u, 2u, 3u } }, 389 }; 390 391 const TestCaseConfig mipLevelAndArrayRemainingRangeCases[] = 392 { 393 // name samplerLod subresourceRange (aspectMask, baseMipLevel, mipLevels, baseArrayLayer, arraySize) 394 { "lod_base_mip_level_remaining_levels", 0.0f, { imageAspectFlags, 1u, VK_REMAINING_MIP_LEVELS, 0u, arraySize } }, 395 { "base_array_layer_remaining_layers", 0.0f, { imageAspectFlags, 0u, numLevels, 1u, VK_REMAINING_ARRAY_LAYERS } }, 396 { "lod_base_mip_level_base_array_layer_remaining_levels_and_layers", 0.0f, { imageAspectFlags, 2u, VK_REMAINING_MIP_LEVELS, 2u, VK_REMAINING_ARRAY_LAYERS } }, 397 }; 398 399 ADD_SUBRESOURCE_RANGE_TESTS(mipLevelRangeCases); 400 ADD_SUBRESOURCE_RANGE_TESTS(arrayRangeCases); 401 ADD_SUBRESOURCE_RANGE_TESTS(mipLevelAndArrayRangeCases); 402 ADD_SUBRESOURCE_RANGE_TESTS(mipLevelAndArrayRemainingRangeCases); 403 } 404 else if (viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) 405 { 406 const TestCaseConfig mipLevelRangeCases[] = 407 { 408 // name samplerLod subresourceRange (aspectMask, baseMipLevel, mipLevels, baseArrayLayer, arraySize) 409 { "lod_base_mip_level", 0.0f, { imageAspectFlags, 2u, numLevels - 2u, 0u, arraySize } }, 410 { "lod_mip_levels", 4.0f, { imageAspectFlags, 0u, 3u, 0u, arraySize } }, 411 }; 412 413 const TestCaseConfig arrayRangeCases[] = 414 { 415 // name samplerLod subresourceRange (aspectMask, baseMipLevel, mipLevels, baseArrayLayer, arraySize) 416 { "base_array_layer", 0.0f, { imageAspectFlags, 0u, numLevels, 6u, arraySize - 6u } }, 417 { "array_size", 0.0f, { imageAspectFlags, 0u, numLevels, 0u, 6u } }, 418 { "array_base_and_size", 0.0f, { imageAspectFlags, 0u, numLevels, 12u, 6u } }, 419 }; 420 421 const TestCaseConfig mipLevelAndArrayRangeCases[] = 422 { 423 // name samplerLod subresourceRange (aspectMask, baseMipLevel, mipLevels, baseArrayLayer, arraySize) 424 { "lod_base_mip_level_base_array_layer", 0.0f, { imageAspectFlags, 2u, numLevels - 2u, 6u, arraySize - 6u } }, 425 { "lod_mip_levels_base_array_layer", 4.0f, { imageAspectFlags, 0u, 3u, 6u, arraySize - 6u } }, 426 427 { "lod_base_mip_level_array_size", 0.0f, { imageAspectFlags, 2u, numLevels - 2u, 0u, 6u } }, 428 { "lod_mip_levels_array_size", 4.0f, { imageAspectFlags, 0u, 3u, 0u, 6u } }, 429 430 { "lod_base_mip_level_array_base_and_size", 0.0f, { imageAspectFlags, 2u, numLevels - 2u, 12u, 6u } }, 431 { "lod_mip_levels_array_base_and_size", 4.0f, { imageAspectFlags, 0u, 3u, 12u, 6u } }, 432 }; 433 434 const TestCaseConfig mipLevelAndArrayRemainingRangeCases[] = 435 { 436 // name samplerLod subresourceRange (aspectMask, baseMipLevel, mipLevels, baseArrayLayer, arraySize) 437 { "lod_base_mip_level_remaining_levels", 0.0f, { imageAspectFlags, 1u, VK_REMAINING_MIP_LEVELS, 0u, arraySize } }, 438 { "base_array_layer_remaining_layers", 0.0f, { imageAspectFlags, 0u, numLevels, 6u, VK_REMAINING_ARRAY_LAYERS } }, 439 { "lod_base_mip_level_base_array_layer_remaining_levels_and_layers", 0.0f, { imageAspectFlags, 2u, VK_REMAINING_MIP_LEVELS, 12u, VK_REMAINING_ARRAY_LAYERS } }, 440 }; 441 442 ADD_SUBRESOURCE_RANGE_TESTS(mipLevelRangeCases); 443 ADD_SUBRESOURCE_RANGE_TESTS(arrayRangeCases); 444 ADD_SUBRESOURCE_RANGE_TESTS(mipLevelAndArrayRangeCases); 445 ADD_SUBRESOURCE_RANGE_TESTS(mipLevelAndArrayRemainingRangeCases); 446 } 447 else if (viewType == VK_IMAGE_VIEW_TYPE_1D || viewType == VK_IMAGE_VIEW_TYPE_2D) 448 { 449 const TestCaseConfig mipLevelRangeCases[] = 450 { 451 // name samplerLod subresourceRange (aspectMask, baseMipLevel, mipLevels, baseArrayLayer, arraySize) 452 { "lod_base_mip_level", 0.0f, { imageAspectFlags, 2u, numLevels - 2u, 0u, 1u } }, 453 { "lod_mip_levels", 4.0f, { imageAspectFlags, 0u, 3u, 0u, 1u } }, 454 }; 455 456 const TestCaseConfig arrayRangeCases[] = 457 { 458 // name samplerLod subresourceRange (aspectMask, baseMipLevel, mipLevels, baseArrayLayer, arraySize) 459 { "array_layer_second", 0.0f, { imageAspectFlags, 0u, numLevels, 1u, 1u } }, 460 { "array_layer_last", 0.0f, { imageAspectFlags, 0u, numLevels, arraySize - 1u, 1u } }, 461 }; 462 463 const TestCaseConfig mipLevelAndArrayRangeCases[] = 464 { 465 // name samplerLod subresourceRange (aspectMask, baseMipLevel, mipLevels, baseArrayLayer, arraySize) 466 { "lod_base_mip_level_array_layer_second", 0.0f, { imageAspectFlags, 2u, numLevels - 2u, 1u, 1u } }, 467 { "lod_mip_levels_array_layer_second", 4.0f, { imageAspectFlags, 0u, 3u, arraySize - 1u, 1u } }, 468 469 { "lod_base_mip_level_array_layer_last", 0.0f, { imageAspectFlags, 2u, numLevels - 2u, 5u, 1u } }, 470 { "lod_mip_levels_array_layer_last", 4.0f, { imageAspectFlags, 0u, 3u, arraySize - 1u, 1u } }, 471 }; 472 473 const TestCaseConfig mipLevelAndArrayRemainingRangeCases[] = 474 { 475 // name samplerLod subresourceRange (aspectMask, baseMipLevel, mipLevels, baseArrayLayer, arraySize) 476 { "lod_base_mip_level_remaining_levels", 0.0f, { imageAspectFlags, 1u, VK_REMAINING_MIP_LEVELS, 0u, 1u } }, 477 { "array_layer_last_remaining_layers", 0.0f, { imageAspectFlags, 0u, numLevels, arraySize - 1u, VK_REMAINING_ARRAY_LAYERS } }, 478 { "lod_base_mip_level_array_layer_last_remaining_levels_and_layers", 0.0f, { imageAspectFlags, 2u, VK_REMAINING_MIP_LEVELS, arraySize - 1u, VK_REMAINING_ARRAY_LAYERS } }, 479 }; 480 481 ADD_SUBRESOURCE_RANGE_TESTS(mipLevelRangeCases); 482 ADD_SUBRESOURCE_RANGE_TESTS(arrayRangeCases); 483 ADD_SUBRESOURCE_RANGE_TESTS(mipLevelAndArrayRangeCases); 484 ADD_SUBRESOURCE_RANGE_TESTS(mipLevelAndArrayRemainingRangeCases); 485 } 486 else if (viewType == VK_IMAGE_VIEW_TYPE_CUBE) 487 { 488 const TestCaseConfig mipLevelRangeCases[] = 489 { 490 // name samplerLod subresourceRange (aspectMask, baseMipLevel, mipLevels, baseArrayLayer, arraySize) 491 { "lod_base_mip_level", 0.0f, { imageAspectFlags, 2u, numLevels - 2u, 0u, 6u } }, 492 { "lod_mip_levels", 4.0f, { imageAspectFlags, 0u, 3u, 0u, 6u } }, 493 }; 494 495 const TestCaseConfig arrayRangeCases[] = 496 { 497 // name samplerLod subresourceRange (aspectMask, baseMipLevel, mipLevels, baseArrayLayer, arraySize) 498 { "array_layer_second", 0.0f, { imageAspectFlags, 0u, numLevels, 6u, 6u } }, 499 { "array_layer_last", 0.0f, { imageAspectFlags, 0u, numLevels, arraySize - 6u, 6u } }, 500 }; 501 502 const TestCaseConfig mipLevelAndArrayRangeCases[] = 503 { 504 // name samplerLod subresourceRange (aspectMask, baseMipLevel, mipLevels, baseArrayLayer, arraySize) 505 { "lod_base_mip_level_array_layer_second", 0.0f, { imageAspectFlags, 2u, numLevels - 2u, 6u, 6u } }, 506 { "lod_mip_levels_array_layer_second", 4.0f, { imageAspectFlags, 0u, 3u, 6u, 6u } }, 507 508 { "lod_base_mip_level_array_layer_last", 0.0f, { imageAspectFlags, 2u, numLevels - 2u, arraySize - 6u, 6u } }, 509 { "lod_mip_levels_array_layer_last", 4.0f, { imageAspectFlags, 0u, 3u, arraySize - 6u, 6u } }, 510 }; 511 512 const TestCaseConfig mipLevelAndArrayRemainingRangeCases[] = 513 { 514 // name samplerLod subresourceRange (aspectMask, baseMipLevel, mipLevels, baseArrayLayer, arraySize) 515 { "lod_base_mip_level_remaining_levels", 0.0f, { imageAspectFlags, 1u, VK_REMAINING_MIP_LEVELS, 0u, 6u } }, 516 { "array_layer_last_remaining_layers", 0.0f, { imageAspectFlags, 0u, numLevels, arraySize - 6u, VK_REMAINING_ARRAY_LAYERS } }, 517 { "lod_base_mip_level_array_layer_last_remaining_levels_and_layers", 0.0f, { imageAspectFlags, 2u, VK_REMAINING_MIP_LEVELS, arraySize - 6u, VK_REMAINING_ARRAY_LAYERS } }, 518 }; 519 520 ADD_SUBRESOURCE_RANGE_TESTS(mipLevelRangeCases); 521 ADD_SUBRESOURCE_RANGE_TESTS(arrayRangeCases); 522 ADD_SUBRESOURCE_RANGE_TESTS(mipLevelAndArrayRangeCases); 523 ADD_SUBRESOURCE_RANGE_TESTS(mipLevelAndArrayRemainingRangeCases); 524 } 525 else if (viewType == VK_IMAGE_VIEW_TYPE_3D) 526 { 527 const TestCaseConfig mipLevelRangeCases[] = 528 { 529 // name samplerLod subresourceRange (aspectMask, baseMipLevel, mipLevels, baseArrayLayer, arraySize) 530 { "lod_base_mip_level", 0.0f, { imageAspectFlags, 2u, numLevels - 2u, 0u, arraySize } }, 531 { "lod_mip_levels", 4.0f, { imageAspectFlags, 0u, 3u, 0u, arraySize } }, 532 }; 533 534 const TestCaseConfig mipLevelAndArrayRemainingRangeCases[] = 535 { 536 // name samplerLod subresourceRange (aspectMask, baseMipLevel, mipLevels, baseArrayLayer, arraySize) 537 { "lod_base_mip_level_remaining_levels", 0.0f, { imageAspectFlags, 1u, VK_REMAINING_MIP_LEVELS, 0u, arraySize } }, 538 { "single_array_layer_remaining_layers", 0.0f, { imageAspectFlags, 0u, numLevels, 0u, VK_REMAINING_ARRAY_LAYERS } }, 539 { "lod_base_mip_level_single_array_layer_remaining_levels_and_layers", 0.0f, { imageAspectFlags, 2u, VK_REMAINING_MIP_LEVELS, 0u, VK_REMAINING_ARRAY_LAYERS } }, 540 }; 541 542 ADD_SUBRESOURCE_RANGE_TESTS(mipLevelRangeCases); 543 ADD_SUBRESOURCE_RANGE_TESTS(mipLevelAndArrayRemainingRangeCases); 544 } 545 546 #undef ADD_SUBRESOURCE_RANGE_TESTS 547 548 return rangeTests; 549 } 550 551 static std::vector<VkComponentMapping> getComponentMappingPermutations (const VkComponentMapping& componentMapping) 552 { 553 std::vector<VkComponentMapping> mappings; 554 555 const VkComponentSwizzle channelSwizzles[4] = { componentMapping.r, componentMapping.g, componentMapping.b, componentMapping.a }; 556 557 // Rearranges the channels by shifting their positions. 558 for (int firstChannelNdx = 0; firstChannelNdx < 4; firstChannelNdx++) 559 { 560 VkComponentSwizzle currentChannel[4]; 561 562 for (int channelNdx = 0; channelNdx < 4; channelNdx++) 563 currentChannel[channelNdx] = channelSwizzles[(firstChannelNdx + channelNdx) % 4]; 564 565 const VkComponentMapping mappingPermutation = 566 { 567 currentChannel[0], 568 currentChannel[1], 569 currentChannel[2], 570 currentChannel[3] 571 }; 572 573 mappings.push_back(mappingPermutation); 574 } 575 576 return mappings; 577 } 578 579 static std::string getComponentSwizzleCaseName (VkComponentSwizzle componentSwizzle) 580 { 581 const std::string fullName = getComponentSwizzleName(componentSwizzle); 582 583 DE_ASSERT(de::beginsWith(fullName, "VK_COMPONENT_SWIZZLE_")); 584 585 return de::toLower(fullName.substr(21)); 586 } 587 588 static std::string getComponentMappingCaseName (const VkComponentMapping& componentMapping) 589 { 590 std::ostringstream name; 591 592 name << getComponentSwizzleCaseName(componentMapping.r) << "_" 593 << getComponentSwizzleCaseName(componentMapping.g) << "_" 594 << getComponentSwizzleCaseName(componentMapping.b) << "_" 595 << getComponentSwizzleCaseName(componentMapping.a); 596 597 return name.str(); 598 } 599 600 static de::MovePtr<tcu::TestCaseGroup> createComponentSwizzleTests (tcu::TestContext& testCtx, VkImageViewType viewType, VkFormat imageFormat) 601 { 602 deUint32 arraySize = 0; 603 604 switch (viewType) 605 { 606 case VK_IMAGE_VIEW_TYPE_1D: 607 case VK_IMAGE_VIEW_TYPE_2D: 608 case VK_IMAGE_VIEW_TYPE_3D: 609 arraySize = 1; 610 break; 611 612 case VK_IMAGE_VIEW_TYPE_CUBE: 613 arraySize = 6; 614 break; 615 616 case VK_IMAGE_VIEW_TYPE_1D_ARRAY: 617 case VK_IMAGE_VIEW_TYPE_2D_ARRAY: 618 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: 619 arraySize = ImageViewTest::getArraySize(viewType); 620 break; 621 622 default: 623 break; 624 } 625 626 const VkImageSubresourceRange subresourceRange = 627 { 628 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 629 0u, // deUint32 baseMipLevel; 630 (deUint32)ImageViewTest::getNumLevels(viewType), // deUint32 mipLevels; 631 0u, // deUint32 baseArrayLayer; 632 arraySize, // deUint32 arraySize; 633 }; 634 635 const VkComponentMapping baseMapping = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; 636 const std::vector<VkComponentMapping> componentMappings = getComponentMappingPermutations(baseMapping); 637 de::MovePtr<tcu::TestCaseGroup> swizzleTests (new tcu::TestCaseGroup(testCtx, "component_swizzle", "")); 638 639 for (size_t mappingNdx = 0; mappingNdx < componentMappings.size(); mappingNdx++) 640 { 641 swizzleTests->addChild(new ImageViewTest(testCtx, 642 getComponentMappingCaseName(componentMappings[mappingNdx]).c_str(), 643 "", 644 viewType, 645 imageFormat, 646 0.0f, 647 componentMappings[mappingNdx], 648 subresourceRange)); 649 } 650 651 return swizzleTests; 652 } 653 654 } // anonymous 655 656 tcu::TestCaseGroup* createImageViewTests (tcu::TestContext& testCtx) 657 { 658 const struct 659 { 660 VkImageViewType type; 661 const char* name; 662 } 663 imageViewTypes[] = 664 { 665 { VK_IMAGE_VIEW_TYPE_1D, "1d" }, 666 { VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array" }, 667 { VK_IMAGE_VIEW_TYPE_2D, "2d" }, 668 { VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array" }, 669 { VK_IMAGE_VIEW_TYPE_3D, "3d" }, 670 { VK_IMAGE_VIEW_TYPE_CUBE, "cube" }, 671 { VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array" } 672 }; 673 674 const VkFormat formats[] = 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_A2B10G10R10_USCALED_PACK32, 711 VK_FORMAT_R16_UNORM, 712 VK_FORMAT_R16_SNORM, 713 VK_FORMAT_R16_USCALED, 714 VK_FORMAT_R16_SSCALED, 715 VK_FORMAT_R16_UINT, 716 VK_FORMAT_R16_SINT, 717 VK_FORMAT_R16_SFLOAT, 718 VK_FORMAT_R16G16_UNORM, 719 VK_FORMAT_R16G16_SNORM, 720 VK_FORMAT_R16G16_USCALED, 721 VK_FORMAT_R16G16_SSCALED, 722 VK_FORMAT_R16G16_UINT, 723 VK_FORMAT_R16G16_SINT, 724 VK_FORMAT_R16G16_SFLOAT, 725 VK_FORMAT_R16G16B16_UNORM, 726 VK_FORMAT_R16G16B16_SNORM, 727 VK_FORMAT_R16G16B16_USCALED, 728 VK_FORMAT_R16G16B16_SSCALED, 729 VK_FORMAT_R16G16B16_UINT, 730 VK_FORMAT_R16G16B16_SINT, 731 VK_FORMAT_R16G16B16_SFLOAT, 732 VK_FORMAT_R16G16B16A16_UNORM, 733 VK_FORMAT_R16G16B16A16_SNORM, 734 VK_FORMAT_R16G16B16A16_USCALED, 735 VK_FORMAT_R16G16B16A16_SSCALED, 736 VK_FORMAT_R16G16B16A16_UINT, 737 VK_FORMAT_R16G16B16A16_SINT, 738 VK_FORMAT_R16G16B16A16_SFLOAT, 739 VK_FORMAT_R32_UINT, 740 VK_FORMAT_R32_SINT, 741 VK_FORMAT_R32_SFLOAT, 742 VK_FORMAT_R32G32_UINT, 743 VK_FORMAT_R32G32_SINT, 744 VK_FORMAT_R32G32_SFLOAT, 745 VK_FORMAT_R32G32B32_UINT, 746 VK_FORMAT_R32G32B32_SINT, 747 VK_FORMAT_R32G32B32_SFLOAT, 748 VK_FORMAT_R32G32B32A32_UINT, 749 VK_FORMAT_R32G32B32A32_SINT, 750 VK_FORMAT_R32G32B32A32_SFLOAT, 751 VK_FORMAT_B10G11R11_UFLOAT_PACK32, 752 VK_FORMAT_E5B9G9R9_UFLOAT_PACK32, 753 VK_FORMAT_B4G4R4A4_UNORM_PACK16, 754 VK_FORMAT_B5G5R5A1_UNORM_PACK16, 755 756 // Compressed formats 757 VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, 758 VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK, 759 VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK, 760 VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK, 761 VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, 762 VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK, 763 VK_FORMAT_EAC_R11_UNORM_BLOCK, 764 VK_FORMAT_EAC_R11_SNORM_BLOCK, 765 VK_FORMAT_EAC_R11G11_UNORM_BLOCK, 766 VK_FORMAT_EAC_R11G11_SNORM_BLOCK, 767 VK_FORMAT_ASTC_4x4_UNORM_BLOCK, 768 VK_FORMAT_ASTC_4x4_SRGB_BLOCK, 769 VK_FORMAT_ASTC_5x4_UNORM_BLOCK, 770 VK_FORMAT_ASTC_5x4_SRGB_BLOCK, 771 VK_FORMAT_ASTC_5x5_UNORM_BLOCK, 772 VK_FORMAT_ASTC_5x5_SRGB_BLOCK, 773 VK_FORMAT_ASTC_6x5_UNORM_BLOCK, 774 VK_FORMAT_ASTC_6x5_SRGB_BLOCK, 775 VK_FORMAT_ASTC_6x6_UNORM_BLOCK, 776 VK_FORMAT_ASTC_6x6_SRGB_BLOCK, 777 VK_FORMAT_ASTC_8x5_UNORM_BLOCK, 778 VK_FORMAT_ASTC_8x5_SRGB_BLOCK, 779 VK_FORMAT_ASTC_8x6_UNORM_BLOCK, 780 VK_FORMAT_ASTC_8x6_SRGB_BLOCK, 781 VK_FORMAT_ASTC_8x8_UNORM_BLOCK, 782 VK_FORMAT_ASTC_8x8_SRGB_BLOCK, 783 VK_FORMAT_ASTC_10x5_UNORM_BLOCK, 784 VK_FORMAT_ASTC_10x5_SRGB_BLOCK, 785 VK_FORMAT_ASTC_10x6_UNORM_BLOCK, 786 VK_FORMAT_ASTC_10x6_SRGB_BLOCK, 787 VK_FORMAT_ASTC_10x8_UNORM_BLOCK, 788 VK_FORMAT_ASTC_10x8_SRGB_BLOCK, 789 VK_FORMAT_ASTC_10x10_UNORM_BLOCK, 790 VK_FORMAT_ASTC_10x10_SRGB_BLOCK, 791 VK_FORMAT_ASTC_12x10_UNORM_BLOCK, 792 VK_FORMAT_ASTC_12x10_SRGB_BLOCK, 793 VK_FORMAT_ASTC_12x12_UNORM_BLOCK, 794 VK_FORMAT_ASTC_12x12_SRGB_BLOCK, 795 }; 796 797 de::MovePtr<tcu::TestCaseGroup> imageTests (new tcu::TestCaseGroup(testCtx, "image_view", "Image tests")); 798 de::MovePtr<tcu::TestCaseGroup> viewTypeTests (new tcu::TestCaseGroup(testCtx, "view_type", "")); 799 800 for (int viewTypeNdx = 0; viewTypeNdx < DE_LENGTH_OF_ARRAY(imageViewTypes); viewTypeNdx++) 801 { 802 const VkImageViewType viewType = imageViewTypes[viewTypeNdx].type; 803 de::MovePtr<tcu::TestCaseGroup> viewTypeGroup (new tcu::TestCaseGroup(testCtx, imageViewTypes[viewTypeNdx].name, (std::string("Uses a ") + imageViewTypes[viewTypeNdx].name + " view").c_str())); 804 de::MovePtr<tcu::TestCaseGroup> formatTests (new tcu::TestCaseGroup(testCtx, "format", "Uses samplable formats")); 805 806 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++) 807 { 808 const VkFormat format = formats[formatNdx]; 809 810 if (isCompressedFormat(format)) 811 { 812 // Do not use compressed formats with 1D and 1D array textures. 813 if (viewType == VK_IMAGE_VIEW_TYPE_1D || viewType == VK_IMAGE_VIEW_TYPE_1D_ARRAY) 814 break; 815 } 816 817 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx, 818 getFormatCaseName(format).c_str(), 819 (std::string("Samples a texture of format ") + getFormatName(format)).c_str())); 820 821 de::MovePtr<tcu::TestCaseGroup> subresourceRangeTests = createSubresourceRangeTests(testCtx, viewType, format); 822 de::MovePtr<tcu::TestCaseGroup> componentSwizzleTests = createComponentSwizzleTests(testCtx, viewType, format); 823 824 formatGroup->addChild(componentSwizzleTests.release()); 825 formatGroup->addChild(subresourceRangeTests.release()); 826 formatTests->addChild(formatGroup.release()); 827 } 828 829 viewTypeGroup->addChild(formatTests.release()); 830 viewTypeTests->addChild(viewTypeGroup.release()); 831 } 832 833 imageTests->addChild(viewTypeTests.release()); 834 835 return imageTests.release(); 836 } 837 838 } // pipeline 839 } // vkt 840