1 /*------------------------------------------------------------------------- 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2016 The Khronos Group Inc. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 *//*! 20 * \file 21 * \brief Buffer and image memory requirements tests. 22 *//*--------------------------------------------------------------------*/ 23 24 #include "vktMemoryRequirementsTests.hpp" 25 #include "vktTestCaseUtil.hpp" 26 #include "vktTestGroupUtil.hpp" 27 28 #include "vkDefs.hpp" 29 #include "vkRef.hpp" 30 #include "vkRefUtil.hpp" 31 #include "vkMemUtil.hpp" 32 #include "vkQueryUtil.hpp" 33 #include "vkStrUtil.hpp" 34 #include "vkTypeUtil.hpp" 35 #include "vkImageUtil.hpp" 36 37 #include "deUniquePtr.hpp" 38 #include "deStringUtil.hpp" 39 #include "deSTLUtil.hpp" 40 41 #include "tcuResultCollector.hpp" 42 #include "tcuTestLog.hpp" 43 44 namespace vkt 45 { 46 namespace memory 47 { 48 namespace 49 { 50 using namespace vk; 51 using de::MovePtr; 52 using tcu::TestLog; 53 54 Move<VkBuffer> makeBuffer (const DeviceInterface& vk, const VkDevice device, const VkDeviceSize size, const VkBufferCreateFlags flags, const VkBufferUsageFlags usage) 55 { 56 const VkBufferCreateInfo createInfo = 57 { 58 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 59 DE_NULL, // const void* pNext; 60 flags, // VkBufferCreateFlags flags; 61 size, // VkDeviceSize size; 62 usage, // VkBufferUsageFlags usage; 63 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 64 0u, // uint32_t queueFamilyIndexCount; 65 DE_NULL, // const uint32_t* pQueueFamilyIndices; 66 }; 67 return createBuffer(vk, device, &createInfo); 68 } 69 70 VkMemoryRequirements getBufferMemoryRequirements (const DeviceInterface& vk, const VkDevice device, const VkDeviceSize size, const VkBufferCreateFlags flags, const VkBufferUsageFlags usage) 71 { 72 const Unique<VkBuffer> buffer(makeBuffer(vk, device, size, flags, usage)); 73 return getBufferMemoryRequirements(vk, device, *buffer); 74 } 75 76 VkMemoryRequirements getBufferMemoryRequirements2 (const DeviceInterface& vk, const VkDevice device, const VkDeviceSize size, const VkBufferCreateFlags flags, const VkBufferUsageFlags usage, void* next = DE_NULL) 77 { 78 const Unique<VkBuffer> buffer (makeBuffer(vk, device, size, flags, usage)); 79 VkBufferMemoryRequirementsInfo2 info = 80 { 81 VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR, // VkStructureType sType 82 DE_NULL, // const void* pNext 83 *buffer // VkBuffer buffer 84 }; 85 VkMemoryRequirements2 req2 = 86 { 87 VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR, // VkStructureType sType 88 next, // void* pNext 89 {0, 0, 0} // VkMemoryRequirements memoryRequirements 90 }; 91 92 vk.getBufferMemoryRequirements2(device, &info, &req2); 93 94 return req2.memoryRequirements; 95 } 96 97 VkMemoryRequirements getImageMemoryRequirements2 (const DeviceInterface& vk, const VkDevice device, const VkImageCreateInfo& createInfo, void* next = DE_NULL) 98 { 99 const Unique<VkImage> image(createImage(vk, device, &createInfo)); 100 101 VkImageMemoryRequirementsInfo2 info = 102 { 103 VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR, // VkStructureType sType 104 DE_NULL, // const void* pNext 105 *image // VkImage image 106 }; 107 VkMemoryRequirements2 req2 = 108 { 109 VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR, // VkStructureType sType 110 next, // void* pNext 111 {0, 0, 0} // VkMemoryRequirements memoryRequirements 112 }; 113 114 vk.getImageMemoryRequirements2(device, &info, &req2); 115 116 return req2.memoryRequirements; 117 } 118 119 //! Get an index of each set bit, starting from the least significant bit. 120 std::vector<deUint32> bitsToIndices (deUint32 bits) 121 { 122 std::vector<deUint32> indices; 123 for (deUint32 i = 0u; bits != 0u; ++i, bits >>= 1) 124 { 125 if (bits & 1u) 126 indices.push_back(i); 127 } 128 return indices; 129 } 130 131 template<typename T> 132 T nextEnum (T value) 133 { 134 return static_cast<T>(static_cast<deUint32>(value) + 1); 135 } 136 137 template<typename T> 138 T nextFlag (T value) 139 { 140 if (value) 141 return static_cast<T>(static_cast<deUint32>(value) << 1); 142 else 143 return static_cast<T>(1); 144 } 145 146 template<typename T> 147 T nextFlagExcluding (T value, T excludedFlags) 148 { 149 deUint32 tmp = static_cast<deUint32>(value); 150 while ((tmp = nextFlag(tmp)) & static_cast<deUint32>(excludedFlags)); 151 return static_cast<T>(tmp); 152 } 153 154 bool validValueVkBool32 (const VkBool32 value) 155 { 156 return (value == VK_FALSE || value == VK_TRUE); 157 } 158 159 class IBufferMemoryRequirements 160 { 161 public: 162 virtual void populateTestGroup (tcu::TestCaseGroup* group) = 0; 163 164 protected: 165 virtual void addFunctionTestCase (tcu::TestCaseGroup* group, 166 const std::string& name, 167 const std::string& desc, 168 VkBufferCreateFlags arg0) = 0; 169 170 virtual tcu::TestStatus execTest (Context& context, 171 const VkBufferCreateFlags bufferFlags) = 0; 172 173 virtual void preTestChecks (Context& context, 174 const InstanceInterface& vki, 175 const VkPhysicalDevice physDevice, 176 const VkBufferCreateFlags flags) = 0; 177 178 virtual void updateMemoryRequirements (const DeviceInterface& vk, 179 const VkDevice device, 180 const VkDeviceSize size, 181 const VkBufferCreateFlags flags, 182 const VkBufferUsageFlags usage, 183 const bool all) = 0; 184 185 virtual void verifyMemoryRequirements (tcu::ResultCollector& result, 186 const VkPhysicalDeviceMemoryProperties& deviceMemoryProperties, 187 const VkPhysicalDeviceLimits& limits, 188 const VkBufferCreateFlags bufferFlags, 189 const VkBufferUsageFlags usage) = 0; 190 }; 191 192 class BufferMemoryRequirementsOriginal : public IBufferMemoryRequirements 193 { 194 static tcu::TestStatus testEntryPoint (Context& context, 195 const VkBufferCreateFlags bufferFlags); 196 197 public: 198 virtual void populateTestGroup (tcu::TestCaseGroup* group); 199 200 protected: 201 virtual void addFunctionTestCase (tcu::TestCaseGroup* group, 202 const std::string& name, 203 const std::string& desc, 204 VkBufferCreateFlags arg0); 205 206 virtual tcu::TestStatus execTest (Context& context, 207 const VkBufferCreateFlags bufferFlags); 208 209 virtual void preTestChecks (Context& context, 210 const InstanceInterface& vki, 211 const VkPhysicalDevice physDevice, 212 const VkBufferCreateFlags flags); 213 214 virtual void updateMemoryRequirements (const DeviceInterface& vk, 215 const VkDevice device, 216 const VkDeviceSize size, 217 const VkBufferCreateFlags flags, 218 const VkBufferUsageFlags usage, 219 const bool all); 220 221 virtual void verifyMemoryRequirements (tcu::ResultCollector& result, 222 const VkPhysicalDeviceMemoryProperties& deviceMemoryProperties, 223 const VkPhysicalDeviceLimits& limits, 224 const VkBufferCreateFlags bufferFlags, 225 const VkBufferUsageFlags usage); 226 227 protected: 228 VkMemoryRequirements m_allUsageFlagsRequirements; 229 VkMemoryRequirements m_currentTestRequirements; 230 }; 231 232 233 tcu::TestStatus BufferMemoryRequirementsOriginal::testEntryPoint (Context& context, const VkBufferCreateFlags bufferFlags) 234 { 235 BufferMemoryRequirementsOriginal test; 236 237 return test.execTest(context, bufferFlags); 238 } 239 240 void BufferMemoryRequirementsOriginal::populateTestGroup (tcu::TestCaseGroup* group) 241 { 242 const struct 243 { 244 VkBufferCreateFlags flags; 245 const char* const name; 246 } bufferCases[] = 247 { 248 { (VkBufferCreateFlags)0, "regular" }, 249 { VK_BUFFER_CREATE_SPARSE_BINDING_BIT, "sparse" }, 250 { VK_BUFFER_CREATE_SPARSE_BINDING_BIT | VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT, "sparse_residency" }, 251 { VK_BUFFER_CREATE_SPARSE_BINDING_BIT | VK_BUFFER_CREATE_SPARSE_ALIASED_BIT, "sparse_aliased" }, 252 { VK_BUFFER_CREATE_SPARSE_BINDING_BIT | VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT | VK_BUFFER_CREATE_SPARSE_ALIASED_BIT, "sparse_residency_aliased" }, 253 }; 254 255 de::MovePtr<tcu::TestCaseGroup> bufferGroup(new tcu::TestCaseGroup(group->getTestContext(), "buffer", "")); 256 257 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(bufferCases); ++ndx) 258 addFunctionTestCase(bufferGroup.get(), bufferCases[ndx].name, "", bufferCases[ndx].flags); 259 260 group->addChild(bufferGroup.release()); 261 } 262 263 void BufferMemoryRequirementsOriginal::addFunctionTestCase (tcu::TestCaseGroup* group, 264 const std::string& name, 265 const std::string& desc, 266 VkBufferCreateFlags arg0) 267 { 268 addFunctionCase(group, name, desc, testEntryPoint, arg0); 269 } 270 271 tcu::TestStatus BufferMemoryRequirementsOriginal::execTest (Context& context, const VkBufferCreateFlags bufferFlags) 272 { 273 const DeviceInterface& vk = context.getDeviceInterface(); 274 const InstanceInterface& vki = context.getInstanceInterface(); 275 const VkDevice device = context.getDevice(); 276 const VkPhysicalDevice physDevice = context.getPhysicalDevice(); 277 278 preTestChecks(context, vki, physDevice, bufferFlags); 279 280 const VkPhysicalDeviceMemoryProperties memoryProperties = getPhysicalDeviceMemoryProperties(vki, physDevice); 281 const VkPhysicalDeviceLimits limits = getPhysicalDeviceProperties(vki, physDevice).limits; 282 const VkBufferUsageFlags allUsageFlags = static_cast<VkBufferUsageFlags>((VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT << 1) - 1); 283 tcu::TestLog& log = context.getTestContext().getLog(); 284 bool allPass = true; 285 286 const VkDeviceSize sizeCases[] = 287 { 288 1 * 1024, 289 8 * 1024, 290 64 * 1024, 291 1024 * 1024, 292 }; 293 294 // Updates m_allUsageFlags* fields 295 updateMemoryRequirements(vk, device, 1024, bufferFlags, allUsageFlags, true); // doesn't depend on size 296 297 for (VkBufferUsageFlags usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; usage <= VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT; usage = nextFlag(usage)) 298 { 299 deUint32 previousMemoryTypeBits = 0u; 300 VkDeviceSize previousAlignment = 0u; 301 302 log << tcu::TestLog::Message << "Verify a buffer with usage flags: " << de::toString(getBufferUsageFlagsStr(usage)) << tcu::TestLog::EndMessage; 303 304 for (const VkDeviceSize* pSize = sizeCases; pSize < sizeCases + DE_LENGTH_OF_ARRAY(sizeCases); ++pSize) 305 { 306 log << tcu::TestLog::Message << "- size " << *pSize << " bytes" << tcu::TestLog::EndMessage; 307 308 tcu::ResultCollector result(log, "ERROR: "); 309 310 // Updates m_allUsageFlags* fields 311 updateMemoryRequirements(vk, device, *pSize, bufferFlags, usage, false); 312 313 // Check: 314 // - requirements for a particular buffer usage 315 // - memoryTypeBits are a subset of bits for requirements with all usage flags combined 316 verifyMemoryRequirements(result, memoryProperties, limits, bufferFlags, usage); 317 318 // Check that for the same usage and create flags: 319 // - memoryTypeBits are the same 320 // - alignment is the same 321 if (pSize > sizeCases) 322 { 323 result.check(m_currentTestRequirements.memoryTypeBits == previousMemoryTypeBits, 324 "memoryTypeBits differ from the ones in the previous buffer size"); 325 326 result.check(m_currentTestRequirements.alignment == previousAlignment, 327 "alignment differs from the one in the previous buffer size"); 328 } 329 330 if (result.getResult() != QP_TEST_RESULT_PASS) 331 allPass = false; 332 333 previousMemoryTypeBits = m_currentTestRequirements.memoryTypeBits; 334 previousAlignment = m_currentTestRequirements.alignment; 335 } 336 337 if (!allPass) 338 break; 339 } 340 341 return allPass ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Some memory requirements were incorrect"); 342 } 343 344 void BufferMemoryRequirementsOriginal::preTestChecks (Context& , 345 const InstanceInterface& vki, 346 const VkPhysicalDevice physDevice, 347 const VkBufferCreateFlags flags) 348 { 349 const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice); 350 351 if ((flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT) && !features.sparseBinding) 352 TCU_THROW(NotSupportedError, "Feature not supported: sparseBinding"); 353 354 if ((flags & VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT) && !features.sparseResidencyBuffer) 355 TCU_THROW(NotSupportedError, "Feature not supported: sparseResidencyBuffer"); 356 357 if ((flags & VK_BUFFER_CREATE_SPARSE_ALIASED_BIT) && !features.sparseResidencyAliased) 358 TCU_THROW(NotSupportedError, "Feature not supported: sparseResidencyAliased"); 359 } 360 361 void BufferMemoryRequirementsOriginal::updateMemoryRequirements (const DeviceInterface& vk, 362 const VkDevice device, 363 const VkDeviceSize size, 364 const VkBufferCreateFlags flags, 365 const VkBufferUsageFlags usage, 366 const bool all) 367 { 368 if (all) 369 { 370 m_allUsageFlagsRequirements = getBufferMemoryRequirements(vk, device, size, flags, usage); 371 } 372 else 373 { 374 m_currentTestRequirements = getBufferMemoryRequirements(vk, device, size, flags, usage); 375 } 376 } 377 378 void BufferMemoryRequirementsOriginal::verifyMemoryRequirements (tcu::ResultCollector& result, 379 const VkPhysicalDeviceMemoryProperties& deviceMemoryProperties, 380 const VkPhysicalDeviceLimits& limits, 381 const VkBufferCreateFlags bufferFlags, 382 const VkBufferUsageFlags usage) 383 { 384 if (result.check(m_currentTestRequirements.memoryTypeBits != 0, "VkMemoryRequirements memoryTypeBits has no bits set")) 385 { 386 typedef std::vector<deUint32>::const_iterator IndexIterator; 387 const std::vector<deUint32> usedMemoryTypeIndices = bitsToIndices(m_currentTestRequirements.memoryTypeBits); 388 bool deviceLocalMemoryFound = false; 389 bool hostVisibleCoherentMemoryFound = false; 390 391 for (IndexIterator memoryTypeNdx = usedMemoryTypeIndices.begin(); memoryTypeNdx != usedMemoryTypeIndices.end(); ++memoryTypeNdx) 392 { 393 if (*memoryTypeNdx >= deviceMemoryProperties.memoryTypeCount) 394 { 395 result.fail("VkMemoryRequirements memoryTypeBits contains bits for non-existing memory types"); 396 continue; 397 } 398 399 const VkMemoryPropertyFlags memoryPropertyFlags = deviceMemoryProperties.memoryTypes[*memoryTypeNdx].propertyFlags; 400 401 if (memoryPropertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) 402 deviceLocalMemoryFound = true; 403 404 if (memoryPropertyFlags & (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) 405 hostVisibleCoherentMemoryFound = true; 406 407 result.check((memoryPropertyFlags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) == 0u, 408 "Memory type includes VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT"); 409 } 410 411 result.check(deIsPowerOfTwo64(static_cast<deUint64>(m_currentTestRequirements.alignment)) == DE_TRUE, 412 "VkMemoryRequirements alignment isn't power of two"); 413 414 if (usage & (VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT)) 415 { 416 result.check(m_currentTestRequirements.alignment >= limits.minTexelBufferOffsetAlignment, 417 "VkMemoryRequirements alignment doesn't respect minTexelBufferOffsetAlignment"); 418 } 419 420 if (usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) 421 { 422 result.check(m_currentTestRequirements.alignment >= limits.minUniformBufferOffsetAlignment, 423 "VkMemoryRequirements alignment doesn't respect minUniformBufferOffsetAlignment"); 424 } 425 426 if (usage & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT) 427 { 428 result.check(m_currentTestRequirements.alignment >= limits.minStorageBufferOffsetAlignment, 429 "VkMemoryRequirements alignment doesn't respect minStorageBufferOffsetAlignment"); 430 } 431 432 result.check(deviceLocalMemoryFound, 433 "None of the required memory types included VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT"); 434 435 result.check((bufferFlags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT) || hostVisibleCoherentMemoryFound, 436 "Required memory type doesn't include VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT and VK_MEMORY_PROPERTY_HOST_COHERENT_BIT"); 437 438 result.check((m_currentTestRequirements.memoryTypeBits & m_allUsageFlagsRequirements.memoryTypeBits) == m_allUsageFlagsRequirements.memoryTypeBits, 439 "Memory type bits aren't a superset of memory type bits for all usage flags combined"); 440 } 441 } 442 443 class BufferMemoryRequirementsExtended : public BufferMemoryRequirementsOriginal 444 { 445 static tcu::TestStatus testEntryPoint (Context& context, 446 const VkBufferCreateFlags bufferFlags); 447 448 protected: 449 virtual void addFunctionTestCase (tcu::TestCaseGroup* group, 450 const std::string& name, 451 const std::string& desc, 452 VkBufferCreateFlags arg0); 453 454 virtual void preTestChecks (Context& context, 455 const InstanceInterface& vki, 456 const VkPhysicalDevice physDevice, 457 const VkBufferCreateFlags flags); 458 459 virtual void updateMemoryRequirements (const DeviceInterface& vk, 460 const VkDevice device, 461 const VkDeviceSize size, 462 const VkBufferCreateFlags flags, 463 const VkBufferUsageFlags usage, 464 const bool all); 465 }; 466 467 tcu::TestStatus BufferMemoryRequirementsExtended::testEntryPoint (Context& context, const VkBufferCreateFlags bufferFlags) 468 { 469 BufferMemoryRequirementsExtended test; 470 471 return test.execTest(context, bufferFlags); 472 } 473 474 void BufferMemoryRequirementsExtended::addFunctionTestCase (tcu::TestCaseGroup* group, 475 const std::string& name, 476 const std::string& desc, 477 VkBufferCreateFlags arg0) 478 { 479 addFunctionCase(group, name, desc, testEntryPoint, arg0); 480 } 481 482 void BufferMemoryRequirementsExtended::preTestChecks (Context& context, 483 const InstanceInterface& vki, 484 const VkPhysicalDevice physDevice, 485 const VkBufferCreateFlags flags) 486 { 487 const std::string extensionName("VK_KHR_get_memory_requirements2"); 488 489 if (!isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), extensionName)) 490 TCU_THROW(NotSupportedError, std::string(extensionName + " is not supported").c_str()); 491 492 BufferMemoryRequirementsOriginal::preTestChecks(context, vki, physDevice, flags); 493 } 494 495 void BufferMemoryRequirementsExtended::updateMemoryRequirements (const DeviceInterface& vk, 496 const VkDevice device, 497 const VkDeviceSize size, 498 const VkBufferCreateFlags flags, 499 const VkBufferUsageFlags usage, 500 const bool all) 501 { 502 if (all) 503 { 504 m_allUsageFlagsRequirements = getBufferMemoryRequirements2(vk, device, size, flags, usage); 505 } 506 else 507 { 508 m_currentTestRequirements = getBufferMemoryRequirements2(vk, device, size, flags, usage); 509 } 510 } 511 512 513 class BufferMemoryRequirementsDedicatedAllocation : public BufferMemoryRequirementsExtended 514 { 515 static tcu::TestStatus testEntryPoint (Context& context, 516 const VkBufferCreateFlags bufferFlags); 517 518 protected: 519 virtual void addFunctionTestCase (tcu::TestCaseGroup* group, 520 const std::string& name, 521 const std::string& desc, 522 VkBufferCreateFlags arg0); 523 524 virtual void preTestChecks (Context& context, 525 const InstanceInterface& vki, 526 const VkPhysicalDevice physDevice, 527 const VkBufferCreateFlags flags); 528 529 virtual void updateMemoryRequirements (const DeviceInterface& vk, 530 const VkDevice device, 531 const VkDeviceSize size, 532 const VkBufferCreateFlags flags, 533 const VkBufferUsageFlags usage, 534 const bool all); 535 536 virtual void verifyMemoryRequirements (tcu::ResultCollector& result, 537 const VkPhysicalDeviceMemoryProperties& deviceMemoryProperties, 538 const VkPhysicalDeviceLimits& limits, 539 const VkBufferCreateFlags bufferFlags, 540 const VkBufferUsageFlags usage); 541 542 protected: 543 VkBool32 m_allUsageFlagsPrefersDedicatedAllocation; 544 VkBool32 m_allUsageFlagsRequiresDedicatedAllocation; 545 546 VkBool32 m_currentTestPrefersDedicatedAllocation; 547 VkBool32 m_currentTestRequiresDedicatedAllocation; 548 }; 549 550 551 tcu::TestStatus BufferMemoryRequirementsDedicatedAllocation::testEntryPoint(Context& context, const VkBufferCreateFlags bufferFlags) 552 { 553 BufferMemoryRequirementsDedicatedAllocation test; 554 555 return test.execTest(context, bufferFlags); 556 } 557 558 void BufferMemoryRequirementsDedicatedAllocation::addFunctionTestCase (tcu::TestCaseGroup* group, 559 const std::string& name, 560 const std::string& desc, 561 VkBufferCreateFlags arg0) 562 { 563 addFunctionCase(group, name, desc, testEntryPoint, arg0); 564 } 565 566 void BufferMemoryRequirementsDedicatedAllocation::preTestChecks (Context& context, 567 const InstanceInterface& vki, 568 const VkPhysicalDevice physDevice, 569 const VkBufferCreateFlags flags) 570 { 571 if (!isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_dedicated_allocation")) 572 TCU_THROW(NotSupportedError, "VK_KHR_dedicated_allocation is not supported"); 573 574 BufferMemoryRequirementsExtended::preTestChecks(context, vki, physDevice, flags); 575 } 576 577 void BufferMemoryRequirementsDedicatedAllocation::updateMemoryRequirements (const DeviceInterface& vk, 578 const VkDevice device, 579 const VkDeviceSize size, 580 const VkBufferCreateFlags flags, 581 const VkBufferUsageFlags usage, 582 const bool all) 583 { 584 const deUint32 invalidVkBool32 = static_cast<deUint32>(~0); 585 586 VkMemoryDedicatedRequirements dedicatedRequirements = 587 { 588 VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR, // VkStructureType sType 589 DE_NULL, // void* pNext 590 invalidVkBool32, // VkBool32 prefersDedicatedAllocation 591 invalidVkBool32 // VkBool32 requiresDedicatedAllocation 592 }; 593 594 if (all) 595 { 596 m_allUsageFlagsRequirements = getBufferMemoryRequirements2(vk, device, size, flags, usage, &dedicatedRequirements); 597 m_allUsageFlagsPrefersDedicatedAllocation = dedicatedRequirements.prefersDedicatedAllocation; 598 m_allUsageFlagsRequiresDedicatedAllocation = dedicatedRequirements.requiresDedicatedAllocation; 599 600 TCU_CHECK(validValueVkBool32(m_allUsageFlagsPrefersDedicatedAllocation)); 601 // Test design expects m_allUsageFlagsRequiresDedicatedAllocation to be false 602 TCU_CHECK(m_allUsageFlagsRequiresDedicatedAllocation == VK_FALSE); 603 } 604 else 605 { 606 m_currentTestRequirements = getBufferMemoryRequirements2(vk, device, size, flags, usage, &dedicatedRequirements); 607 m_currentTestPrefersDedicatedAllocation = dedicatedRequirements.prefersDedicatedAllocation; 608 m_currentTestRequiresDedicatedAllocation = dedicatedRequirements.requiresDedicatedAllocation; 609 } 610 } 611 612 void BufferMemoryRequirementsDedicatedAllocation::verifyMemoryRequirements (tcu::ResultCollector& result, 613 const VkPhysicalDeviceMemoryProperties& deviceMemoryProperties, 614 const VkPhysicalDeviceLimits& limits, 615 const VkBufferCreateFlags bufferFlags, 616 const VkBufferUsageFlags usage) 617 { 618 BufferMemoryRequirementsExtended::verifyMemoryRequirements(result, deviceMemoryProperties, limits, bufferFlags, usage); 619 620 result.check(validValueVkBool32(m_currentTestPrefersDedicatedAllocation), 621 "Invalid VkBool32 value in m_currentTestPrefersDedicatedAllocation"); 622 623 result.check(m_currentTestRequiresDedicatedAllocation == VK_FALSE, 624 "Regular (non-shared) objects must not require dedicated allocations"); 625 626 result.check(m_currentTestPrefersDedicatedAllocation == VK_FALSE || m_currentTestPrefersDedicatedAllocation == VK_FALSE, 627 "Preferred and required flags for dedicated memory cannot be set to true at the same time"); 628 } 629 630 631 struct ImageTestParams 632 { 633 ImageTestParams (VkImageCreateFlags flags_, 634 VkImageTiling tiling_, 635 bool transient_) 636 : flags (flags_) 637 , tiling (tiling_) 638 , transient (transient_) 639 { 640 } 641 642 ImageTestParams (void) 643 { 644 } 645 646 VkImageCreateFlags flags; 647 VkImageTiling tiling; 648 bool transient; 649 }; 650 651 class IImageMemoryRequirements 652 { 653 public: 654 virtual void populateTestGroup (tcu::TestCaseGroup* group) = 0; 655 656 protected: 657 virtual void addFunctionTestCase (tcu::TestCaseGroup* group, 658 const std::string& name, 659 const std::string& desc, 660 const ImageTestParams arg0) = 0; 661 662 virtual tcu::TestStatus execTest (Context& context, 663 const ImageTestParams bufferFlags) = 0; 664 665 virtual void preTestChecks (Context& context, 666 const InstanceInterface& vki, 667 const VkPhysicalDevice physDevice, 668 const VkImageCreateFlags flags) = 0; 669 670 virtual void updateMemoryRequirements (const DeviceInterface& vk, 671 const VkDevice device) = 0; 672 673 virtual void verifyMemoryRequirements (tcu::ResultCollector& result, 674 const VkPhysicalDeviceMemoryProperties& deviceMemoryProperties) = 0; 675 }; 676 677 class ImageMemoryRequirementsOriginal : public IImageMemoryRequirements 678 { 679 static tcu::TestStatus testEntryPoint (Context& context, 680 const ImageTestParams params); 681 682 public: 683 virtual void populateTestGroup (tcu::TestCaseGroup* group); 684 685 protected: 686 virtual void addFunctionTestCase (tcu::TestCaseGroup* group, 687 const std::string& name, 688 const std::string& desc, 689 const ImageTestParams arg0); 690 691 virtual tcu::TestStatus execTest (Context& context, 692 const ImageTestParams params); 693 694 virtual void preTestChecks (Context& context, 695 const InstanceInterface& vki, 696 const VkPhysicalDevice physDevice, 697 const VkImageCreateFlags flags); 698 699 virtual void updateMemoryRequirements (const DeviceInterface& vk, 700 const VkDevice device); 701 702 virtual void verifyMemoryRequirements (tcu::ResultCollector& result, 703 const VkPhysicalDeviceMemoryProperties& deviceMemoryProperties); 704 705 private: 706 virtual bool isImageSupported (const deUint32 apiVersion, 707 const InstanceInterface& vki, 708 const VkPhysicalDevice physDevice, 709 const std::vector<std::string>& deviceExtensions, 710 const VkImageCreateInfo& info); 711 712 virtual bool isFormatMatchingAspect (const VkFormat format, 713 const VkImageAspectFlags aspect); 714 715 protected: 716 VkImageCreateInfo m_currentTestImageInfo; 717 VkMemoryRequirements m_currentTestRequirements; 718 }; 719 720 721 tcu::TestStatus ImageMemoryRequirementsOriginal::testEntryPoint (Context& context, const ImageTestParams params) 722 { 723 ImageMemoryRequirementsOriginal test; 724 725 return test.execTest(context, params); 726 } 727 728 void ImageMemoryRequirementsOriginal::populateTestGroup (tcu::TestCaseGroup* group) 729 { 730 const struct 731 { 732 VkImageCreateFlags flags; 733 bool transient; 734 const char* const name; 735 } imageFlagsCases[] = 736 { 737 { (VkImageCreateFlags)0, false, "regular" }, 738 { (VkImageCreateFlags)0, true, "transient" }, 739 { VK_IMAGE_CREATE_SPARSE_BINDING_BIT, false, "sparse" }, 740 { VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT, false, "sparse_residency" }, 741 { VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT, false, "sparse_aliased" }, 742 { VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT, false, "sparse_residency_aliased" }, 743 }; 744 745 de::MovePtr<tcu::TestCaseGroup> imageGroup(new tcu::TestCaseGroup(group->getTestContext(), "image", "")); 746 747 for (int flagsNdx = 0; flagsNdx < DE_LENGTH_OF_ARRAY(imageFlagsCases); ++flagsNdx) 748 for (int tilingNdx = 0; tilingNdx <= 1; ++tilingNdx) 749 { 750 ImageTestParams params; 751 std::ostringstream caseName; 752 753 params.flags = imageFlagsCases[flagsNdx].flags; 754 params.transient = imageFlagsCases[flagsNdx].transient; 755 caseName << imageFlagsCases[flagsNdx].name; 756 757 if (tilingNdx != 0) 758 { 759 params.tiling = VK_IMAGE_TILING_OPTIMAL; 760 caseName << "_tiling_optimal"; 761 } 762 else 763 { 764 params.tiling = VK_IMAGE_TILING_LINEAR; 765 caseName << "_tiling_linear"; 766 } 767 768 if ((params.flags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) && (params.tiling == VK_IMAGE_TILING_LINEAR)) 769 continue; 770 771 addFunctionTestCase(imageGroup.get(), caseName.str(), "", params); 772 } 773 774 group->addChild(imageGroup.release()); 775 } 776 777 void ImageMemoryRequirementsOriginal::addFunctionTestCase (tcu::TestCaseGroup* group, 778 const std::string& name, 779 const std::string& desc, 780 const ImageTestParams arg0) 781 { 782 addFunctionCase(group, name, desc, testEntryPoint, arg0); 783 } 784 785 void ImageMemoryRequirementsOriginal::preTestChecks (Context& , 786 const InstanceInterface& vki, 787 const VkPhysicalDevice physDevice, 788 const VkImageCreateFlags createFlags) 789 { 790 const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice); 791 792 if ((createFlags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) && !features.sparseBinding) 793 TCU_THROW(NotSupportedError, "Feature not supported: sparseBinding"); 794 795 if ((createFlags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) && !(features.sparseResidencyImage2D || features.sparseResidencyImage3D)) 796 TCU_THROW(NotSupportedError, "Feature not supported: sparseResidencyImage (2D and 3D)"); 797 798 if ((createFlags & VK_IMAGE_CREATE_SPARSE_ALIASED_BIT) && !features.sparseResidencyAliased) 799 TCU_THROW(NotSupportedError, "Feature not supported: sparseResidencyAliased"); 800 } 801 802 void ImageMemoryRequirementsOriginal::updateMemoryRequirements (const DeviceInterface& vk, 803 const VkDevice device) 804 { 805 const Unique<VkImage> image(createImage(vk, device, &m_currentTestImageInfo)); 806 807 m_currentTestRequirements = getImageMemoryRequirements(vk, device, *image); 808 } 809 810 void ImageMemoryRequirementsOriginal::verifyMemoryRequirements (tcu::ResultCollector& result, 811 const VkPhysicalDeviceMemoryProperties& deviceMemoryProperties) 812 { 813 if (result.check(m_currentTestRequirements.memoryTypeBits != 0, "VkMemoryRequirements memoryTypeBits has no bits set")) 814 { 815 typedef std::vector<deUint32>::const_iterator IndexIterator; 816 const std::vector<deUint32> usedMemoryTypeIndices = bitsToIndices(m_currentTestRequirements.memoryTypeBits); 817 bool deviceLocalMemoryFound = false; 818 bool hostVisibleCoherentMemoryFound = false; 819 820 for (IndexIterator memoryTypeNdx = usedMemoryTypeIndices.begin(); memoryTypeNdx != usedMemoryTypeIndices.end(); ++memoryTypeNdx) 821 { 822 if (*memoryTypeNdx >= deviceMemoryProperties.memoryTypeCount) 823 { 824 result.fail("VkMemoryRequirements memoryTypeBits contains bits for non-existing memory types"); 825 continue; 826 } 827 828 const VkMemoryPropertyFlags memoryPropertyFlags = deviceMemoryProperties.memoryTypes[*memoryTypeNdx].propertyFlags; 829 830 if (memoryPropertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) 831 deviceLocalMemoryFound = true; 832 833 if (memoryPropertyFlags & (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) 834 hostVisibleCoherentMemoryFound = true; 835 836 if (memoryPropertyFlags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) 837 { 838 result.check((m_currentTestImageInfo.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) != 0u, 839 "Memory type includes VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT for a non-transient attachment image"); 840 } 841 } 842 843 result.check(deIsPowerOfTwo64(static_cast<deUint64>(m_currentTestRequirements.alignment)) == DE_TRUE, 844 "VkMemoryRequirements alignment isn't power of two"); 845 846 result.check(deviceLocalMemoryFound, 847 "None of the required memory types included VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT"); 848 849 result.check(m_currentTestImageInfo.tiling == VK_IMAGE_TILING_OPTIMAL || hostVisibleCoherentMemoryFound, 850 "Required memory type doesn't include VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT and VK_MEMORY_PROPERTY_HOST_COHERENT_BIT"); 851 } 852 } 853 854 bool isUsageMatchesFeatures (const VkImageUsageFlags usage, const VkFormatFeatureFlags featureFlags) 855 { 856 if ((usage & VK_IMAGE_USAGE_SAMPLED_BIT) && (featureFlags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) 857 return true; 858 if ((usage & VK_IMAGE_USAGE_STORAGE_BIT) && (featureFlags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)) 859 return true; 860 if ((usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) && (featureFlags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) 861 return true; 862 if ((usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) && (featureFlags & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) 863 return true; 864 865 return false; 866 } 867 868 //! This catches both invalid as well as legal but unsupported combinations of image parameters 869 bool ImageMemoryRequirementsOriginal::isImageSupported (const deUint32 apiVersion, const InstanceInterface& vki, const VkPhysicalDevice physDevice, const std::vector<std::string>& deviceExtensions, const VkImageCreateInfo& info) 870 { 871 DE_ASSERT(info.extent.width >= 1u && info.extent.height >= 1u && info.extent.depth >= 1u); 872 873 if ((isYCbCrFormat(info.format) 874 && (info.imageType != VK_IMAGE_TYPE_2D 875 || info.mipLevels != 1 876 || info.arrayLayers != 1 877 || info.samples != VK_SAMPLE_COUNT_1_BIT)) 878 || !isDeviceExtensionSupported(apiVersion, deviceExtensions, "VK_KHR_sampler_ycbcr_conversion")) 879 { 880 return false; 881 } 882 883 if (info.imageType == VK_IMAGE_TYPE_1D) 884 { 885 DE_ASSERT(info.extent.height == 1u && info.extent.depth == 1u); 886 } 887 else if (info.imageType == VK_IMAGE_TYPE_2D) 888 { 889 DE_ASSERT(info.extent.depth == 1u); 890 891 if (info.flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) 892 { 893 DE_ASSERT(info.extent.width == info.extent.height); 894 DE_ASSERT(info.arrayLayers >= 6u && (info.arrayLayers % 6u) == 0u); 895 } 896 } 897 898 if ((info.flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) && info.imageType != VK_IMAGE_TYPE_2D) 899 return false; 900 901 if ((info.samples != VK_SAMPLE_COUNT_1_BIT) && 902 (info.imageType != VK_IMAGE_TYPE_2D || (info.flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) || info.tiling != VK_IMAGE_TILING_OPTIMAL || info.mipLevels > 1u)) 903 return false; 904 905 if ((info.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) && 906 (info.usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) == 0u) 907 return false; 908 909 const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice); 910 911 if (info.flags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) 912 { 913 DE_ASSERT(info.tiling == VK_IMAGE_TILING_OPTIMAL); 914 915 if (info.imageType == VK_IMAGE_TYPE_2D && !features.sparseResidencyImage2D) 916 return false; 917 if (info.imageType == VK_IMAGE_TYPE_3D && !features.sparseResidencyImage3D) 918 return false; 919 if (info.samples == VK_SAMPLE_COUNT_2_BIT && !features.sparseResidency2Samples) 920 return false; 921 if (info.samples == VK_SAMPLE_COUNT_4_BIT && !features.sparseResidency4Samples) 922 return false; 923 if (info.samples == VK_SAMPLE_COUNT_8_BIT && !features.sparseResidency8Samples) 924 return false; 925 if (info.samples == VK_SAMPLE_COUNT_16_BIT && !features.sparseResidency16Samples) 926 return false; 927 if (info.samples == VK_SAMPLE_COUNT_32_BIT || info.samples == VK_SAMPLE_COUNT_64_BIT) 928 return false; 929 } 930 931 if (info.samples != VK_SAMPLE_COUNT_1_BIT && (info.usage & VK_IMAGE_USAGE_STORAGE_BIT) && !features.shaderStorageImageMultisample) 932 return false; 933 934 switch (info.format) 935 { 936 case VK_FORMAT_BC1_RGB_UNORM_BLOCK: 937 case VK_FORMAT_BC1_RGB_SRGB_BLOCK: 938 case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: 939 case VK_FORMAT_BC1_RGBA_SRGB_BLOCK: 940 case VK_FORMAT_BC2_UNORM_BLOCK: 941 case VK_FORMAT_BC2_SRGB_BLOCK: 942 case VK_FORMAT_BC3_UNORM_BLOCK: 943 case VK_FORMAT_BC3_SRGB_BLOCK: 944 case VK_FORMAT_BC4_UNORM_BLOCK: 945 case VK_FORMAT_BC4_SNORM_BLOCK: 946 case VK_FORMAT_BC5_UNORM_BLOCK: 947 case VK_FORMAT_BC5_SNORM_BLOCK: 948 case VK_FORMAT_BC6H_UFLOAT_BLOCK: 949 case VK_FORMAT_BC6H_SFLOAT_BLOCK: 950 case VK_FORMAT_BC7_UNORM_BLOCK: 951 case VK_FORMAT_BC7_SRGB_BLOCK: 952 if (!features.textureCompressionBC) 953 return false; 954 break; 955 956 case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: 957 case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK: 958 case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK: 959 case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK: 960 case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK: 961 case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK: 962 case VK_FORMAT_EAC_R11_UNORM_BLOCK: 963 case VK_FORMAT_EAC_R11_SNORM_BLOCK: 964 case VK_FORMAT_EAC_R11G11_UNORM_BLOCK: 965 case VK_FORMAT_EAC_R11G11_SNORM_BLOCK: 966 if (!features.textureCompressionETC2) 967 return false; 968 break; 969 970 case VK_FORMAT_ASTC_4x4_UNORM_BLOCK: 971 case VK_FORMAT_ASTC_4x4_SRGB_BLOCK: 972 case VK_FORMAT_ASTC_5x4_UNORM_BLOCK: 973 case VK_FORMAT_ASTC_5x4_SRGB_BLOCK: 974 case VK_FORMAT_ASTC_5x5_UNORM_BLOCK: 975 case VK_FORMAT_ASTC_5x5_SRGB_BLOCK: 976 case VK_FORMAT_ASTC_6x5_UNORM_BLOCK: 977 case VK_FORMAT_ASTC_6x5_SRGB_BLOCK: 978 case VK_FORMAT_ASTC_6x6_UNORM_BLOCK: 979 case VK_FORMAT_ASTC_6x6_SRGB_BLOCK: 980 case VK_FORMAT_ASTC_8x5_UNORM_BLOCK: 981 case VK_FORMAT_ASTC_8x5_SRGB_BLOCK: 982 case VK_FORMAT_ASTC_8x6_UNORM_BLOCK: 983 case VK_FORMAT_ASTC_8x6_SRGB_BLOCK: 984 case VK_FORMAT_ASTC_8x8_UNORM_BLOCK: 985 case VK_FORMAT_ASTC_8x8_SRGB_BLOCK: 986 case VK_FORMAT_ASTC_10x5_UNORM_BLOCK: 987 case VK_FORMAT_ASTC_10x5_SRGB_BLOCK: 988 case VK_FORMAT_ASTC_10x6_UNORM_BLOCK: 989 case VK_FORMAT_ASTC_10x6_SRGB_BLOCK: 990 case VK_FORMAT_ASTC_10x8_UNORM_BLOCK: 991 case VK_FORMAT_ASTC_10x8_SRGB_BLOCK: 992 case VK_FORMAT_ASTC_10x10_UNORM_BLOCK: 993 case VK_FORMAT_ASTC_10x10_SRGB_BLOCK: 994 case VK_FORMAT_ASTC_12x10_UNORM_BLOCK: 995 case VK_FORMAT_ASTC_12x10_SRGB_BLOCK: 996 case VK_FORMAT_ASTC_12x12_UNORM_BLOCK: 997 case VK_FORMAT_ASTC_12x12_SRGB_BLOCK: 998 if (!features.textureCompressionASTC_LDR) 999 return false; 1000 break; 1001 1002 default: 1003 break; 1004 } 1005 1006 const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(vki, physDevice, info.format); 1007 const VkFormatFeatureFlags formatFeatures = (info.tiling == VK_IMAGE_TILING_LINEAR ? formatProperties.linearTilingFeatures 1008 : formatProperties.optimalTilingFeatures); 1009 1010 if (!isUsageMatchesFeatures(info.usage, formatFeatures)) 1011 return false; 1012 1013 VkImageFormatProperties imageFormatProperties; 1014 const VkResult result = vki.getPhysicalDeviceImageFormatProperties( 1015 physDevice, info.format, info.imageType, info.tiling, info.usage, info.flags, &imageFormatProperties); 1016 1017 if (result == VK_SUCCESS) 1018 { 1019 if (info.arrayLayers > imageFormatProperties.maxArrayLayers) 1020 return false; 1021 if (info.mipLevels > imageFormatProperties.maxMipLevels) 1022 return false; 1023 if ((info.samples & imageFormatProperties.sampleCounts) == 0u) 1024 return false; 1025 } 1026 1027 return result == VK_SUCCESS; 1028 } 1029 1030 VkExtent3D makeExtentForImage (const VkImageType imageType) 1031 { 1032 VkExtent3D extent = { 64u, 64u, 4u }; 1033 1034 if (imageType == VK_IMAGE_TYPE_1D) 1035 extent.height = extent.depth = 1u; 1036 else if (imageType == VK_IMAGE_TYPE_2D) 1037 extent.depth = 1u; 1038 1039 return extent; 1040 } 1041 1042 bool ImageMemoryRequirementsOriginal::isFormatMatchingAspect (const VkFormat format, const VkImageAspectFlags aspect) 1043 { 1044 DE_ASSERT(aspect == VK_IMAGE_ASPECT_COLOR_BIT || aspect == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)); 1045 1046 // D/S formats are laid out next to each other in the enum 1047 const bool isDepthStencilFormat = (format >= VK_FORMAT_D16_UNORM && format <= VK_FORMAT_D32_SFLOAT_S8_UINT); 1048 1049 return (aspect == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) == isDepthStencilFormat; 1050 } 1051 1052 std::string getImageInfoString (const VkImageCreateInfo& imageInfo) 1053 { 1054 std::ostringstream str; 1055 1056 switch (imageInfo.imageType) 1057 { 1058 case VK_IMAGE_TYPE_1D: str << "1D "; break; 1059 case VK_IMAGE_TYPE_2D: str << "2D "; break; 1060 case VK_IMAGE_TYPE_3D: str << "3D "; break; 1061 default: break; 1062 } 1063 1064 switch (imageInfo.tiling) 1065 { 1066 case VK_IMAGE_TILING_OPTIMAL: str << "(optimal) "; break; 1067 case VK_IMAGE_TILING_LINEAR: str << "(linear) "; break; 1068 default: break; 1069 } 1070 1071 str << "extent:[" << imageInfo.extent.width << ", " << imageInfo.extent.height << ", " << imageInfo.extent.depth << "] "; 1072 str << imageInfo.format << " "; 1073 str << "samples:" << static_cast<deUint32>(imageInfo.samples) << " "; 1074 str << "flags:" << static_cast<deUint32>(imageInfo.flags) << " "; 1075 str << "usage:" << static_cast<deUint32>(imageInfo.usage) << " "; 1076 1077 return str.str(); 1078 } 1079 1080 tcu::TestStatus ImageMemoryRequirementsOriginal::execTest (Context& context, const ImageTestParams params) 1081 { 1082 const VkFormat formats[] = 1083 { 1084 VK_FORMAT_R4G4_UNORM_PACK8, 1085 VK_FORMAT_R4G4B4A4_UNORM_PACK16, 1086 VK_FORMAT_B4G4R4A4_UNORM_PACK16, 1087 VK_FORMAT_R5G6B5_UNORM_PACK16, 1088 VK_FORMAT_B5G6R5_UNORM_PACK16, 1089 VK_FORMAT_R5G5B5A1_UNORM_PACK16, 1090 VK_FORMAT_B5G5R5A1_UNORM_PACK16, 1091 VK_FORMAT_A1R5G5B5_UNORM_PACK16, 1092 VK_FORMAT_R8_UNORM, 1093 VK_FORMAT_R8_SNORM, 1094 VK_FORMAT_R8_USCALED, 1095 VK_FORMAT_R8_SSCALED, 1096 VK_FORMAT_R8_UINT, 1097 VK_FORMAT_R8_SINT, 1098 VK_FORMAT_R8_SRGB, 1099 VK_FORMAT_R8G8_UNORM, 1100 VK_FORMAT_R8G8_SNORM, 1101 VK_FORMAT_R8G8_USCALED, 1102 VK_FORMAT_R8G8_SSCALED, 1103 VK_FORMAT_R8G8_UINT, 1104 VK_FORMAT_R8G8_SINT, 1105 VK_FORMAT_R8G8_SRGB, 1106 VK_FORMAT_R8G8B8_UNORM, 1107 VK_FORMAT_R8G8B8_SNORM, 1108 VK_FORMAT_R8G8B8_USCALED, 1109 VK_FORMAT_R8G8B8_SSCALED, 1110 VK_FORMAT_R8G8B8_UINT, 1111 VK_FORMAT_R8G8B8_SINT, 1112 VK_FORMAT_R8G8B8_SRGB, 1113 VK_FORMAT_B8G8R8_UNORM, 1114 VK_FORMAT_B8G8R8_SNORM, 1115 VK_FORMAT_B8G8R8_USCALED, 1116 VK_FORMAT_B8G8R8_SSCALED, 1117 VK_FORMAT_B8G8R8_UINT, 1118 VK_FORMAT_B8G8R8_SINT, 1119 VK_FORMAT_B8G8R8_SRGB, 1120 VK_FORMAT_R8G8B8A8_UNORM, 1121 VK_FORMAT_R8G8B8A8_SNORM, 1122 VK_FORMAT_R8G8B8A8_USCALED, 1123 VK_FORMAT_R8G8B8A8_SSCALED, 1124 VK_FORMAT_R8G8B8A8_UINT, 1125 VK_FORMAT_R8G8B8A8_SINT, 1126 VK_FORMAT_R8G8B8A8_SRGB, 1127 VK_FORMAT_B8G8R8A8_UNORM, 1128 VK_FORMAT_B8G8R8A8_SNORM, 1129 VK_FORMAT_B8G8R8A8_USCALED, 1130 VK_FORMAT_B8G8R8A8_SSCALED, 1131 VK_FORMAT_B8G8R8A8_UINT, 1132 VK_FORMAT_B8G8R8A8_SINT, 1133 VK_FORMAT_B8G8R8A8_SRGB, 1134 VK_FORMAT_A8B8G8R8_UNORM_PACK32, 1135 VK_FORMAT_A8B8G8R8_SNORM_PACK32, 1136 VK_FORMAT_A8B8G8R8_USCALED_PACK32, 1137 VK_FORMAT_A8B8G8R8_SSCALED_PACK32, 1138 VK_FORMAT_A8B8G8R8_UINT_PACK32, 1139 VK_FORMAT_A8B8G8R8_SINT_PACK32, 1140 VK_FORMAT_A8B8G8R8_SRGB_PACK32, 1141 VK_FORMAT_A2R10G10B10_UNORM_PACK32, 1142 VK_FORMAT_A2R10G10B10_SNORM_PACK32, 1143 VK_FORMAT_A2R10G10B10_USCALED_PACK32, 1144 VK_FORMAT_A2R10G10B10_SSCALED_PACK32, 1145 VK_FORMAT_A2R10G10B10_UINT_PACK32, 1146 VK_FORMAT_A2R10G10B10_SINT_PACK32, 1147 VK_FORMAT_A2B10G10R10_UNORM_PACK32, 1148 VK_FORMAT_A2B10G10R10_SNORM_PACK32, 1149 VK_FORMAT_A2B10G10R10_USCALED_PACK32, 1150 VK_FORMAT_A2B10G10R10_SSCALED_PACK32, 1151 VK_FORMAT_A2B10G10R10_UINT_PACK32, 1152 VK_FORMAT_A2B10G10R10_SINT_PACK32, 1153 VK_FORMAT_R16_UNORM, 1154 VK_FORMAT_R16_SNORM, 1155 VK_FORMAT_R16_USCALED, 1156 VK_FORMAT_R16_SSCALED, 1157 VK_FORMAT_R16_UINT, 1158 VK_FORMAT_R16_SINT, 1159 VK_FORMAT_R16_SFLOAT, 1160 VK_FORMAT_R16G16_UNORM, 1161 VK_FORMAT_R16G16_SNORM, 1162 VK_FORMAT_R16G16_USCALED, 1163 VK_FORMAT_R16G16_SSCALED, 1164 VK_FORMAT_R16G16_UINT, 1165 VK_FORMAT_R16G16_SINT, 1166 VK_FORMAT_R16G16_SFLOAT, 1167 VK_FORMAT_R16G16B16_UNORM, 1168 VK_FORMAT_R16G16B16_SNORM, 1169 VK_FORMAT_R16G16B16_USCALED, 1170 VK_FORMAT_R16G16B16_SSCALED, 1171 VK_FORMAT_R16G16B16_UINT, 1172 VK_FORMAT_R16G16B16_SINT, 1173 VK_FORMAT_R16G16B16_SFLOAT, 1174 VK_FORMAT_R16G16B16A16_UNORM, 1175 VK_FORMAT_R16G16B16A16_SNORM, 1176 VK_FORMAT_R16G16B16A16_USCALED, 1177 VK_FORMAT_R16G16B16A16_SSCALED, 1178 VK_FORMAT_R16G16B16A16_UINT, 1179 VK_FORMAT_R16G16B16A16_SINT, 1180 VK_FORMAT_R16G16B16A16_SFLOAT, 1181 VK_FORMAT_R32_UINT, 1182 VK_FORMAT_R32_SINT, 1183 VK_FORMAT_R32_SFLOAT, 1184 VK_FORMAT_R32G32_UINT, 1185 VK_FORMAT_R32G32_SINT, 1186 VK_FORMAT_R32G32_SFLOAT, 1187 VK_FORMAT_R32G32B32_UINT, 1188 VK_FORMAT_R32G32B32_SINT, 1189 VK_FORMAT_R32G32B32_SFLOAT, 1190 VK_FORMAT_R32G32B32A32_UINT, 1191 VK_FORMAT_R32G32B32A32_SINT, 1192 VK_FORMAT_R32G32B32A32_SFLOAT, 1193 VK_FORMAT_R64_UINT, 1194 VK_FORMAT_R64_SINT, 1195 VK_FORMAT_R64_SFLOAT, 1196 VK_FORMAT_R64G64_UINT, 1197 VK_FORMAT_R64G64_SINT, 1198 VK_FORMAT_R64G64_SFLOAT, 1199 VK_FORMAT_R64G64B64_UINT, 1200 VK_FORMAT_R64G64B64_SINT, 1201 VK_FORMAT_R64G64B64_SFLOAT, 1202 VK_FORMAT_R64G64B64A64_UINT, 1203 VK_FORMAT_R64G64B64A64_SINT, 1204 VK_FORMAT_R64G64B64A64_SFLOAT, 1205 VK_FORMAT_B10G11R11_UFLOAT_PACK32, 1206 VK_FORMAT_E5B9G9R9_UFLOAT_PACK32, 1207 VK_FORMAT_D16_UNORM, 1208 VK_FORMAT_X8_D24_UNORM_PACK32, 1209 VK_FORMAT_D32_SFLOAT, 1210 VK_FORMAT_S8_UINT, 1211 VK_FORMAT_D16_UNORM_S8_UINT, 1212 VK_FORMAT_D24_UNORM_S8_UINT, 1213 VK_FORMAT_D32_SFLOAT_S8_UINT, 1214 VK_FORMAT_BC1_RGB_UNORM_BLOCK, 1215 VK_FORMAT_BC1_RGB_SRGB_BLOCK, 1216 VK_FORMAT_BC1_RGBA_UNORM_BLOCK, 1217 VK_FORMAT_BC1_RGBA_SRGB_BLOCK, 1218 VK_FORMAT_BC2_UNORM_BLOCK, 1219 VK_FORMAT_BC2_SRGB_BLOCK, 1220 VK_FORMAT_BC3_UNORM_BLOCK, 1221 VK_FORMAT_BC3_SRGB_BLOCK, 1222 VK_FORMAT_BC4_UNORM_BLOCK, 1223 VK_FORMAT_BC4_SNORM_BLOCK, 1224 VK_FORMAT_BC5_UNORM_BLOCK, 1225 VK_FORMAT_BC5_SNORM_BLOCK, 1226 VK_FORMAT_BC6H_UFLOAT_BLOCK, 1227 VK_FORMAT_BC6H_SFLOAT_BLOCK, 1228 VK_FORMAT_BC7_UNORM_BLOCK, 1229 VK_FORMAT_BC7_SRGB_BLOCK, 1230 VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, 1231 VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK, 1232 VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK, 1233 VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK, 1234 VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, 1235 VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK, 1236 VK_FORMAT_EAC_R11_UNORM_BLOCK, 1237 VK_FORMAT_EAC_R11_SNORM_BLOCK, 1238 VK_FORMAT_EAC_R11G11_UNORM_BLOCK, 1239 VK_FORMAT_EAC_R11G11_SNORM_BLOCK, 1240 VK_FORMAT_ASTC_4x4_UNORM_BLOCK, 1241 VK_FORMAT_ASTC_4x4_SRGB_BLOCK, 1242 VK_FORMAT_ASTC_5x4_UNORM_BLOCK, 1243 VK_FORMAT_ASTC_5x4_SRGB_BLOCK, 1244 VK_FORMAT_ASTC_5x5_UNORM_BLOCK, 1245 VK_FORMAT_ASTC_5x5_SRGB_BLOCK, 1246 VK_FORMAT_ASTC_6x5_UNORM_BLOCK, 1247 VK_FORMAT_ASTC_6x5_SRGB_BLOCK, 1248 VK_FORMAT_ASTC_6x6_UNORM_BLOCK, 1249 VK_FORMAT_ASTC_6x6_SRGB_BLOCK, 1250 VK_FORMAT_ASTC_8x5_UNORM_BLOCK, 1251 VK_FORMAT_ASTC_8x5_SRGB_BLOCK, 1252 VK_FORMAT_ASTC_8x6_UNORM_BLOCK, 1253 VK_FORMAT_ASTC_8x6_SRGB_BLOCK, 1254 VK_FORMAT_ASTC_8x8_UNORM_BLOCK, 1255 VK_FORMAT_ASTC_8x8_SRGB_BLOCK, 1256 VK_FORMAT_ASTC_10x5_UNORM_BLOCK, 1257 VK_FORMAT_ASTC_10x5_SRGB_BLOCK, 1258 VK_FORMAT_ASTC_10x6_UNORM_BLOCK, 1259 VK_FORMAT_ASTC_10x6_SRGB_BLOCK, 1260 VK_FORMAT_ASTC_10x8_UNORM_BLOCK, 1261 VK_FORMAT_ASTC_10x8_SRGB_BLOCK, 1262 VK_FORMAT_ASTC_10x10_UNORM_BLOCK, 1263 VK_FORMAT_ASTC_10x10_SRGB_BLOCK, 1264 VK_FORMAT_ASTC_12x10_UNORM_BLOCK, 1265 VK_FORMAT_ASTC_12x10_SRGB_BLOCK, 1266 VK_FORMAT_ASTC_12x12_UNORM_BLOCK, 1267 VK_FORMAT_ASTC_12x12_SRGB_BLOCK, 1268 VK_FORMAT_G8B8G8R8_422_UNORM_KHR, 1269 VK_FORMAT_B8G8R8G8_422_UNORM_KHR, 1270 VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR, 1271 VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR, 1272 VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM_KHR, 1273 VK_FORMAT_G8_B8R8_2PLANE_422_UNORM_KHR, 1274 VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM_KHR, 1275 VK_FORMAT_R10X6_UNORM_PACK16_KHR, 1276 VK_FORMAT_R10X6G10X6_UNORM_2PACK16_KHR, 1277 VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16_KHR, 1278 VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16_KHR, 1279 VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16_KHR, 1280 VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_KHR, 1281 VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_KHR, 1282 VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16_KHR, 1283 VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16_KHR, 1284 VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16_KHR, 1285 VK_FORMAT_R12X4_UNORM_PACK16_KHR, 1286 VK_FORMAT_R12X4G12X4_UNORM_2PACK16_KHR, 1287 VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16_KHR, 1288 VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16_KHR, 1289 VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16_KHR, 1290 VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_KHR, 1291 VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_KHR, 1292 VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16_KHR, 1293 VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16_KHR, 1294 VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16_KHR, 1295 VK_FORMAT_G16B16G16R16_422_UNORM_KHR, 1296 VK_FORMAT_B16G16R16G16_422_UNORM_KHR, 1297 VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM_KHR, 1298 VK_FORMAT_G16_B16R16_2PLANE_420_UNORM_KHR, 1299 VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM_KHR, 1300 VK_FORMAT_G16_B16R16_2PLANE_422_UNORM_KHR, 1301 VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM_KHR 1302 }; 1303 const DeviceInterface& vk = context.getDeviceInterface(); 1304 const InstanceInterface& vki = context.getInstanceInterface(); 1305 const VkDevice device = context.getDevice(); 1306 const VkPhysicalDevice physDevice = context.getPhysicalDevice(); 1307 const VkImageCreateFlags sparseFlags = VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT; 1308 const VkImageUsageFlags transientFlags = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT; 1309 1310 preTestChecks(context, vki, physDevice, params.flags); 1311 1312 const VkPhysicalDeviceMemoryProperties memoryProperties = getPhysicalDeviceMemoryProperties(vki, physDevice); 1313 const deUint32 notInitializedBits = ~0u; 1314 const VkImageAspectFlags colorAspect = VK_IMAGE_ASPECT_COLOR_BIT; 1315 const VkImageAspectFlags depthStencilAspect = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; 1316 const VkImageAspectFlags allAspects[2] = { colorAspect, depthStencilAspect }; 1317 tcu::TestLog& log = context.getTestContext().getLog(); 1318 bool allPass = true; 1319 deUint32 numCheckedImages = 0u; 1320 1321 log << tcu::TestLog::Message << "Verify memory requirements for the following parameter combinations:" << tcu::TestLog::EndMessage; 1322 1323 for (deUint32 loopAspectNdx = 0u; loopAspectNdx < DE_LENGTH_OF_ARRAY(allAspects); ++loopAspectNdx) 1324 { 1325 const VkImageAspectFlags aspect = allAspects[loopAspectNdx]; 1326 deUint32 previousMemoryTypeBits = notInitializedBits; 1327 1328 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++) 1329 { 1330 const VkFormat format = formats[formatNdx]; 1331 1332 if (isFormatMatchingAspect(format, aspect)) 1333 { 1334 // memoryTypeBits may differ between depth/stencil formats 1335 if (aspect == depthStencilAspect) 1336 previousMemoryTypeBits = notInitializedBits; 1337 1338 for (VkImageType loopImageType = VK_IMAGE_TYPE_1D; loopImageType != VK_IMAGE_TYPE_LAST; loopImageType = nextEnum(loopImageType)) 1339 for (VkImageCreateFlags loopCreateFlags = (VkImageCreateFlags)0; loopCreateFlags <= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT; loopCreateFlags = nextFlagExcluding(loopCreateFlags, sparseFlags)) 1340 for (VkImageUsageFlags loopUsageFlags = VK_IMAGE_USAGE_TRANSFER_SRC_BIT; loopUsageFlags <= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT; loopUsageFlags = nextFlagExcluding(loopUsageFlags, transientFlags)) 1341 for (VkSampleCountFlagBits loopSampleCount = VK_SAMPLE_COUNT_1_BIT; loopSampleCount <= VK_SAMPLE_COUNT_16_BIT; loopSampleCount = nextFlag(loopSampleCount)) 1342 { 1343 const VkImageCreateFlags actualCreateFlags = loopCreateFlags | params.flags; 1344 const VkImageUsageFlags actualUsageFlags = loopUsageFlags | (params.transient ? VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT : (VkImageUsageFlagBits)0); 1345 const bool isCube = (actualCreateFlags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) != 0u; 1346 const VkImageCreateInfo imageInfo = 1347 { 1348 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 1349 DE_NULL, // const void* pNext; 1350 actualCreateFlags, // VkImageCreateFlags flags; 1351 loopImageType, // VkImageType imageType; 1352 format, // VkFormat format; 1353 makeExtentForImage(loopImageType), // VkExtent3D extent; 1354 1u, // uint32_t mipLevels; 1355 (isCube ? 6u : 1u), // uint32_t arrayLayers; 1356 loopSampleCount, // VkSampleCountFlagBits samples; 1357 params.tiling, // VkImageTiling tiling; 1358 actualUsageFlags, // VkImageUsageFlags usage; 1359 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1360 0u, // uint32_t queueFamilyIndexCount; 1361 DE_NULL, // const uint32_t* pQueueFamilyIndices; 1362 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 1363 }; 1364 1365 m_currentTestImageInfo = imageInfo; 1366 1367 if (!isImageSupported(context.getUsedApiVersion(), vki, physDevice, context.getDeviceExtensions(), m_currentTestImageInfo)) 1368 continue; 1369 1370 log << tcu::TestLog::Message << "- " << getImageInfoString(m_currentTestImageInfo) << tcu::TestLog::EndMessage; 1371 ++numCheckedImages; 1372 1373 tcu::ResultCollector result(log, "ERROR: "); 1374 1375 updateMemoryRequirements(vk, device); 1376 1377 verifyMemoryRequirements(result, memoryProperties); 1378 1379 // For the same tiling, transient usage, and sparse flags, (and format, if D/S) memoryTypeBits must be the same for all images 1380 result.check((previousMemoryTypeBits == notInitializedBits) || (m_currentTestRequirements.memoryTypeBits == previousMemoryTypeBits), 1381 "memoryTypeBits differ from the ones in the previous image configuration"); 1382 1383 if (result.getResult() != QP_TEST_RESULT_PASS) 1384 allPass = false; 1385 1386 previousMemoryTypeBits = m_currentTestRequirements.memoryTypeBits; 1387 } 1388 } 1389 } 1390 } 1391 1392 if (numCheckedImages == 0u) 1393 log << tcu::TestLog::Message << "NOTE: No supported image configurations -- nothing to check" << tcu::TestLog::EndMessage; 1394 1395 return allPass ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Some memory requirements were incorrect"); 1396 } 1397 1398 1399 class ImageMemoryRequirementsExtended : public ImageMemoryRequirementsOriginal 1400 { 1401 public: 1402 static tcu::TestStatus testEntryPoint (Context& context, 1403 const ImageTestParams params); 1404 1405 protected: 1406 virtual void addFunctionTestCase (tcu::TestCaseGroup* group, 1407 const std::string& name, 1408 const std::string& desc, 1409 const ImageTestParams arg0); 1410 1411 virtual void preTestChecks (Context& context, 1412 const InstanceInterface& vki, 1413 const VkPhysicalDevice physDevice, 1414 const VkImageCreateFlags flags); 1415 1416 virtual void updateMemoryRequirements (const DeviceInterface& vk, 1417 const VkDevice device); 1418 }; 1419 1420 1421 tcu::TestStatus ImageMemoryRequirementsExtended::testEntryPoint (Context& context, const ImageTestParams params) 1422 { 1423 ImageMemoryRequirementsExtended test; 1424 1425 return test.execTest(context, params); 1426 } 1427 1428 void ImageMemoryRequirementsExtended::addFunctionTestCase (tcu::TestCaseGroup* group, 1429 const std::string& name, 1430 const std::string& desc, 1431 const ImageTestParams arg0) 1432 { 1433 addFunctionCase(group, name, desc, testEntryPoint, arg0); 1434 } 1435 1436 void ImageMemoryRequirementsExtended::preTestChecks (Context& context, 1437 const InstanceInterface& vki, 1438 const VkPhysicalDevice physDevice, 1439 const VkImageCreateFlags createFlags) 1440 { 1441 const std::string extensionName("VK_KHR_get_memory_requirements2"); 1442 1443 if (!isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), extensionName)) 1444 TCU_THROW(NotSupportedError, std::string(extensionName + " is not supported").c_str()); 1445 1446 ImageMemoryRequirementsOriginal::preTestChecks (context, vki, physDevice, createFlags); 1447 } 1448 1449 void ImageMemoryRequirementsExtended::updateMemoryRequirements (const DeviceInterface& vk, 1450 const VkDevice device) 1451 { 1452 m_currentTestRequirements = getImageMemoryRequirements2(vk, device, m_currentTestImageInfo); 1453 } 1454 1455 1456 class ImageMemoryRequirementsDedicatedAllocation : public ImageMemoryRequirementsExtended 1457 { 1458 public: 1459 static tcu::TestStatus testEntryPoint (Context& context, 1460 const ImageTestParams params); 1461 1462 protected: 1463 virtual void addFunctionTestCase (tcu::TestCaseGroup* group, 1464 const std::string& name, 1465 const std::string& desc, 1466 const ImageTestParams arg0); 1467 1468 virtual void preTestChecks (Context& context, 1469 const InstanceInterface& vki, 1470 const VkPhysicalDevice physDevice, 1471 const VkImageCreateFlags flags); 1472 1473 virtual void updateMemoryRequirements (const DeviceInterface& vk, 1474 const VkDevice device); 1475 1476 virtual void verifyMemoryRequirements (tcu::ResultCollector& result, 1477 const VkPhysicalDeviceMemoryProperties& deviceMemoryProperties); 1478 1479 protected: 1480 VkBool32 m_currentTestPrefersDedicatedAllocation; 1481 VkBool32 m_currentTestRequiresDedicatedAllocation; 1482 }; 1483 1484 1485 tcu::TestStatus ImageMemoryRequirementsDedicatedAllocation::testEntryPoint (Context& context, const ImageTestParams params) 1486 { 1487 ImageMemoryRequirementsDedicatedAllocation test; 1488 1489 return test.execTest(context, params); 1490 } 1491 1492 void ImageMemoryRequirementsDedicatedAllocation::addFunctionTestCase (tcu::TestCaseGroup* group, 1493 const std::string& name, 1494 const std::string& desc, 1495 const ImageTestParams arg0) 1496 { 1497 addFunctionCase(group, name, desc, testEntryPoint, arg0); 1498 } 1499 1500 void ImageMemoryRequirementsDedicatedAllocation::preTestChecks (Context& context, 1501 const InstanceInterface& vki, 1502 const VkPhysicalDevice physDevice, 1503 const VkImageCreateFlags createFlags) 1504 { 1505 if (!isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_dedicated_allocation")) 1506 TCU_THROW(NotSupportedError, "VK_KHR_dedicated_allocation is not supported"); 1507 1508 ImageMemoryRequirementsExtended::preTestChecks (context, vki, physDevice, createFlags); 1509 } 1510 1511 1512 void ImageMemoryRequirementsDedicatedAllocation::updateMemoryRequirements (const DeviceInterface& vk, 1513 const VkDevice device) 1514 { 1515 const deUint32 invalidVkBool32 = static_cast<deUint32>(~0); 1516 1517 VkMemoryDedicatedRequirements dedicatedRequirements = 1518 { 1519 VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR, // VkStructureType sType 1520 DE_NULL, // void* pNext 1521 invalidVkBool32, // VkBool32 prefersDedicatedAllocation 1522 invalidVkBool32 // VkBool32 requiresDedicatedAllocation 1523 }; 1524 1525 m_currentTestRequirements = getImageMemoryRequirements2(vk, device, m_currentTestImageInfo, &dedicatedRequirements); 1526 m_currentTestPrefersDedicatedAllocation = dedicatedRequirements.prefersDedicatedAllocation; 1527 m_currentTestRequiresDedicatedAllocation = dedicatedRequirements.requiresDedicatedAllocation; 1528 } 1529 1530 void ImageMemoryRequirementsDedicatedAllocation::verifyMemoryRequirements (tcu::ResultCollector& result, 1531 const VkPhysicalDeviceMemoryProperties& deviceMemoryProperties) 1532 { 1533 ImageMemoryRequirementsExtended::verifyMemoryRequirements(result, deviceMemoryProperties); 1534 1535 result.check(validValueVkBool32(m_currentTestPrefersDedicatedAllocation), 1536 "Non-bool value in m_currentTestPrefersDedicatedAllocation"); 1537 1538 result.check(m_currentTestRequiresDedicatedAllocation == VK_FALSE, 1539 "Test design expects m_currentTestRequiresDedicatedAllocation to be false"); 1540 1541 result.check(m_currentTestPrefersDedicatedAllocation == VK_FALSE || m_currentTestPrefersDedicatedAllocation == VK_FALSE, 1542 "Preferred and required flags for dedicated memory cannot be set to true at the same time"); 1543 } 1544 1545 void populateCoreTestGroup (tcu::TestCaseGroup* group) 1546 { 1547 BufferMemoryRequirementsOriginal bufferTest; 1548 ImageMemoryRequirementsOriginal imageTest; 1549 1550 bufferTest.populateTestGroup(group); 1551 imageTest.populateTestGroup(group); 1552 } 1553 1554 void populateExtendedTestGroup (tcu::TestCaseGroup* group) 1555 { 1556 BufferMemoryRequirementsExtended bufferTest; 1557 ImageMemoryRequirementsExtended imageTest; 1558 1559 bufferTest.populateTestGroup(group); 1560 imageTest.populateTestGroup(group); 1561 } 1562 1563 void populateDedicatedAllocationTestGroup (tcu::TestCaseGroup* group) 1564 { 1565 BufferMemoryRequirementsDedicatedAllocation bufferTest; 1566 ImageMemoryRequirementsDedicatedAllocation imageTest; 1567 1568 bufferTest.populateTestGroup(group); 1569 imageTest.populateTestGroup(group); 1570 } 1571 1572 bool isMultiplaneImageSupported (const InstanceInterface& vki, 1573 const VkPhysicalDevice physicalDevice, 1574 const VkImageCreateInfo& info) 1575 { 1576 if ((info.flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) && info.imageType != VK_IMAGE_TYPE_2D) 1577 return false; 1578 1579 if ((info.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) && 1580 (info.usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) == 0u) 1581 return false; 1582 1583 const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physicalDevice); 1584 1585 if (info.flags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) 1586 { 1587 DE_ASSERT(info.tiling == VK_IMAGE_TILING_OPTIMAL); 1588 1589 if (info.imageType == VK_IMAGE_TYPE_2D && !features.sparseResidencyImage2D) 1590 return false; 1591 } 1592 1593 const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(vki, physicalDevice, info.format); 1594 const VkFormatFeatureFlags formatFeatures = (info.tiling == VK_IMAGE_TILING_LINEAR ? formatProperties.linearTilingFeatures 1595 : formatProperties.optimalTilingFeatures); 1596 1597 if (!isUsageMatchesFeatures(info.usage, formatFeatures)) 1598 return false; 1599 1600 VkImageFormatProperties imageFormatProperties; 1601 const VkResult result = vki.getPhysicalDeviceImageFormatProperties( 1602 physicalDevice, info.format, info.imageType, info.tiling, info.usage, info.flags, &imageFormatProperties); 1603 1604 if (result == VK_SUCCESS) 1605 { 1606 if (info.arrayLayers > imageFormatProperties.maxArrayLayers) 1607 return false; 1608 if (info.mipLevels > imageFormatProperties.maxMipLevels) 1609 return false; 1610 if ((info.samples & imageFormatProperties.sampleCounts) == 0u) 1611 return false; 1612 } 1613 1614 return result == VK_SUCCESS; 1615 } 1616 1617 tcu::TestStatus testMultiplaneImages (Context& context, ImageTestParams params) 1618 { 1619 const VkFormat multiplaneFormats[] = 1620 { 1621 VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR, 1622 VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR, 1623 VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM_KHR, 1624 VK_FORMAT_G8_B8R8_2PLANE_422_UNORM_KHR, 1625 VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM_KHR, 1626 VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_KHR, 1627 VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_KHR, 1628 VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16_KHR, 1629 VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16_KHR, 1630 VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16_KHR, 1631 VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_KHR, 1632 VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_KHR, 1633 VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16_KHR, 1634 VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16_KHR, 1635 VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16_KHR, 1636 VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM_KHR, 1637 VK_FORMAT_G16_B16R16_2PLANE_420_UNORM_KHR, 1638 VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM_KHR, 1639 VK_FORMAT_G16_B16R16_2PLANE_422_UNORM_KHR 1640 }; 1641 { 1642 const std::string extensionName("VK_KHR_get_memory_requirements2"); 1643 1644 if (!isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), extensionName)) 1645 TCU_THROW(NotSupportedError, std::string(extensionName + " is not supported").c_str()); 1646 } 1647 { 1648 const std::string extensionName("VK_KHR_sampler_ycbcr_conversion"); 1649 1650 if (!isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), extensionName)) 1651 TCU_THROW(NotSupportedError, std::string(extensionName + " is not supported").c_str()); 1652 } 1653 1654 const DeviceInterface& vk = context.getDeviceInterface(); 1655 const InstanceInterface& vki = context.getInstanceInterface(); 1656 const VkDevice device = context.getDevice(); 1657 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice(); 1658 const VkImageCreateFlags sparseFlags = VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT; 1659 const VkImageUsageFlags transientFlags = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT; 1660 const VkPhysicalDeviceMemoryProperties memoryProperties = getPhysicalDeviceMemoryProperties(vki, physicalDevice); 1661 tcu::TestLog& log = context.getTestContext().getLog(); 1662 tcu::ResultCollector result (log, "ERROR: "); 1663 deUint32 errorCount = 0; 1664 1665 log << TestLog::Message << "Memory properties: " << memoryProperties << TestLog::EndMessage; 1666 1667 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(multiplaneFormats); formatNdx++) 1668 { 1669 for (VkImageCreateFlags loopCreateFlags = (VkImageCreateFlags)0; loopCreateFlags <= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT; loopCreateFlags = nextFlagExcluding(loopCreateFlags, sparseFlags)) 1670 for (VkImageUsageFlags loopUsageFlags = VK_IMAGE_USAGE_TRANSFER_SRC_BIT; loopUsageFlags <= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT; loopUsageFlags = nextFlagExcluding(loopUsageFlags, transientFlags)) 1671 { 1672 const VkFormat format = multiplaneFormats[formatNdx]; 1673 const VkImageCreateFlags actualCreateFlags = loopCreateFlags | params.flags; 1674 const VkImageUsageFlags actualUsageFlags = loopUsageFlags | (params.transient ? VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT : (VkImageUsageFlagBits)0); 1675 const VkImageCreateInfo imageInfo = 1676 { 1677 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 1678 DE_NULL, // const void* pNext; 1679 actualCreateFlags, // VkImageCreateFlags flags; 1680 VK_IMAGE_TYPE_2D, // VkImageType imageType; 1681 format, // VkFormat format; 1682 { 64u, 64u, 1u, }, // VkExtent3D extent; 1683 1u, // uint32_t mipLevels; 1684 1u, // uint32_t arrayLayers; 1685 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 1686 params.tiling, // VkImageTiling tiling; 1687 actualUsageFlags, // VkImageUsageFlags usage; 1688 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1689 0u, // uint32_t queueFamilyIndexCount; 1690 DE_NULL, // const uint32_t* pQueueFamilyIndices; 1691 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 1692 }; 1693 1694 if (isMultiplaneImageSupported(vki, physicalDevice, imageInfo)) 1695 { 1696 const Unique<VkImage> image (createImage(vk, device, &imageInfo)); 1697 1698 log << tcu::TestLog::Message << "- " << getImageInfoString(imageInfo) << tcu::TestLog::EndMessage; 1699 1700 for (deUint32 planeNdx = 0; planeNdx < (deUint32)getPlaneCount(format); planeNdx++) 1701 { 1702 const VkImageAspectFlagBits aspect = getPlaneAspect(planeNdx); 1703 const VkImagePlaneMemoryRequirementsInfo aspectInfo = 1704 { 1705 VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO_KHR, 1706 DE_NULL, 1707 aspect 1708 }; 1709 const VkImageMemoryRequirementsInfo2 info = 1710 { 1711 VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR, 1712 (actualCreateFlags & VK_IMAGE_CREATE_DISJOINT_BIT_KHR) == 0 ? DE_NULL : &aspectInfo, 1713 *image 1714 }; 1715 VkMemoryRequirements2 requirements = 1716 { 1717 VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR, 1718 DE_NULL, 1719 { 0u, 0u, 0u } 1720 }; 1721 1722 vk.getImageMemoryRequirements2(device, &info, &requirements); 1723 1724 log << TestLog::Message << "Aspect: " << getImageAspectFlagsStr(aspect) << ", Requirements: " << requirements << TestLog::EndMessage; 1725 1726 result.check(deIsPowerOfTwo64(static_cast<deUint64>(requirements.memoryRequirements.alignment)), "VkMemoryRequirements alignment isn't power of two"); 1727 1728 if (result.check(requirements.memoryRequirements.memoryTypeBits != 0, "No supported memory types")) 1729 { 1730 bool hasHostVisibleType = false; 1731 1732 for (deUint32 memoryTypeIndex = 0; (0x1u << memoryTypeIndex) <= requirements.memoryRequirements.memoryTypeBits; memoryTypeIndex++) 1733 { 1734 if (result.check(memoryTypeIndex < memoryProperties.memoryTypeCount, "Unknown memory type bits set in memory requirements")) 1735 { 1736 const VkMemoryPropertyFlags propertyFlags (memoryProperties.memoryTypes[memoryTypeIndex].propertyFlags); 1737 1738 if (propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) 1739 hasHostVisibleType = true; 1740 1741 if (propertyFlags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) 1742 { 1743 result.check((imageInfo.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) != 0u, 1744 "Memory type includes VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT for a non-transient attachment image"); 1745 } 1746 } 1747 else 1748 break; 1749 } 1750 1751 result.check(params.tiling != VK_IMAGE_TILING_LINEAR || hasHostVisibleType, "Required memory type doesn't include VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT"); 1752 } 1753 } 1754 } 1755 } 1756 } 1757 1758 if (errorCount > 1) 1759 return tcu::TestStatus(result.getResult(), "Failed " + de::toString(errorCount) + " cases."); 1760 else 1761 return tcu::TestStatus(result.getResult(), result.getMessage()); 1762 } 1763 1764 void populateMultiplaneTestGroup (tcu::TestCaseGroup* group) 1765 { 1766 const struct 1767 { 1768 VkImageCreateFlags flags; 1769 bool transient; 1770 const char* const name; 1771 } imageFlagsCases[] = 1772 { 1773 { (VkImageCreateFlags)0, false, "regular" }, 1774 { (VkImageCreateFlags)0, true, "transient" }, 1775 { VK_IMAGE_CREATE_SPARSE_BINDING_BIT, false, "sparse" }, 1776 { VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT, false, "sparse_residency" }, 1777 { VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT, false, "sparse_aliased" }, 1778 { VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT, false, "sparse_residency_aliased" }, 1779 }; 1780 const struct 1781 { 1782 VkImageTiling value; 1783 const char* name; 1784 } tilings[] = 1785 { 1786 { VK_IMAGE_TILING_OPTIMAL, "optimal" }, 1787 { VK_IMAGE_TILING_LINEAR, "linear" } 1788 }; 1789 1790 for (size_t flagsNdx = 0; flagsNdx < DE_LENGTH_OF_ARRAY(imageFlagsCases); ++flagsNdx) 1791 for (size_t tilingNdx = 0; tilingNdx < DE_LENGTH_OF_ARRAY(tilings); ++tilingNdx) 1792 { 1793 const VkImageCreateFlags flags = imageFlagsCases[flagsNdx].flags; 1794 const bool transient = imageFlagsCases[flagsNdx].transient; 1795 const VkImageTiling tiling = tilings[tilingNdx].value; 1796 const ImageTestParams params (flags, tiling, transient); 1797 const std::string name = std::string(imageFlagsCases[flagsNdx].name) + "_" + tilings[tilingNdx].name; 1798 1799 if (tiling == VK_IMAGE_TILING_LINEAR && (flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) != 0) 1800 continue; 1801 1802 addFunctionCase(group, name, name, testMultiplaneImages, params); 1803 } 1804 } 1805 1806 } // anonymous 1807 1808 1809 tcu::TestCaseGroup* createRequirementsTests (tcu::TestContext& testCtx) 1810 { 1811 de::MovePtr<tcu::TestCaseGroup> requirementsGroup(new tcu::TestCaseGroup(testCtx, "requirements", "Buffer and image memory requirements")); 1812 1813 requirementsGroup->addChild(createTestGroup(testCtx, "core", "Memory requirements tests with core functionality", populateCoreTestGroup)); 1814 requirementsGroup->addChild(createTestGroup(testCtx, "extended", "Memory requirements tests with extension VK_KHR_get_memory_requirements2", populateExtendedTestGroup)); 1815 requirementsGroup->addChild(createTestGroup(testCtx, "dedicated_allocation", "Memory requirements tests with extension VK_KHR_dedicated_allocation", populateDedicatedAllocationTestGroup)); 1816 requirementsGroup->addChild(createTestGroup(testCtx, "multiplane_image", "Memory requirements tests with vkGetImagePlaneMemoryRequirements", populateMultiplaneTestGroup)); 1817 1818 return requirementsGroup.release(); 1819 } 1820 1821 } // memory 1822 } // vkt 1823