1 /*------------------------------------------------------------------------- 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2015 Google 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 Object management tests 22 *//*--------------------------------------------------------------------*/ 23 24 #include "vktApiObjectManagementTests.hpp" 25 #include "vktTestCaseUtil.hpp" 26 27 #include "vkDefs.hpp" 28 #include "vkRef.hpp" 29 #include "vkRefUtil.hpp" 30 #include "vkQueryUtil.hpp" 31 #include "vkMemUtil.hpp" 32 #include "vkPrograms.hpp" 33 #include "vkTypeUtil.hpp" 34 #include "vkPlatform.hpp" 35 #include "vkStrUtil.hpp" 36 #include "vkAllocationCallbackUtil.hpp" 37 #include "vkObjUtil.hpp" 38 39 #include "tcuVector.hpp" 40 #include "tcuResultCollector.hpp" 41 #include "tcuCommandLine.hpp" 42 #include "tcuTestLog.hpp" 43 #include "tcuPlatform.hpp" 44 45 #include "deUniquePtr.hpp" 46 #include "deSharedPtr.hpp" 47 #include "deArrayUtil.hpp" 48 #include "deSpinBarrier.hpp" 49 #include "deThread.hpp" 50 #include "deInt32.h" 51 52 #include <limits> 53 54 #define VK_DESCRIPTOR_TYPE_LAST (VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT + 1) 55 56 namespace vkt 57 { 58 namespace api 59 { 60 61 namespace 62 { 63 64 using namespace vk; 65 66 using de::UniquePtr; 67 using de::MovePtr; 68 using de::SharedPtr; 69 70 using tcu::IVec3; 71 using tcu::UVec3; 72 using tcu::ResultCollector; 73 using tcu::TestStatus; 74 using tcu::TestLog; 75 76 using std::string; 77 using std::vector; 78 79 typedef SharedPtr<Move<VkPipeline> > VkPipelineSp; // Move so it's possible to disown the handle 80 typedef SharedPtr<Move<VkDescriptorSet> > VkDescriptorSetSp; 81 typedef SharedPtr<Move<VkCommandBuffer> > VkCommandBufferSp; 82 83 class ThreadGroupThread; 84 85 /*--------------------------------------------------------------------*//*! 86 * \brief Thread group 87 * 88 * Thread group manages collection of threads that are expected to be 89 * launched simultaneously as a group. 90 * 91 * Shared barrier is provided for synchronizing execution. Terminating thread 92 * early either by returning from ThreadGroupThread::runThread() or throwing 93 * an exception is safe, and other threads will continue execution. The 94 * thread that has been terminated is simply removed from the synchronization 95 * group. 96 * 97 * TestException-based exceptions are collected and translated into a 98 * tcu::TestStatus by using tcu::ResultCollector. 99 * 100 * Use cases for ThreadGroup include for example testing thread-safety of 101 * certain API operations by poking API simultaneously from multiple 102 * threads. 103 *//*--------------------------------------------------------------------*/ 104 class ThreadGroup 105 { 106 public: 107 ThreadGroup (void); 108 ~ThreadGroup (void); 109 110 void add (de::MovePtr<ThreadGroupThread> thread); 111 TestStatus run (void); 112 113 private: 114 typedef std::vector<de::SharedPtr<ThreadGroupThread> > ThreadVector; 115 116 ThreadVector m_threads; 117 de::SpinBarrier m_barrier; 118 } DE_WARN_UNUSED_TYPE; 119 120 class ThreadGroupThread : private de::Thread 121 { 122 public: 123 ThreadGroupThread (void); 124 virtual ~ThreadGroupThread (void); 125 126 void start (de::SpinBarrier* groupBarrier); 127 128 ResultCollector& getResultCollector (void) { return m_resultCollector; } 129 130 using de::Thread::join; 131 132 protected: 133 virtual void runThread (void) = 0; 134 135 void barrier (void); 136 137 private: 138 ThreadGroupThread (const ThreadGroupThread&); 139 ThreadGroupThread& operator= (const ThreadGroupThread&); 140 141 void run (void); 142 143 ResultCollector m_resultCollector; 144 de::SpinBarrier* m_barrier; 145 }; 146 147 // ThreadGroup 148 149 ThreadGroup::ThreadGroup (void) 150 : m_barrier(1) 151 { 152 } 153 154 ThreadGroup::~ThreadGroup (void) 155 { 156 } 157 158 void ThreadGroup::add (de::MovePtr<ThreadGroupThread> thread) 159 { 160 m_threads.push_back(de::SharedPtr<ThreadGroupThread>(thread.release())); 161 } 162 163 tcu::TestStatus ThreadGroup::run (void) 164 { 165 tcu::ResultCollector resultCollector; 166 167 m_barrier.reset((int)m_threads.size()); 168 169 for (ThreadVector::iterator threadIter = m_threads.begin(); threadIter != m_threads.end(); ++threadIter) 170 (*threadIter)->start(&m_barrier); 171 172 for (ThreadVector::iterator threadIter = m_threads.begin(); threadIter != m_threads.end(); ++threadIter) 173 { 174 tcu::ResultCollector& threadResult = (*threadIter)->getResultCollector(); 175 (*threadIter)->join(); 176 resultCollector.addResult(threadResult.getResult(), threadResult.getMessage()); 177 } 178 179 return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage()); 180 } 181 182 // ThreadGroupThread 183 184 ThreadGroupThread::ThreadGroupThread (void) 185 : m_barrier(DE_NULL) 186 { 187 } 188 189 ThreadGroupThread::~ThreadGroupThread (void) 190 { 191 } 192 193 void ThreadGroupThread::start (de::SpinBarrier* groupBarrier) 194 { 195 m_barrier = groupBarrier; 196 de::Thread::start(); 197 } 198 199 void ThreadGroupThread::run (void) 200 { 201 try 202 { 203 runThread(); 204 } 205 catch (const tcu::TestException& e) 206 { 207 getResultCollector().addResult(e.getTestResult(), e.getMessage()); 208 } 209 catch (const std::exception& e) 210 { 211 getResultCollector().addResult(QP_TEST_RESULT_FAIL, e.what()); 212 } 213 catch (...) 214 { 215 getResultCollector().addResult(QP_TEST_RESULT_FAIL, "Exception"); 216 } 217 218 m_barrier->removeThread(de::SpinBarrier::WAIT_MODE_AUTO); 219 } 220 221 inline void ThreadGroupThread::barrier (void) 222 { 223 m_barrier->sync(de::SpinBarrier::WAIT_MODE_AUTO); 224 } 225 226 deUint32 getDefaultTestThreadCount (void) 227 { 228 return de::clamp(deGetNumAvailableLogicalCores(), 2u, 8u); 229 } 230 231 // Utilities 232 233 struct Environment 234 { 235 const PlatformInterface& vkp; 236 deUint32 apiVersion; 237 VkInstance instance; 238 const DeviceInterface& vkd; 239 VkDevice device; 240 deUint32 queueFamilyIndex; 241 const BinaryCollection& programBinaries; 242 const VkAllocationCallbacks* allocationCallbacks; 243 deUint32 maxResourceConsumers; // Maximum number of objects using same Object::Resources concurrently 244 245 Environment (Context& context, deUint32 maxResourceConsumers_) 246 : vkp (context.getPlatformInterface()) 247 , apiVersion (context.getUsedApiVersion()) 248 , instance (context.getInstance()) 249 , vkd (context.getDeviceInterface()) 250 , device (context.getDevice()) 251 , queueFamilyIndex (context.getUniversalQueueFamilyIndex()) 252 , programBinaries (context.getBinaryCollection()) 253 , allocationCallbacks (DE_NULL) 254 , maxResourceConsumers (maxResourceConsumers_) 255 { 256 } 257 258 Environment (const PlatformInterface& vkp_, 259 deUint32 apiVersion_, 260 VkInstance instance_, 261 const DeviceInterface& vkd_, 262 VkDevice device_, 263 deUint32 queueFamilyIndex_, 264 const BinaryCollection& programBinaries_, 265 const VkAllocationCallbacks* allocationCallbacks_, 266 deUint32 maxResourceConsumers_) 267 : vkp (vkp_) 268 , apiVersion (apiVersion_) 269 , instance (instance_) 270 , vkd (vkd_) 271 , device (device_) 272 , queueFamilyIndex (queueFamilyIndex_) 273 , programBinaries (programBinaries_) 274 , allocationCallbacks (allocationCallbacks_) 275 , maxResourceConsumers (maxResourceConsumers_) 276 { 277 } 278 }; 279 280 template<typename Case> 281 struct Dependency 282 { 283 typename Case::Resources resources; 284 Unique<typename Case::Type> object; 285 286 Dependency (const Environment& env, const typename Case::Parameters& params) 287 : resources (env, params) 288 , object (Case::create(env, resources, params)) 289 {} 290 }; 291 292 template<typename T> 293 T roundUpToNextMultiple (T value, T multiple) 294 { 295 if (value % multiple == 0) 296 return value; 297 else 298 return value + multiple - (value % multiple); 299 } 300 301 #if defined(DE_DEBUG) 302 template<typename T> 303 bool isPowerOfTwo (T value) 304 { 305 return ((value & (value - T(1))) == 0); 306 } 307 #endif 308 309 template<typename T> 310 T alignToPowerOfTwo (T value, T align) 311 { 312 DE_ASSERT(isPowerOfTwo(align)); 313 return (value + align - T(1)) & ~(align - T(1)); 314 } 315 316 inline bool hasDeviceExtension (Context& context, const string name) 317 { 318 return isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), name); 319 } 320 321 VkDeviceSize getPageTableSize (const PlatformMemoryLimits& limits, VkDeviceSize allocationSize) 322 { 323 VkDeviceSize totalSize = 0; 324 325 for (size_t levelNdx = 0; levelNdx < limits.devicePageTableHierarchyLevels; ++levelNdx) 326 { 327 const VkDeviceSize coveredAddressSpaceSize = limits.devicePageSize<<levelNdx; 328 const VkDeviceSize numPagesNeeded = alignToPowerOfTwo(allocationSize, coveredAddressSpaceSize) / coveredAddressSpaceSize; 329 330 totalSize += numPagesNeeded*limits.devicePageTableEntrySize; 331 } 332 333 return totalSize; 334 } 335 336 size_t getCurrentSystemMemoryUsage (const AllocationCallbackRecorder& allocRecoder) 337 { 338 const size_t systemAllocationOverhead = sizeof(void*)*2; 339 AllocationCallbackValidationResults validationResults; 340 341 validateAllocationCallbacks(allocRecoder, &validationResults); 342 TCU_CHECK(validationResults.violations.empty()); 343 344 return getLiveSystemAllocationTotal(validationResults) + systemAllocationOverhead*validationResults.liveAllocations.size(); 345 } 346 347 template<typename Object> 348 size_t computeSystemMemoryUsage (Context& context, const typename Object::Parameters& params) 349 { 350 AllocationCallbackRecorder allocRecorder (getSystemAllocator()); 351 const Environment env (context.getPlatformInterface(), 352 context.getUsedApiVersion(), 353 context.getInstance(), 354 context.getDeviceInterface(), 355 context.getDevice(), 356 context.getUniversalQueueFamilyIndex(), 357 context.getBinaryCollection(), 358 allocRecorder.getCallbacks(), 359 1u); 360 const typename Object::Resources res (env, params); 361 const size_t resourceMemoryUsage = getCurrentSystemMemoryUsage(allocRecorder); 362 363 { 364 Unique<typename Object::Type> obj (Object::create(env, res, params)); 365 const size_t totalMemoryUsage = getCurrentSystemMemoryUsage(allocRecorder); 366 367 return totalMemoryUsage - resourceMemoryUsage; 368 } 369 } 370 371 size_t getSafeObjectCount (const PlatformMemoryLimits& memoryLimits, 372 size_t objectSystemMemoryUsage, 373 VkDeviceSize objectDeviceMemoryUsage = 0) 374 { 375 const VkDeviceSize roundedUpDeviceMemory = roundUpToNextMultiple(objectDeviceMemoryUsage, memoryLimits.deviceMemoryAllocationGranularity); 376 377 if (memoryLimits.totalDeviceLocalMemory > 0 && roundedUpDeviceMemory > 0) 378 { 379 if (objectSystemMemoryUsage > 0) 380 return de::min(memoryLimits.totalSystemMemory / objectSystemMemoryUsage, 381 (size_t)(memoryLimits.totalDeviceLocalMemory / roundedUpDeviceMemory)); 382 else 383 return (size_t)(memoryLimits.totalDeviceLocalMemory / roundedUpDeviceMemory); 384 } 385 else if (objectSystemMemoryUsage + roundedUpDeviceMemory > 0) 386 { 387 DE_ASSERT(roundedUpDeviceMemory <= std::numeric_limits<size_t>::max() - objectSystemMemoryUsage); 388 return memoryLimits.totalSystemMemory / (objectSystemMemoryUsage + (size_t)roundedUpDeviceMemory); 389 } 390 else 391 { 392 // Warning: at this point driver has probably not implemented allocation callbacks correctly 393 return std::numeric_limits<size_t>::max(); 394 } 395 } 396 397 PlatformMemoryLimits getPlatformMemoryLimits (Context& context) 398 { 399 PlatformMemoryLimits memoryLimits; 400 401 context.getTestContext().getPlatform().getVulkanPlatform().getMemoryLimits(memoryLimits); 402 403 return memoryLimits; 404 } 405 406 size_t getSafeObjectCount (Context& context, size_t objectSystemMemoryUsage, VkDeviceSize objectDeviceMemorySize = 0) 407 { 408 return getSafeObjectCount(getPlatformMemoryLimits(context), objectSystemMemoryUsage, objectDeviceMemorySize); 409 } 410 411 VkDeviceSize getPageTableSize (Context& context, VkDeviceSize allocationSize) 412 { 413 return getPageTableSize(getPlatformMemoryLimits(context), allocationSize); 414 } 415 416 template<typename Object> 417 deUint32 getSafeObjectCount (Context& context, 418 const typename Object::Parameters& params, 419 deUint32 hardCountLimit, 420 VkDeviceSize deviceMemoryUsage = 0) 421 { 422 return (deUint32)de::min((size_t)hardCountLimit, 423 getSafeObjectCount(context, 424 computeSystemMemoryUsage<Object>(context, params), 425 deviceMemoryUsage)); 426 } 427 428 // Object definitions 429 430 enum 431 { 432 MAX_CONCURRENT_INSTANCES = 32, 433 MAX_CONCURRENT_DEVICES = 32, 434 MAX_CONCURRENT_SYNC_PRIMITIVES = 100, 435 MAX_CONCURRENT_PIPELINE_CACHES = 128, 436 DEFAULT_MAX_CONCURRENT_OBJECTS = 16*1024, 437 }; 438 439 struct Instance 440 { 441 typedef VkInstance Type; 442 443 struct Parameters 444 { 445 const vector<string> instanceExtensions; 446 447 Parameters (void) {} 448 449 Parameters (vector<string>& extensions) 450 : instanceExtensions (extensions) 451 {} 452 }; 453 454 struct Resources 455 { 456 Resources (const Environment&, const Parameters&) {} 457 }; 458 459 static deUint32 getMaxConcurrent (Context& context, const Parameters& params) 460 { 461 return getSafeObjectCount<Instance>(context, params, MAX_CONCURRENT_INSTANCES); 462 } 463 464 static Move<VkInstance> create (const Environment& env, const Resources&, const Parameters& params) 465 { 466 vector<const char*> extensionNamePtrs; 467 const vector<VkExtensionProperties> instanceExts = enumerateInstanceExtensionProperties(env.vkp, DE_NULL); 468 for (size_t extensionID = 0; extensionID < params.instanceExtensions.size(); extensionID++) 469 { 470 if (!isInstanceExtensionSupported(env.apiVersion, instanceExts, RequiredExtension(params.instanceExtensions[extensionID]))) 471 TCU_THROW(NotSupportedError, (params.instanceExtensions[extensionID] + " is not supported").c_str()); 472 473 if (!isCoreInstanceExtension(env.apiVersion, params.instanceExtensions[extensionID])) 474 extensionNamePtrs.push_back(params.instanceExtensions[extensionID].c_str()); 475 } 476 477 const VkApplicationInfo appInfo = 478 { 479 VK_STRUCTURE_TYPE_APPLICATION_INFO, 480 DE_NULL, 481 DE_NULL, // pApplicationName 482 0u, // applicationVersion 483 DE_NULL, // pEngineName 484 0u, // engineVersion 485 env.apiVersion 486 }; 487 488 const VkInstanceCreateInfo instanceInfo = 489 { 490 VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, 491 DE_NULL, 492 (VkInstanceCreateFlags)0, 493 &appInfo, 494 0u, // enabledLayerNameCount 495 DE_NULL, // ppEnabledLayerNames 496 (deUint32)extensionNamePtrs.size(), // enabledExtensionNameCount 497 extensionNamePtrs.empty() ? DE_NULL : &extensionNamePtrs[0], // ppEnabledExtensionNames 498 }; 499 500 return createInstance(env.vkp, &instanceInfo, env.allocationCallbacks); 501 } 502 }; 503 504 struct Device 505 { 506 typedef VkDevice Type; 507 508 struct Parameters 509 { 510 deUint32 deviceIndex; 511 VkQueueFlags queueFlags; 512 513 Parameters (deUint32 deviceIndex_, VkQueueFlags queueFlags_) 514 : deviceIndex (deviceIndex_) 515 , queueFlags (queueFlags_) 516 {} 517 }; 518 519 struct Resources 520 { 521 Dependency<Instance> instance; 522 InstanceDriver vki; 523 VkPhysicalDevice physicalDevice; 524 deUint32 queueFamilyIndex; 525 526 Resources (const Environment& env, const Parameters& params) 527 : instance (env, Instance::Parameters()) 528 , vki (env.vkp, *instance.object) 529 , physicalDevice (0) 530 , queueFamilyIndex (~0u) 531 { 532 { 533 const vector<VkPhysicalDevice> physicalDevices = enumeratePhysicalDevices(vki, *instance.object); 534 535 if (physicalDevices.size() <= (size_t)params.deviceIndex) 536 TCU_THROW(NotSupportedError, "Device not found"); 537 538 physicalDevice = physicalDevices[params.deviceIndex]; 539 } 540 541 { 542 const vector<VkQueueFamilyProperties> queueProps = getPhysicalDeviceQueueFamilyProperties(vki, physicalDevice); 543 bool foundMatching = false; 544 545 for (size_t curQueueNdx = 0; curQueueNdx < queueProps.size(); curQueueNdx++) 546 { 547 if ((queueProps[curQueueNdx].queueFlags & params.queueFlags) == params.queueFlags) 548 { 549 queueFamilyIndex = (deUint32)curQueueNdx; 550 foundMatching = true; 551 } 552 } 553 554 if (!foundMatching) 555 TCU_THROW(NotSupportedError, "Matching queue not found"); 556 } 557 } 558 }; 559 560 static deUint32 getMaxConcurrent (Context& context, const Parameters& params) 561 { 562 return getSafeObjectCount<Device>(context, params, MAX_CONCURRENT_DEVICES); 563 } 564 565 static Move<VkDevice> create (const Environment& env, const Resources& res, const Parameters&) 566 { 567 const float queuePriority = 1.0; 568 569 const VkDeviceQueueCreateInfo queues[] = 570 { 571 { 572 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, 573 DE_NULL, 574 (VkDeviceQueueCreateFlags)0, 575 res.queueFamilyIndex, 576 1u, // queueCount 577 &queuePriority, // pQueuePriorities 578 } 579 }; 580 const VkDeviceCreateInfo deviceInfo = 581 { 582 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, 583 DE_NULL, 584 (VkDeviceCreateFlags)0, 585 DE_LENGTH_OF_ARRAY(queues), 586 queues, 587 0u, // enabledLayerNameCount 588 DE_NULL, // ppEnabledLayerNames 589 0u, // enabledExtensionNameCount 590 DE_NULL, // ppEnabledExtensionNames 591 DE_NULL, // pEnabledFeatures 592 }; 593 594 return createDevice(env.vkp, env.instance, res.vki, res.physicalDevice, &deviceInfo, env.allocationCallbacks); 595 } 596 }; 597 598 599 struct DeviceGroup 600 { 601 typedef VkDevice Type; 602 603 struct Parameters 604 { 605 deUint32 deviceGroupIndex; 606 deUint32 deviceIndex; 607 VkQueueFlags queueFlags; 608 609 Parameters (deUint32 deviceGroupIndex_, deUint32 deviceIndex_, VkQueueFlags queueFlags_) 610 : deviceGroupIndex (deviceGroupIndex_) 611 , deviceIndex (deviceIndex_) 612 , queueFlags (queueFlags_) 613 {} 614 }; 615 616 struct Resources 617 { 618 vector<string> extensions; 619 Dependency<Instance> instance; 620 InstanceDriver vki; 621 vector<VkPhysicalDevice> physicalDevices; 622 deUint32 physicalDeviceCount; 623 deUint32 queueFamilyIndex; 624 625 Resources (const Environment& env, const Parameters& params) 626 : extensions (1, "VK_KHR_device_group_creation") 627 , instance (env, Instance::Parameters(extensions)) 628 , vki (env.vkp, *instance.object) 629 , physicalDeviceCount (0) 630 , queueFamilyIndex (~0u) 631 { 632 { 633 const vector<VkPhysicalDeviceGroupProperties> devGroupProperties = enumeratePhysicalDeviceGroups(vki, *instance.object); 634 635 if (devGroupProperties.size() <= (size_t)params.deviceGroupIndex) 636 TCU_THROW(NotSupportedError, "Device Group not found"); 637 638 physicalDeviceCount = devGroupProperties[params.deviceGroupIndex].physicalDeviceCount; 639 physicalDevices.resize(physicalDeviceCount); 640 641 for (deUint32 physicalDeviceIdx = 0; physicalDeviceIdx < physicalDeviceCount; physicalDeviceIdx++) 642 physicalDevices[physicalDeviceIdx] = devGroupProperties[params.deviceGroupIndex].physicalDevices[physicalDeviceIdx]; 643 } 644 645 { 646 const vector<VkQueueFamilyProperties> queueProps = getPhysicalDeviceQueueFamilyProperties(vki, physicalDevices[params.deviceIndex]); 647 bool foundMatching = false; 648 649 for (size_t curQueueNdx = 0; curQueueNdx < queueProps.size(); curQueueNdx++) 650 { 651 if ((queueProps[curQueueNdx].queueFlags & params.queueFlags) == params.queueFlags) 652 { 653 queueFamilyIndex = (deUint32)curQueueNdx; 654 foundMatching = true; 655 } 656 } 657 658 if (!foundMatching) 659 TCU_THROW(NotSupportedError, "Matching queue not found"); 660 } 661 } 662 }; 663 664 static deUint32 getMaxConcurrent (Context& context, const Parameters& params) 665 { 666 return getSafeObjectCount<DeviceGroup>(context, params, MAX_CONCURRENT_DEVICES); 667 } 668 669 static Move<VkDevice> create (const Environment& env, const Resources& res, const Parameters& params) 670 { 671 const float queuePriority = 1.0; 672 673 const VkDeviceQueueCreateInfo queues[] = 674 { 675 { 676 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, 677 DE_NULL, // pNext 678 (VkDeviceQueueCreateFlags)0, // flags 679 res.queueFamilyIndex, // queueFamilyIndex 680 1u, // queueCount 681 &queuePriority, // pQueuePriorities 682 } 683 }; 684 685 const VkDeviceGroupDeviceCreateInfo deviceGroupInfo = 686 { 687 VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO, //stype 688 DE_NULL, //pNext 689 res.physicalDeviceCount, //physicalDeviceCount 690 res.physicalDevices.data() //physicalDevices 691 }; 692 693 const VkDeviceCreateInfo deviceGroupCreateInfo = 694 { 695 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, 696 &deviceGroupInfo, 697 (VkDeviceCreateFlags)0, 698 DE_LENGTH_OF_ARRAY(queues), 699 queues, 700 0u, // enabledLayerNameCount 701 DE_NULL, // ppEnabledLayerNames 702 0u, // enabledExtensionNameCount 703 DE_NULL, // ppEnabledExtensionNames 704 DE_NULL, // pEnabledFeatures 705 }; 706 707 return createDevice(env.vkp, env.instance, res.vki, res.physicalDevices[params.deviceIndex], &deviceGroupCreateInfo, env.allocationCallbacks); 708 } 709 }; 710 711 struct DeviceMemory 712 { 713 typedef VkDeviceMemory Type; 714 715 struct Parameters 716 { 717 VkDeviceSize size; 718 deUint32 memoryTypeIndex; 719 720 Parameters (VkDeviceSize size_, deUint32 memoryTypeIndex_) 721 : size (size_) 722 , memoryTypeIndex (memoryTypeIndex_) 723 { 724 DE_ASSERT(memoryTypeIndex < VK_MAX_MEMORY_TYPES); 725 } 726 }; 727 728 struct Resources 729 { 730 Resources (const Environment&, const Parameters&) {} 731 }; 732 733 static deUint32 getMaxConcurrent (Context& context, const Parameters& params) 734 { 735 const VkDeviceSize deviceMemoryUsage = params.size + getPageTableSize(context, params.size); 736 737 return getSafeObjectCount<DeviceMemory>(context, 738 params, 739 de::min(context.getDeviceProperties().limits.maxMemoryAllocationCount, 740 (deUint32)DEFAULT_MAX_CONCURRENT_OBJECTS), 741 deviceMemoryUsage); 742 } 743 744 static Move<VkDeviceMemory> create (const Environment& env, const Resources&, const Parameters& params) 745 { 746 const VkMemoryAllocateInfo allocInfo = 747 { 748 VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, 749 DE_NULL, 750 params.size, 751 params.memoryTypeIndex 752 }; 753 754 return allocateMemory(env.vkd, env.device, &allocInfo, env.allocationCallbacks); 755 } 756 }; 757 758 DeviceMemory::Parameters getDeviceMemoryParameters (const VkMemoryRequirements& memReqs) 759 { 760 return DeviceMemory::Parameters(memReqs.size, deCtz32(memReqs.memoryTypeBits)); 761 } 762 763 DeviceMemory::Parameters getDeviceMemoryParameters (const Environment& env, VkImage image) 764 { 765 return getDeviceMemoryParameters(getImageMemoryRequirements(env.vkd, env.device, image)); 766 } 767 768 DeviceMemory::Parameters getDeviceMemoryParameters (const Environment& env, VkBuffer image) 769 { 770 return getDeviceMemoryParameters(getBufferMemoryRequirements(env.vkd, env.device, image)); 771 } 772 773 struct Buffer 774 { 775 typedef VkBuffer Type; 776 777 struct Parameters 778 { 779 VkDeviceSize size; 780 VkBufferUsageFlags usage; 781 782 Parameters (VkDeviceSize size_, 783 VkBufferUsageFlags usage_) 784 : size (size_) 785 , usage (usage_) 786 {} 787 }; 788 789 struct Resources 790 { 791 Resources (const Environment&, const Parameters&) {} 792 }; 793 794 static deUint32 getMaxConcurrent (Context& context, const Parameters& params) 795 { 796 const Environment env (context, 1u); 797 const Resources res (env, params); 798 const Unique<VkBuffer> buffer (create(env, res, params)); 799 const VkMemoryRequirements memReqs = getBufferMemoryRequirements(env.vkd, env.device, *buffer); 800 801 return getSafeObjectCount<Buffer>(context, 802 params, 803 DEFAULT_MAX_CONCURRENT_OBJECTS, 804 getPageTableSize(context, memReqs.size)); 805 } 806 807 static Move<VkBuffer> create (const Environment& env, const Resources&, const Parameters& params) 808 { 809 const VkBufferCreateInfo bufferInfo = 810 { 811 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, 812 DE_NULL, 813 (VkBufferCreateFlags)0, 814 params.size, 815 params.usage, 816 VK_SHARING_MODE_EXCLUSIVE, 817 1u, 818 &env.queueFamilyIndex 819 }; 820 821 return createBuffer(env.vkd, env.device, &bufferInfo, env.allocationCallbacks); 822 } 823 }; 824 825 struct BufferView 826 { 827 typedef VkBufferView Type; 828 829 struct Parameters 830 { 831 Buffer::Parameters buffer; 832 VkFormat format; 833 VkDeviceSize offset; 834 VkDeviceSize range; 835 836 Parameters (const Buffer::Parameters& buffer_, 837 VkFormat format_, 838 VkDeviceSize offset_, 839 VkDeviceSize range_) 840 : buffer (buffer_) 841 , format (format_) 842 , offset (offset_) 843 , range (range_) 844 {} 845 }; 846 847 struct Resources 848 { 849 Dependency<Buffer> buffer; 850 Dependency<DeviceMemory> memory; 851 852 Resources (const Environment& env, const Parameters& params) 853 : buffer(env, params.buffer) 854 , memory(env, getDeviceMemoryParameters(env, *buffer.object)) 855 { 856 VK_CHECK(env.vkd.bindBufferMemory(env.device, *buffer.object, *memory.object, 0)); 857 } 858 }; 859 860 static deUint32 getMaxConcurrent (Context& context, const Parameters& params) 861 { 862 return getSafeObjectCount<BufferView>(context, params, DEFAULT_MAX_CONCURRENT_OBJECTS); 863 } 864 865 static Move<VkBufferView> create (const Environment& env, const Resources& res, const Parameters& params) 866 { 867 const VkBufferViewCreateInfo bufferViewInfo = 868 { 869 VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO, 870 DE_NULL, 871 (VkBufferViewCreateFlags)0, 872 *res.buffer.object, 873 params.format, 874 params.offset, 875 params.range 876 }; 877 878 return createBufferView(env.vkd, env.device, &bufferViewInfo, env.allocationCallbacks); 879 } 880 }; 881 882 struct Image 883 { 884 typedef VkImage Type; 885 886 struct Parameters 887 { 888 VkImageCreateFlags flags; 889 VkImageType imageType; 890 VkFormat format; 891 VkExtent3D extent; 892 deUint32 mipLevels; 893 deUint32 arraySize; 894 VkSampleCountFlagBits samples; 895 VkImageTiling tiling; 896 VkImageUsageFlags usage; 897 VkImageLayout initialLayout; 898 899 Parameters (VkImageCreateFlags flags_, 900 VkImageType imageType_, 901 VkFormat format_, 902 VkExtent3D extent_, 903 deUint32 mipLevels_, 904 deUint32 arraySize_, 905 VkSampleCountFlagBits samples_, 906 VkImageTiling tiling_, 907 VkImageUsageFlags usage_, 908 VkImageLayout initialLayout_) 909 : flags (flags_) 910 , imageType (imageType_) 911 , format (format_) 912 , extent (extent_) 913 , mipLevels (mipLevels_) 914 , arraySize (arraySize_) 915 , samples (samples_) 916 , tiling (tiling_) 917 , usage (usage_) 918 , initialLayout (initialLayout_) 919 {} 920 }; 921 922 struct Resources 923 { 924 Resources (const Environment&, const Parameters&) {} 925 }; 926 927 static deUint32 getMaxConcurrent (Context& context, const Parameters& params) 928 { 929 const Environment env (context, 1u); 930 const Resources res (env, params); 931 const Unique<VkImage> image (create(env, res, params)); 932 const VkMemoryRequirements memReqs = getImageMemoryRequirements(env.vkd, env.device, *image); 933 934 return getSafeObjectCount<Image>(context, 935 params, 936 DEFAULT_MAX_CONCURRENT_OBJECTS, 937 getPageTableSize(context, memReqs.size)); 938 } 939 940 static Move<VkImage> create (const Environment& env, const Resources&, const Parameters& params) 941 { 942 const VkImageCreateInfo imageInfo = 943 { 944 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, 945 DE_NULL, 946 params.flags, 947 params.imageType, 948 params.format, 949 params.extent, 950 params.mipLevels, 951 params.arraySize, 952 params.samples, 953 params.tiling, 954 params.usage, 955 VK_SHARING_MODE_EXCLUSIVE, // sharingMode 956 1u, // queueFamilyIndexCount 957 &env.queueFamilyIndex, // pQueueFamilyIndices 958 params.initialLayout 959 }; 960 961 return createImage(env.vkd, env.device, &imageInfo, env.allocationCallbacks); 962 } 963 }; 964 965 struct ImageView 966 { 967 typedef VkImageView Type; 968 969 struct Parameters 970 { 971 Image::Parameters image; 972 VkImageViewType viewType; 973 VkFormat format; 974 VkComponentMapping components; 975 VkImageSubresourceRange subresourceRange; 976 977 Parameters (const Image::Parameters& image_, 978 VkImageViewType viewType_, 979 VkFormat format_, 980 VkComponentMapping components_, 981 VkImageSubresourceRange subresourceRange_) 982 : image (image_) 983 , viewType (viewType_) 984 , format (format_) 985 , components (components_) 986 , subresourceRange (subresourceRange_) 987 {} 988 }; 989 990 struct Resources 991 { 992 Dependency<Image> image; 993 Dependency<DeviceMemory> memory; 994 995 Resources (const Environment& env, const Parameters& params) 996 : image (env, params.image) 997 , memory(env, getDeviceMemoryParameters(env, *image.object)) 998 { 999 VK_CHECK(env.vkd.bindImageMemory(env.device, *image.object, *memory.object, 0)); 1000 } 1001 }; 1002 1003 static deUint32 getMaxConcurrent (Context& context, const Parameters& params) 1004 { 1005 return getSafeObjectCount<ImageView>(context, params, DEFAULT_MAX_CONCURRENT_OBJECTS); 1006 } 1007 1008 static Move<VkImageView> create (const Environment& env, const Resources& res, const Parameters& params) 1009 { 1010 const VkImageViewCreateInfo imageViewInfo = 1011 { 1012 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, 1013 DE_NULL, 1014 (VkImageViewCreateFlags)0, 1015 *res.image.object, 1016 params.viewType, 1017 params.format, 1018 params.components, 1019 params.subresourceRange, 1020 }; 1021 1022 return createImageView(env.vkd, env.device, &imageViewInfo, env.allocationCallbacks); 1023 } 1024 }; 1025 1026 struct Semaphore 1027 { 1028 typedef VkSemaphore Type; 1029 1030 struct Parameters 1031 { 1032 VkSemaphoreCreateFlags flags; 1033 1034 Parameters (VkSemaphoreCreateFlags flags_) 1035 : flags(flags_) 1036 {} 1037 }; 1038 1039 struct Resources 1040 { 1041 Resources (const Environment&, const Parameters&) {} 1042 }; 1043 1044 static deUint32 getMaxConcurrent (Context& context, const Parameters& params) 1045 { 1046 return getSafeObjectCount<Semaphore>(context, params, MAX_CONCURRENT_SYNC_PRIMITIVES); 1047 } 1048 1049 static Move<VkSemaphore> create (const Environment& env, const Resources&, const Parameters& params) 1050 { 1051 const VkSemaphoreCreateInfo semaphoreInfo = 1052 { 1053 VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, 1054 DE_NULL, 1055 params.flags 1056 }; 1057 1058 return createSemaphore(env.vkd, env.device, &semaphoreInfo, env.allocationCallbacks); 1059 } 1060 }; 1061 1062 struct Fence 1063 { 1064 typedef VkFence Type; 1065 1066 struct Parameters 1067 { 1068 VkFenceCreateFlags flags; 1069 1070 Parameters (VkFenceCreateFlags flags_) 1071 : flags(flags_) 1072 {} 1073 }; 1074 1075 struct Resources 1076 { 1077 Resources (const Environment&, const Parameters&) {} 1078 }; 1079 1080 static deUint32 getMaxConcurrent (Context& context, const Parameters& params) 1081 { 1082 return getSafeObjectCount<Fence>(context, params, MAX_CONCURRENT_SYNC_PRIMITIVES); 1083 } 1084 1085 static Move<VkFence> create (const Environment& env, const Resources&, const Parameters& params) 1086 { 1087 const VkFenceCreateInfo fenceInfo = 1088 { 1089 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, 1090 DE_NULL, 1091 params.flags 1092 }; 1093 1094 return createFence(env.vkd, env.device, &fenceInfo, env.allocationCallbacks); 1095 } 1096 }; 1097 1098 struct Event 1099 { 1100 typedef VkEvent Type; 1101 1102 struct Parameters 1103 { 1104 VkEventCreateFlags flags; 1105 1106 Parameters (VkEventCreateFlags flags_) 1107 : flags(flags_) 1108 {} 1109 }; 1110 1111 struct Resources 1112 { 1113 Resources (const Environment&, const Parameters&) {} 1114 }; 1115 1116 static deUint32 getMaxConcurrent (Context& context, const Parameters& params) 1117 { 1118 return getSafeObjectCount<Event>(context, params, MAX_CONCURRENT_SYNC_PRIMITIVES); 1119 } 1120 1121 static Move<VkEvent> create (const Environment& env, const Resources&, const Parameters& params) 1122 { 1123 const VkEventCreateInfo eventInfo = 1124 { 1125 VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, 1126 DE_NULL, 1127 params.flags 1128 }; 1129 1130 return createEvent(env.vkd, env.device, &eventInfo, env.allocationCallbacks); 1131 } 1132 }; 1133 1134 struct QueryPool 1135 { 1136 typedef VkQueryPool Type; 1137 1138 struct Parameters 1139 { 1140 VkQueryType queryType; 1141 deUint32 entryCount; 1142 VkQueryPipelineStatisticFlags pipelineStatistics; 1143 1144 Parameters (VkQueryType queryType_, 1145 deUint32 entryCount_, 1146 VkQueryPipelineStatisticFlags pipelineStatistics_) 1147 : queryType (queryType_) 1148 , entryCount (entryCount_) 1149 , pipelineStatistics (pipelineStatistics_) 1150 {} 1151 }; 1152 1153 struct Resources 1154 { 1155 Resources (const Environment&, const Parameters&) {} 1156 }; 1157 1158 static deUint32 getMaxConcurrent (Context& context, const Parameters& params) 1159 { 1160 return getSafeObjectCount<QueryPool>(context, params, DEFAULT_MAX_CONCURRENT_OBJECTS); 1161 } 1162 1163 static Move<VkQueryPool> create (const Environment& env, const Resources&, const Parameters& params) 1164 { 1165 const VkQueryPoolCreateInfo queryPoolInfo = 1166 { 1167 VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO, 1168 DE_NULL, 1169 (VkQueryPoolCreateFlags)0, 1170 params.queryType, 1171 params.entryCount, 1172 params.pipelineStatistics 1173 }; 1174 1175 return createQueryPool(env.vkd, env.device, &queryPoolInfo, env.allocationCallbacks); 1176 } 1177 }; 1178 1179 struct ShaderModule 1180 { 1181 typedef VkShaderModule Type; 1182 1183 struct Parameters 1184 { 1185 VkShaderStageFlagBits shaderStage; 1186 string binaryName; 1187 1188 Parameters (VkShaderStageFlagBits shaderStage_, 1189 const std::string& binaryName_) 1190 : shaderStage (shaderStage_) 1191 , binaryName (binaryName_) 1192 {} 1193 }; 1194 1195 struct Resources 1196 { 1197 const ProgramBinary& binary; 1198 1199 Resources (const Environment& env, const Parameters& params) 1200 : binary(env.programBinaries.get(params.binaryName)) 1201 {} 1202 }; 1203 1204 static deUint32 getMaxConcurrent (Context& context, const Parameters& params) 1205 { 1206 return getSafeObjectCount<ShaderModule>(context, params, DEFAULT_MAX_CONCURRENT_OBJECTS); 1207 } 1208 1209 static const char* getSource (VkShaderStageFlagBits stage) 1210 { 1211 switch (stage) 1212 { 1213 case VK_SHADER_STAGE_VERTEX_BIT: 1214 return "#version 310 es\n" 1215 "layout(location = 0) in highp vec4 a_position;\n" 1216 "void main () { gl_Position = a_position; }\n"; 1217 1218 case VK_SHADER_STAGE_FRAGMENT_BIT: 1219 return "#version 310 es\n" 1220 "layout(location = 0) out mediump vec4 o_color;\n" 1221 "void main () { o_color = vec4(1.0, 0.5, 0.25, 1.0); }"; 1222 1223 case VK_SHADER_STAGE_COMPUTE_BIT: 1224 return "#version 310 es\n" 1225 "layout(binding = 0) buffer Input { highp uint dataIn[]; };\n" 1226 "layout(binding = 1) buffer Output { highp uint dataOut[]; };\n" 1227 "void main (void)\n" 1228 "{\n" 1229 " dataOut[gl_GlobalInvocationID.x] = ~dataIn[gl_GlobalInvocationID.x];\n" 1230 "}\n"; 1231 1232 default: 1233 DE_FATAL("Not implemented"); 1234 return DE_NULL; 1235 } 1236 } 1237 1238 static void initPrograms (SourceCollections& dst, Parameters params) 1239 { 1240 const char* const source = getSource(params.shaderStage); 1241 1242 DE_ASSERT(source); 1243 1244 dst.glslSources.add(params.binaryName) 1245 << glu::ShaderSource(getGluShaderType(params.shaderStage), source); 1246 } 1247 1248 static Move<VkShaderModule> create (const Environment& env, const Resources& res, const Parameters&) 1249 { 1250 const VkShaderModuleCreateInfo shaderModuleInfo = 1251 { 1252 VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, 1253 DE_NULL, 1254 (VkShaderModuleCreateFlags)0, 1255 res.binary.getSize(), 1256 (const deUint32*)res.binary.getBinary(), 1257 }; 1258 1259 return createShaderModule(env.vkd, env.device, &shaderModuleInfo, env.allocationCallbacks); 1260 } 1261 }; 1262 1263 struct PipelineCache 1264 { 1265 typedef VkPipelineCache Type; 1266 1267 struct Parameters 1268 { 1269 Parameters (void) {} 1270 }; 1271 1272 struct Resources 1273 { 1274 Resources (const Environment&, const Parameters&) {} 1275 }; 1276 1277 static deUint32 getMaxConcurrent (Context& context, const Parameters& params) 1278 { 1279 return getSafeObjectCount<PipelineCache>(context, params, MAX_CONCURRENT_PIPELINE_CACHES); 1280 } 1281 1282 static Move<VkPipelineCache> create (const Environment& env, const Resources&, const Parameters&) 1283 { 1284 const VkPipelineCacheCreateInfo pipelineCacheInfo = 1285 { 1286 VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, 1287 DE_NULL, 1288 (VkPipelineCacheCreateFlags)0u, 1289 0u, // initialDataSize 1290 DE_NULL, // pInitialData 1291 }; 1292 1293 return createPipelineCache(env.vkd, env.device, &pipelineCacheInfo, env.allocationCallbacks); 1294 } 1295 }; 1296 1297 struct Sampler 1298 { 1299 typedef VkSampler Type; 1300 1301 struct Parameters 1302 { 1303 VkFilter magFilter; 1304 VkFilter minFilter; 1305 VkSamplerMipmapMode mipmapMode; 1306 VkSamplerAddressMode addressModeU; 1307 VkSamplerAddressMode addressModeV; 1308 VkSamplerAddressMode addressModeW; 1309 float mipLodBias; 1310 VkBool32 anisotropyEnable; 1311 float maxAnisotropy; 1312 VkBool32 compareEnable; 1313 VkCompareOp compareOp; 1314 float minLod; 1315 float maxLod; 1316 VkBorderColor borderColor; 1317 VkBool32 unnormalizedCoordinates; 1318 1319 // \todo [2015-09-17 pyry] Other configurations 1320 Parameters (void) 1321 : magFilter (VK_FILTER_NEAREST) 1322 , minFilter (VK_FILTER_NEAREST) 1323 , mipmapMode (VK_SAMPLER_MIPMAP_MODE_NEAREST) 1324 , addressModeU (VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE) 1325 , addressModeV (VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE) 1326 , addressModeW (VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE) 1327 , mipLodBias (0.0f) 1328 , anisotropyEnable (VK_FALSE) 1329 , maxAnisotropy (1.0f) 1330 , compareEnable (VK_FALSE) 1331 , compareOp (VK_COMPARE_OP_ALWAYS) 1332 , minLod (-1000.f) 1333 , maxLod (+1000.f) 1334 , borderColor (VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK) 1335 , unnormalizedCoordinates (VK_FALSE) 1336 {} 1337 }; 1338 1339 struct Resources 1340 { 1341 Resources (const Environment&, const Parameters&) {} 1342 }; 1343 1344 static deUint32 getMaxConcurrent (Context& context, const Parameters& params) 1345 { 1346 return getSafeObjectCount<Sampler>(context, 1347 params, 1348 de::min(context.getDeviceProperties().limits.maxSamplerAllocationCount, 1349 (deUint32)DEFAULT_MAX_CONCURRENT_OBJECTS)); 1350 } 1351 1352 static Move<VkSampler> create (const Environment& env, const Resources&, const Parameters& params) 1353 { 1354 const VkSamplerCreateInfo samplerInfo = 1355 { 1356 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, 1357 DE_NULL, 1358 (VkSamplerCreateFlags)0, 1359 params.magFilter, 1360 params.minFilter, 1361 params.mipmapMode, 1362 params.addressModeU, 1363 params.addressModeV, 1364 params.addressModeW, 1365 params.mipLodBias, 1366 params.anisotropyEnable, 1367 params.maxAnisotropy, 1368 params.compareEnable, 1369 params.compareOp, 1370 params.minLod, 1371 params.maxLod, 1372 params.borderColor, 1373 params.unnormalizedCoordinates 1374 }; 1375 1376 return createSampler(env.vkd, env.device, &samplerInfo, env.allocationCallbacks); 1377 } 1378 }; 1379 1380 struct DescriptorSetLayout 1381 { 1382 typedef VkDescriptorSetLayout Type; 1383 1384 struct Parameters 1385 { 1386 struct Binding 1387 { 1388 deUint32 binding; 1389 VkDescriptorType descriptorType; 1390 deUint32 descriptorCount; 1391 VkShaderStageFlags stageFlags; 1392 bool useImmutableSampler; 1393 1394 Binding (deUint32 binding_, 1395 VkDescriptorType descriptorType_, 1396 deUint32 descriptorCount_, 1397 VkShaderStageFlags stageFlags_, 1398 bool useImmutableSampler_) 1399 : binding (binding_) 1400 , descriptorType (descriptorType_) 1401 , descriptorCount (descriptorCount_) 1402 , stageFlags (stageFlags_) 1403 , useImmutableSampler (useImmutableSampler_) 1404 {} 1405 1406 Binding (void) {} 1407 }; 1408 1409 vector<Binding> bindings; 1410 1411 Parameters (const vector<Binding>& bindings_) 1412 : bindings(bindings_) 1413 {} 1414 1415 static Parameters empty (void) 1416 { 1417 return Parameters(vector<Binding>()); 1418 } 1419 1420 static Parameters single (deUint32 binding, 1421 VkDescriptorType descriptorType, 1422 deUint32 descriptorCount, 1423 VkShaderStageFlags stageFlags, 1424 bool useImmutableSampler = false) 1425 { 1426 vector<Binding> bindings; 1427 bindings.push_back(Binding(binding, descriptorType, descriptorCount, stageFlags, useImmutableSampler)); 1428 return Parameters(bindings); 1429 } 1430 }; 1431 1432 struct Resources 1433 { 1434 vector<VkDescriptorSetLayoutBinding> bindings; 1435 MovePtr<Dependency<Sampler> > immutableSampler; 1436 vector<VkSampler> immutableSamplersPtr; 1437 1438 Resources (const Environment& env, const Parameters& params) 1439 { 1440 // Create immutable sampler if needed 1441 for (vector<Parameters::Binding>::const_iterator cur = params.bindings.begin(); cur != params.bindings.end(); cur++) 1442 { 1443 if (cur->useImmutableSampler && !immutableSampler) 1444 { 1445 immutableSampler = de::newMovePtr<Dependency<Sampler> >(env, Sampler::Parameters()); 1446 1447 if (cur->useImmutableSampler && immutableSamplersPtr.size() < (size_t)cur->descriptorCount) 1448 immutableSamplersPtr.resize(cur->descriptorCount, *immutableSampler->object); 1449 } 1450 } 1451 1452 for (vector<Parameters::Binding>::const_iterator cur = params.bindings.begin(); cur != params.bindings.end(); cur++) 1453 { 1454 const VkDescriptorSetLayoutBinding binding = 1455 { 1456 cur->binding, 1457 cur->descriptorType, 1458 cur->descriptorCount, 1459 cur->stageFlags, 1460 (cur->useImmutableSampler ? &immutableSamplersPtr[0] : DE_NULL) 1461 }; 1462 1463 bindings.push_back(binding); 1464 } 1465 } 1466 }; 1467 1468 static deUint32 getMaxConcurrent (Context& context, const Parameters& params) 1469 { 1470 return getSafeObjectCount<DescriptorSetLayout>(context, params, DEFAULT_MAX_CONCURRENT_OBJECTS); 1471 } 1472 1473 static Move<VkDescriptorSetLayout> create (const Environment& env, const Resources& res, const Parameters&) 1474 { 1475 const VkDescriptorSetLayoutCreateInfo descriptorSetLayoutInfo = 1476 { 1477 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, 1478 DE_NULL, 1479 (VkDescriptorSetLayoutCreateFlags)0, 1480 (deUint32)res.bindings.size(), 1481 (res.bindings.empty() ? DE_NULL : &res.bindings[0]) 1482 }; 1483 1484 return createDescriptorSetLayout(env.vkd, env.device, &descriptorSetLayoutInfo, env.allocationCallbacks); 1485 } 1486 }; 1487 1488 struct PipelineLayout 1489 { 1490 typedef VkPipelineLayout Type; 1491 1492 struct Parameters 1493 { 1494 vector<DescriptorSetLayout::Parameters> descriptorSetLayouts; 1495 vector<VkPushConstantRange> pushConstantRanges; 1496 1497 Parameters (void) {} 1498 1499 static Parameters empty (void) 1500 { 1501 return Parameters(); 1502 } 1503 1504 static Parameters singleDescriptorSet (const DescriptorSetLayout::Parameters& descriptorSetLayout) 1505 { 1506 Parameters params; 1507 params.descriptorSetLayouts.push_back(descriptorSetLayout); 1508 return params; 1509 } 1510 }; 1511 1512 struct Resources 1513 { 1514 typedef SharedPtr<Dependency<DescriptorSetLayout> > DescriptorSetLayoutDepSp; 1515 typedef vector<DescriptorSetLayoutDepSp> DescriptorSetLayouts; 1516 1517 DescriptorSetLayouts descriptorSetLayouts; 1518 vector<VkDescriptorSetLayout> pSetLayouts; 1519 1520 Resources (const Environment& env, const Parameters& params) 1521 { 1522 for (vector<DescriptorSetLayout::Parameters>::const_iterator dsParams = params.descriptorSetLayouts.begin(); 1523 dsParams != params.descriptorSetLayouts.end(); 1524 ++dsParams) 1525 { 1526 descriptorSetLayouts.push_back(DescriptorSetLayoutDepSp(new Dependency<DescriptorSetLayout>(env, *dsParams))); 1527 pSetLayouts.push_back(*descriptorSetLayouts.back()->object); 1528 } 1529 } 1530 }; 1531 1532 static deUint32 getMaxConcurrent (Context& context, const Parameters& params) 1533 { 1534 return getSafeObjectCount<PipelineLayout>(context, params, DEFAULT_MAX_CONCURRENT_OBJECTS); 1535 } 1536 1537 static Move<VkPipelineLayout> create (const Environment& env, const Resources& res, const Parameters& params) 1538 { 1539 const VkPipelineLayoutCreateInfo pipelineLayoutInfo = 1540 { 1541 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, 1542 DE_NULL, 1543 (VkPipelineLayoutCreateFlags)0, 1544 (deUint32)res.pSetLayouts.size(), 1545 (res.pSetLayouts.empty() ? DE_NULL : &res.pSetLayouts[0]), 1546 (deUint32)params.pushConstantRanges.size(), 1547 (params.pushConstantRanges.empty() ? DE_NULL : ¶ms.pushConstantRanges[0]), 1548 }; 1549 1550 return createPipelineLayout(env.vkd, env.device, &pipelineLayoutInfo, env.allocationCallbacks); 1551 } 1552 }; 1553 1554 struct RenderPass 1555 { 1556 typedef VkRenderPass Type; 1557 1558 // \todo [2015-09-17 pyry] More interesting configurations 1559 struct Parameters 1560 { 1561 Parameters (void) {} 1562 }; 1563 1564 struct Resources 1565 { 1566 Resources (const Environment&, const Parameters&) {} 1567 }; 1568 1569 static deUint32 getMaxConcurrent (Context& context, const Parameters& params) 1570 { 1571 return getSafeObjectCount<RenderPass>(context, params, DEFAULT_MAX_CONCURRENT_OBJECTS); 1572 } 1573 1574 static Move<VkRenderPass> create (const Environment& env, const Resources&, const Parameters&) 1575 { 1576 return makeRenderPass(env.vkd, env.device, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_D16_UNORM, 1577 VK_ATTACHMENT_LOAD_OP_CLEAR, 1578 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 1579 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 1580 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 1581 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 1582 env.allocationCallbacks); 1583 } 1584 }; 1585 1586 struct GraphicsPipeline 1587 { 1588 typedef VkPipeline Type; 1589 1590 // \todo [2015-09-17 pyry] More interesting configurations 1591 struct Parameters 1592 { 1593 Parameters (void) {} 1594 }; 1595 1596 struct Resources 1597 { 1598 Dependency<ShaderModule> vertexShader; 1599 Dependency<ShaderModule> fragmentShader; 1600 Dependency<PipelineLayout> layout; 1601 Dependency<RenderPass> renderPass; 1602 Dependency<PipelineCache> pipelineCache; 1603 1604 Resources (const Environment& env, const Parameters&) 1605 : vertexShader (env, ShaderModule::Parameters(VK_SHADER_STAGE_VERTEX_BIT, "vert")) 1606 , fragmentShader (env, ShaderModule::Parameters(VK_SHADER_STAGE_FRAGMENT_BIT, "frag")) 1607 , layout (env, PipelineLayout::Parameters::singleDescriptorSet( 1608 DescriptorSetLayout::Parameters::single(0u, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1u, VK_SHADER_STAGE_FRAGMENT_BIT, true))) 1609 , renderPass (env, RenderPass::Parameters()) 1610 , pipelineCache (env, PipelineCache::Parameters()) 1611 {} 1612 }; 1613 1614 static deUint32 getMaxConcurrent (Context& context, const Parameters& params) 1615 { 1616 return getSafeObjectCount<GraphicsPipeline>(context, params, DEFAULT_MAX_CONCURRENT_OBJECTS); 1617 } 1618 1619 static void initPrograms (SourceCollections& dst, Parameters) 1620 { 1621 ShaderModule::initPrograms(dst, ShaderModule::Parameters(VK_SHADER_STAGE_VERTEX_BIT, "vert")); 1622 ShaderModule::initPrograms(dst, ShaderModule::Parameters(VK_SHADER_STAGE_FRAGMENT_BIT, "frag")); 1623 } 1624 1625 static vector<VkPipelineSp> createMultiple (const Environment& env, const Resources& res, const Parameters&, vector<VkPipeline>* const pOutHandles, VkResult* const pOutResult) 1626 { 1627 DE_ASSERT(pOutResult); 1628 DE_ASSERT(pOutHandles); 1629 DE_ASSERT(pOutHandles->size() != 0); 1630 1631 const VkPipelineShaderStageCreateInfo stages[] = 1632 { 1633 { 1634 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, 1635 DE_NULL, 1636 (VkPipelineShaderStageCreateFlags)0, 1637 VK_SHADER_STAGE_VERTEX_BIT, 1638 *res.vertexShader.object, 1639 "main", 1640 DE_NULL, // pSpecializationInfo 1641 }, 1642 { 1643 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, 1644 DE_NULL, 1645 (VkPipelineShaderStageCreateFlags)0, 1646 VK_SHADER_STAGE_FRAGMENT_BIT, 1647 *res.fragmentShader.object, 1648 "main", 1649 DE_NULL, // pSpecializationInfo 1650 } 1651 }; 1652 const VkVertexInputBindingDescription vertexBindings[] = 1653 { 1654 { 1655 0u, // binding 1656 16u, // stride 1657 VK_VERTEX_INPUT_RATE_VERTEX 1658 } 1659 }; 1660 const VkVertexInputAttributeDescription vertexAttribs[] = 1661 { 1662 { 1663 0u, // location 1664 0u, // binding 1665 VK_FORMAT_R32G32B32A32_SFLOAT, 1666 0u, // offset 1667 } 1668 }; 1669 const VkPipelineVertexInputStateCreateInfo vertexInputState = 1670 { 1671 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, 1672 DE_NULL, 1673 (VkPipelineVertexInputStateCreateFlags)0, 1674 DE_LENGTH_OF_ARRAY(vertexBindings), 1675 vertexBindings, 1676 DE_LENGTH_OF_ARRAY(vertexAttribs), 1677 vertexAttribs 1678 }; 1679 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = 1680 { 1681 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, 1682 DE_NULL, 1683 (VkPipelineInputAssemblyStateCreateFlags)0, 1684 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 1685 VK_FALSE // primitiveRestartEnable 1686 }; 1687 const VkViewport viewport = makeViewport(tcu::UVec2(64)); 1688 const VkRect2D scissor = makeRect2D(tcu::UVec2(64)); 1689 1690 const VkPipelineViewportStateCreateInfo viewportState = 1691 { 1692 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, 1693 DE_NULL, 1694 (VkPipelineViewportStateCreateFlags)0, 1695 1u, 1696 &viewport, 1697 1u, 1698 &scissor, 1699 }; 1700 const VkPipelineRasterizationStateCreateInfo rasterState = 1701 { 1702 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, 1703 DE_NULL, 1704 (VkPipelineRasterizationStateCreateFlags)0, 1705 VK_FALSE, // depthClampEnable 1706 VK_FALSE, // rasterizerDiscardEnable 1707 VK_POLYGON_MODE_FILL, 1708 VK_CULL_MODE_BACK_BIT, 1709 VK_FRONT_FACE_COUNTER_CLOCKWISE, 1710 VK_FALSE, // depthBiasEnable 1711 0.0f, // depthBiasConstantFactor 1712 0.0f, // depthBiasClamp 1713 0.0f, // depthBiasSlopeFactor 1714 1.0f, // lineWidth 1715 }; 1716 const VkPipelineMultisampleStateCreateInfo multisampleState = 1717 { 1718 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, 1719 DE_NULL, 1720 (VkPipelineMultisampleStateCreateFlags)0, 1721 VK_SAMPLE_COUNT_1_BIT, 1722 VK_FALSE, // sampleShadingEnable 1723 1.0f, // minSampleShading 1724 DE_NULL, // pSampleMask 1725 VK_FALSE, // alphaToCoverageEnable 1726 VK_FALSE, // alphaToOneEnable 1727 }; 1728 const VkPipelineDepthStencilStateCreateInfo depthStencilState = 1729 { 1730 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, 1731 DE_NULL, 1732 (VkPipelineDepthStencilStateCreateFlags)0, 1733 VK_TRUE, // depthTestEnable 1734 VK_TRUE, // depthWriteEnable 1735 VK_COMPARE_OP_LESS, // depthCompareOp 1736 VK_FALSE, // depthBoundsTestEnable 1737 VK_FALSE, // stencilTestEnable 1738 { VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_COMPARE_OP_ALWAYS, 0u, 0u, 0u }, 1739 { VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_COMPARE_OP_ALWAYS, 0u, 0u, 0u }, 1740 0.0f, // minDepthBounds 1741 1.0f, // maxDepthBounds 1742 }; 1743 const VkPipelineColorBlendAttachmentState colorBlendAttState[]= 1744 { 1745 { 1746 VK_FALSE, // blendEnable 1747 VK_BLEND_FACTOR_ONE, 1748 VK_BLEND_FACTOR_ZERO, 1749 VK_BLEND_OP_ADD, 1750 VK_BLEND_FACTOR_ONE, 1751 VK_BLEND_FACTOR_ZERO, 1752 VK_BLEND_OP_ADD, 1753 VK_COLOR_COMPONENT_R_BIT|VK_COLOR_COMPONENT_G_BIT|VK_COLOR_COMPONENT_B_BIT|VK_COLOR_COMPONENT_A_BIT 1754 } 1755 }; 1756 const VkPipelineColorBlendStateCreateInfo colorBlendState = 1757 { 1758 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, 1759 DE_NULL, 1760 (VkPipelineColorBlendStateCreateFlags)0, 1761 VK_FALSE, // logicOpEnable 1762 VK_LOGIC_OP_COPY, 1763 DE_LENGTH_OF_ARRAY(colorBlendAttState), 1764 colorBlendAttState, 1765 { 0.0f, 0.0f, 0.0f, 0.0f } // blendConstants 1766 }; 1767 const VkGraphicsPipelineCreateInfo pipelineInfo = 1768 { 1769 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, 1770 DE_NULL, 1771 (VkPipelineCreateFlags)0, 1772 DE_LENGTH_OF_ARRAY(stages), 1773 stages, 1774 &vertexInputState, 1775 &inputAssemblyState, 1776 DE_NULL, // pTessellationState 1777 &viewportState, 1778 &rasterState, 1779 &multisampleState, 1780 &depthStencilState, 1781 &colorBlendState, 1782 (const VkPipelineDynamicStateCreateInfo*)DE_NULL, 1783 *res.layout.object, 1784 *res.renderPass.object, 1785 0u, // subpass 1786 (VkPipeline)0, // basePipelineHandle 1787 0, // basePipelineIndex 1788 }; 1789 1790 const deUint32 numPipelines = static_cast<deUint32>(pOutHandles->size()); 1791 VkPipeline* const pHandles = &(*pOutHandles)[0]; 1792 vector<VkGraphicsPipelineCreateInfo> pipelineInfos (numPipelines, pipelineInfo); 1793 1794 *pOutResult = env.vkd.createGraphicsPipelines(env.device, *res.pipelineCache.object, numPipelines, &pipelineInfos[0], env.allocationCallbacks, pHandles); 1795 1796 vector<VkPipelineSp> pipelines; 1797 1798 // Even if an error is returned, some pipelines may have been created successfully 1799 for (deUint32 i = 0; i < numPipelines; ++i) 1800 { 1801 if (pHandles[i] != DE_NULL) 1802 pipelines.push_back(VkPipelineSp(new Move<VkPipeline>(check<VkPipeline>(pHandles[i]), Deleter<VkPipeline>(env.vkd, env.device, env.allocationCallbacks)))); 1803 } 1804 1805 return pipelines; 1806 } 1807 1808 static Move<VkPipeline> create (const Environment& env, const Resources& res, const Parameters&) 1809 { 1810 vector<VkPipeline> handles (1, DE_NULL); 1811 VkResult result = VK_NOT_READY; 1812 vector<VkPipelineSp> scopedHandles = createMultiple(env, res, Parameters(), &handles, &result); 1813 1814 VK_CHECK(result); 1815 return Move<VkPipeline>(check<VkPipeline>(scopedHandles.front()->disown()), Deleter<VkPipeline>(env.vkd, env.device, env.allocationCallbacks)); 1816 } 1817 }; 1818 1819 struct ComputePipeline 1820 { 1821 typedef VkPipeline Type; 1822 1823 // \todo [2015-09-17 pyry] More interesting configurations 1824 struct Parameters 1825 { 1826 Parameters (void) {} 1827 }; 1828 1829 struct Resources 1830 { 1831 Dependency<ShaderModule> shaderModule; 1832 Dependency<PipelineLayout> layout; 1833 Dependency<PipelineCache> pipelineCache; 1834 1835 static DescriptorSetLayout::Parameters getDescriptorSetLayout (void) 1836 { 1837 typedef DescriptorSetLayout::Parameters::Binding Binding; 1838 1839 vector<Binding> bindings; 1840 1841 bindings.push_back(Binding(0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1u, VK_SHADER_STAGE_COMPUTE_BIT, false)); 1842 bindings.push_back(Binding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1u, VK_SHADER_STAGE_COMPUTE_BIT, false)); 1843 1844 return DescriptorSetLayout::Parameters(bindings); 1845 } 1846 1847 Resources (const Environment& env, const Parameters&) 1848 : shaderModule (env, ShaderModule::Parameters(VK_SHADER_STAGE_COMPUTE_BIT, "comp")) 1849 , layout (env, PipelineLayout::Parameters::singleDescriptorSet(getDescriptorSetLayout())) 1850 , pipelineCache (env, PipelineCache::Parameters()) 1851 {} 1852 }; 1853 1854 static deUint32 getMaxConcurrent (Context& context, const Parameters& params) 1855 { 1856 return getSafeObjectCount<ComputePipeline>(context, params, DEFAULT_MAX_CONCURRENT_OBJECTS); 1857 } 1858 1859 static void initPrograms (SourceCollections& dst, Parameters) 1860 { 1861 ShaderModule::initPrograms(dst, ShaderModule::Parameters(VK_SHADER_STAGE_COMPUTE_BIT, "comp")); 1862 } 1863 1864 static Move<VkPipeline> create (const Environment& env, const Resources& res, const Parameters&) 1865 { 1866 const VkComputePipelineCreateInfo pipelineInfo = 1867 { 1868 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, 1869 DE_NULL, 1870 (VkPipelineCreateFlags)0, 1871 { 1872 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, 1873 DE_NULL, 1874 (VkPipelineShaderStageCreateFlags)0, 1875 VK_SHADER_STAGE_COMPUTE_BIT, 1876 *res.shaderModule.object, 1877 "main", 1878 DE_NULL // pSpecializationInfo 1879 }, 1880 *res.layout.object, 1881 (VkPipeline)0, // basePipelineHandle 1882 0u, // basePipelineIndex 1883 }; 1884 1885 return createComputePipeline(env.vkd, env.device, *res.pipelineCache.object, &pipelineInfo, env.allocationCallbacks); 1886 } 1887 1888 static vector<VkPipelineSp> createMultiple (const Environment& env, const Resources& res, const Parameters&, vector<VkPipeline>* const pOutHandles, VkResult* const pOutResult) 1889 { 1890 DE_ASSERT(pOutResult); 1891 DE_ASSERT(pOutHandles); 1892 DE_ASSERT(pOutHandles->size() != 0); 1893 1894 const VkComputePipelineCreateInfo commonPipelineInfo = 1895 { 1896 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, 1897 DE_NULL, 1898 (VkPipelineCreateFlags)0, 1899 { 1900 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, 1901 DE_NULL, 1902 (VkPipelineShaderStageCreateFlags)0, 1903 VK_SHADER_STAGE_COMPUTE_BIT, 1904 *res.shaderModule.object, 1905 "main", 1906 DE_NULL // pSpecializationInfo 1907 }, 1908 *res.layout.object, 1909 (VkPipeline)0, // basePipelineHandle 1910 0u, // basePipelineIndex 1911 }; 1912 1913 const deUint32 numPipelines = static_cast<deUint32>(pOutHandles->size()); 1914 VkPipeline* const pHandles = &(*pOutHandles)[0]; 1915 vector<VkComputePipelineCreateInfo> pipelineInfos (numPipelines, commonPipelineInfo); 1916 1917 *pOutResult = env.vkd.createComputePipelines(env.device, *res.pipelineCache.object, numPipelines, &pipelineInfos[0], env.allocationCallbacks, pHandles); 1918 1919 vector<VkPipelineSp> pipelines; 1920 1921 // Even if an error is returned, some pipelines may have been created successfully 1922 for (deUint32 i = 0; i < numPipelines; ++i) 1923 { 1924 if (pHandles[i] != DE_NULL) 1925 pipelines.push_back(VkPipelineSp(new Move<VkPipeline>(check<VkPipeline>(pHandles[i]), Deleter<VkPipeline>(env.vkd, env.device, env.allocationCallbacks)))); 1926 } 1927 1928 return pipelines; 1929 } 1930 }; 1931 1932 struct DescriptorPool 1933 { 1934 typedef VkDescriptorPool Type; 1935 1936 struct Parameters 1937 { 1938 VkDescriptorPoolCreateFlags flags; 1939 deUint32 maxSets; 1940 vector<VkDescriptorPoolSize> poolSizes; 1941 1942 Parameters (VkDescriptorPoolCreateFlags flags_, 1943 deUint32 maxSets_, 1944 const vector<VkDescriptorPoolSize>& poolSizes_) 1945 : flags (flags_) 1946 , maxSets (maxSets_) 1947 , poolSizes (poolSizes_) 1948 {} 1949 1950 static Parameters singleType (VkDescriptorPoolCreateFlags flags, 1951 deUint32 maxSets, 1952 VkDescriptorType type, 1953 deUint32 count) 1954 { 1955 vector<VkDescriptorPoolSize> poolSizes; 1956 poolSizes.push_back(makeDescriptorPoolSize(type, count)); 1957 return Parameters(flags, maxSets, poolSizes); 1958 } 1959 }; 1960 1961 struct Resources 1962 { 1963 Resources (const Environment&, const Parameters&) {} 1964 }; 1965 1966 static deUint32 getMaxConcurrent (Context& context, const Parameters& params) 1967 { 1968 return getSafeObjectCount<DescriptorPool>(context, params, DEFAULT_MAX_CONCURRENT_OBJECTS); 1969 } 1970 1971 static Move<VkDescriptorPool> create (const Environment& env, const Resources&, const Parameters& params) 1972 { 1973 const VkDescriptorPoolCreateInfo descriptorPoolInfo = 1974 { 1975 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, 1976 DE_NULL, 1977 params.flags, 1978 params.maxSets, 1979 (deUint32)params.poolSizes.size(), 1980 (params.poolSizes.empty() ? DE_NULL : ¶ms.poolSizes[0]) 1981 }; 1982 1983 return createDescriptorPool(env.vkd, env.device, &descriptorPoolInfo, env.allocationCallbacks); 1984 } 1985 }; 1986 1987 struct DescriptorSet 1988 { 1989 typedef VkDescriptorSet Type; 1990 1991 struct Parameters 1992 { 1993 DescriptorSetLayout::Parameters descriptorSetLayout; 1994 1995 Parameters (const DescriptorSetLayout::Parameters& descriptorSetLayout_) 1996 : descriptorSetLayout(descriptorSetLayout_) 1997 {} 1998 }; 1999 2000 struct Resources 2001 { 2002 Dependency<DescriptorPool> descriptorPool; 2003 Dependency<DescriptorSetLayout> descriptorSetLayout; 2004 2005 static vector<VkDescriptorPoolSize> computePoolSizes (const DescriptorSetLayout::Parameters& layout, int maxSets) 2006 { 2007 deUint32 countByType[VK_DESCRIPTOR_TYPE_LAST]; 2008 vector<VkDescriptorPoolSize> typeCounts; 2009 2010 std::fill(DE_ARRAY_BEGIN(countByType), DE_ARRAY_END(countByType), 0u); 2011 2012 for (vector<DescriptorSetLayout::Parameters::Binding>::const_iterator cur = layout.bindings.begin(); 2013 cur != layout.bindings.end(); 2014 ++cur) 2015 { 2016 DE_ASSERT((deUint32)cur->descriptorType < VK_DESCRIPTOR_TYPE_LAST); 2017 countByType[cur->descriptorType] += cur->descriptorCount * maxSets; 2018 } 2019 2020 for (deUint32 type = 0; type < VK_DESCRIPTOR_TYPE_LAST; ++type) 2021 { 2022 if (countByType[type] > 0) 2023 typeCounts.push_back(makeDescriptorPoolSize((VkDescriptorType)type, countByType[type])); 2024 } 2025 2026 return typeCounts; 2027 } 2028 2029 Resources (const Environment& env, const Parameters& params) 2030 : descriptorPool (env, DescriptorPool::Parameters(VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, env.maxResourceConsumers, computePoolSizes(params.descriptorSetLayout, env.maxResourceConsumers))) 2031 , descriptorSetLayout (env, params.descriptorSetLayout) 2032 { 2033 } 2034 }; 2035 2036 static deUint32 getMaxConcurrent (Context& context, const Parameters& params) 2037 { 2038 return getSafeObjectCount<DescriptorSet>(context, params, DEFAULT_MAX_CONCURRENT_OBJECTS); 2039 } 2040 2041 static Move<VkDescriptorSet> create (const Environment& env, const Resources& res, const Parameters&) 2042 { 2043 const VkDescriptorSetAllocateInfo allocateInfo = 2044 { 2045 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, 2046 DE_NULL, 2047 *res.descriptorPool.object, 2048 1u, 2049 &res.descriptorSetLayout.object.get(), 2050 }; 2051 2052 return allocateDescriptorSet(env.vkd, env.device, &allocateInfo); 2053 } 2054 2055 static vector<VkDescriptorSetSp> createMultiple (const Environment& env, const Resources& res, const Parameters&, vector<VkDescriptorSet>* const pOutHandles, VkResult* const pOutResult) 2056 { 2057 DE_ASSERT(pOutResult); 2058 DE_ASSERT(pOutHandles); 2059 DE_ASSERT(pOutHandles->size() != 0); 2060 2061 const deUint32 numDescriptorSets = static_cast<deUint32>(pOutHandles->size()); 2062 VkDescriptorSet* const pHandles = &(*pOutHandles)[0]; 2063 const vector<VkDescriptorSetLayout> descriptorSetLayouts (numDescriptorSets, res.descriptorSetLayout.object.get()); 2064 2065 const VkDescriptorSetAllocateInfo allocateInfo = 2066 { 2067 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, 2068 DE_NULL, 2069 *res.descriptorPool.object, 2070 numDescriptorSets, 2071 &descriptorSetLayouts[0], 2072 }; 2073 2074 *pOutResult = env.vkd.allocateDescriptorSets(env.device, &allocateInfo, pHandles); 2075 2076 vector<VkDescriptorSetSp> descriptorSets; 2077 2078 if (*pOutResult == VK_SUCCESS) 2079 { 2080 for (deUint32 i = 0; i < numDescriptorSets; ++i) 2081 descriptorSets.push_back(VkDescriptorSetSp(new Move<VkDescriptorSet>(check<VkDescriptorSet>(pHandles[i]), Deleter<VkDescriptorSet>(env.vkd, env.device, *res.descriptorPool.object)))); 2082 } 2083 2084 return descriptorSets; 2085 } 2086 }; 2087 2088 struct Framebuffer 2089 { 2090 typedef VkFramebuffer Type; 2091 2092 struct Parameters 2093 { 2094 Parameters (void) 2095 {} 2096 }; 2097 2098 struct Resources 2099 { 2100 Dependency<ImageView> colorAttachment; 2101 Dependency<ImageView> depthStencilAttachment; 2102 Dependency<RenderPass> renderPass; 2103 2104 Resources (const Environment& env, const Parameters&) 2105 : colorAttachment (env, ImageView::Parameters(Image::Parameters(0u, VK_IMAGE_TYPE_2D, VK_FORMAT_R8G8B8A8_UNORM, 2106 makeExtent3D(256, 256, 1), 2107 1u, 1u, 2108 VK_SAMPLE_COUNT_1_BIT, 2109 VK_IMAGE_TILING_OPTIMAL, 2110 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 2111 VK_IMAGE_LAYOUT_UNDEFINED), 2112 VK_IMAGE_VIEW_TYPE_2D, VK_FORMAT_R8G8B8A8_UNORM, 2113 makeComponentMappingRGBA(), 2114 makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u))) 2115 , depthStencilAttachment (env, ImageView::Parameters(Image::Parameters(0u, VK_IMAGE_TYPE_2D, VK_FORMAT_D16_UNORM, 2116 makeExtent3D(256, 256, 1), 2117 1u, 1u, 2118 VK_SAMPLE_COUNT_1_BIT, 2119 VK_IMAGE_TILING_OPTIMAL, 2120 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, 2121 VK_IMAGE_LAYOUT_UNDEFINED), 2122 VK_IMAGE_VIEW_TYPE_2D, VK_FORMAT_D16_UNORM, 2123 makeComponentMappingRGBA(), 2124 makeImageSubresourceRange(VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 1u, 0u, 1u))) 2125 , renderPass (env, RenderPass::Parameters()) 2126 {} 2127 }; 2128 2129 static deUint32 getMaxConcurrent (Context& context, const Parameters& params) 2130 { 2131 // \todo [2016-03-23 pyry] Take into account attachment sizes 2132 return getSafeObjectCount<Framebuffer>(context, params, DEFAULT_MAX_CONCURRENT_OBJECTS); 2133 } 2134 2135 static Move<VkFramebuffer> create (const Environment& env, const Resources& res, const Parameters&) 2136 { 2137 const VkImageView attachments[] = 2138 { 2139 *res.colorAttachment.object, 2140 *res.depthStencilAttachment.object, 2141 }; 2142 const VkFramebufferCreateInfo framebufferInfo = 2143 { 2144 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, 2145 DE_NULL, 2146 (VkFramebufferCreateFlags)0, 2147 *res.renderPass.object, 2148 (deUint32)DE_LENGTH_OF_ARRAY(attachments), 2149 attachments, 2150 256u, // width 2151 256u, // height 2152 1u // layers 2153 }; 2154 2155 return createFramebuffer(env.vkd, env.device, &framebufferInfo, env.allocationCallbacks); 2156 } 2157 }; 2158 2159 struct CommandPool 2160 { 2161 typedef VkCommandPool Type; 2162 2163 struct Parameters 2164 { 2165 VkCommandPoolCreateFlags flags; 2166 2167 Parameters (VkCommandPoolCreateFlags flags_) 2168 : flags(flags_) 2169 {} 2170 }; 2171 2172 struct Resources 2173 { 2174 Resources (const Environment&, const Parameters&) {} 2175 }; 2176 2177 static deUint32 getMaxConcurrent (Context& context, const Parameters& params) 2178 { 2179 return getSafeObjectCount<CommandPool>(context, params, DEFAULT_MAX_CONCURRENT_OBJECTS); 2180 } 2181 2182 static Move<VkCommandPool> create (const Environment& env, const Resources&, const Parameters& params) 2183 { 2184 const VkCommandPoolCreateInfo cmdPoolInfo = 2185 { 2186 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, 2187 DE_NULL, 2188 params.flags, 2189 env.queueFamilyIndex, 2190 }; 2191 2192 return createCommandPool(env.vkd, env.device, &cmdPoolInfo, env.allocationCallbacks); 2193 } 2194 }; 2195 2196 struct CommandBuffer 2197 { 2198 typedef VkCommandBuffer Type; 2199 2200 struct Parameters 2201 { 2202 CommandPool::Parameters commandPool; 2203 VkCommandBufferLevel level; 2204 2205 Parameters (const CommandPool::Parameters& commandPool_, 2206 VkCommandBufferLevel level_) 2207 : commandPool (commandPool_) 2208 , level (level_) 2209 {} 2210 }; 2211 2212 struct Resources 2213 { 2214 Dependency<CommandPool> commandPool; 2215 2216 Resources (const Environment& env, const Parameters& params) 2217 : commandPool(env, params.commandPool) 2218 {} 2219 }; 2220 2221 static deUint32 getMaxConcurrent (Context& context, const Parameters& params) 2222 { 2223 return getSafeObjectCount<CommandBuffer>(context, params, DEFAULT_MAX_CONCURRENT_OBJECTS); 2224 } 2225 2226 static Move<VkCommandBuffer> create (const Environment& env, const Resources& res, const Parameters& params) 2227 { 2228 const VkCommandBufferAllocateInfo cmdBufferInfo = 2229 { 2230 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, 2231 DE_NULL, 2232 *res.commandPool.object, 2233 params.level, 2234 1, // bufferCount 2235 }; 2236 2237 return allocateCommandBuffer(env.vkd, env.device, &cmdBufferInfo); 2238 } 2239 2240 static vector<VkCommandBufferSp> createMultiple (const Environment& env, const Resources& res, const Parameters& params, vector<VkCommandBuffer>* const pOutHandles, VkResult* const pOutResult) 2241 { 2242 DE_ASSERT(pOutResult); 2243 DE_ASSERT(pOutHandles); 2244 DE_ASSERT(pOutHandles->size() != 0); 2245 2246 const deUint32 numCommandBuffers = static_cast<deUint32>(pOutHandles->size()); 2247 VkCommandBuffer* const pHandles = &(*pOutHandles)[0]; 2248 2249 const VkCommandBufferAllocateInfo cmdBufferInfo = 2250 { 2251 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, 2252 DE_NULL, 2253 *res.commandPool.object, 2254 params.level, 2255 numCommandBuffers, 2256 }; 2257 2258 *pOutResult = env.vkd.allocateCommandBuffers(env.device, &cmdBufferInfo, pHandles); 2259 2260 vector<VkCommandBufferSp> commandBuffers; 2261 2262 if (*pOutResult == VK_SUCCESS) 2263 { 2264 for (deUint32 i = 0; i < numCommandBuffers; ++i) 2265 commandBuffers.push_back(VkCommandBufferSp(new Move<VkCommandBuffer>(check<VkCommandBuffer>(pHandles[i]), Deleter<VkCommandBuffer>(env.vkd, env.device, *res.commandPool.object)))); 2266 } 2267 2268 return commandBuffers; 2269 } 2270 }; 2271 2272 // Test cases 2273 2274 template<typename Object> 2275 tcu::TestStatus createSingleTest (Context& context, typename Object::Parameters params) 2276 { 2277 const Environment env (context, 1u); 2278 const typename Object::Resources res (env, params); 2279 2280 { 2281 Unique<typename Object::Type> obj (Object::create(env, res, params)); 2282 } 2283 2284 return tcu::TestStatus::pass("Ok"); 2285 } 2286 2287 template<typename Object> 2288 tcu::TestStatus createMultipleUniqueResourcesTest (Context& context, typename Object::Parameters params) 2289 { 2290 const Environment env (context, 1u); 2291 const typename Object::Resources res0 (env, params); 2292 const typename Object::Resources res1 (env, params); 2293 const typename Object::Resources res2 (env, params); 2294 const typename Object::Resources res3 (env, params); 2295 2296 { 2297 Unique<typename Object::Type> obj0 (Object::create(env, res0, params)); 2298 Unique<typename Object::Type> obj1 (Object::create(env, res1, params)); 2299 Unique<typename Object::Type> obj2 (Object::create(env, res2, params)); 2300 Unique<typename Object::Type> obj3 (Object::create(env, res3, params)); 2301 } 2302 2303 return tcu::TestStatus::pass("Ok"); 2304 } 2305 2306 template<typename Object> 2307 tcu::TestStatus createMultipleSharedResourcesTest (Context& context, typename Object::Parameters params) 2308 { 2309 const Environment env (context, 4u); 2310 const typename Object::Resources res (env, params); 2311 2312 { 2313 Unique<typename Object::Type> obj0 (Object::create(env, res, params)); 2314 Unique<typename Object::Type> obj1 (Object::create(env, res, params)); 2315 Unique<typename Object::Type> obj2 (Object::create(env, res, params)); 2316 Unique<typename Object::Type> obj3 (Object::create(env, res, params)); 2317 } 2318 2319 return tcu::TestStatus::pass("Ok"); 2320 } 2321 2322 template<typename Object> 2323 tcu::TestStatus createMaxConcurrentTest (Context& context, typename Object::Parameters params) 2324 { 2325 typedef Unique<typename Object::Type> UniqueObject; 2326 typedef SharedPtr<UniqueObject> ObjectPtr; 2327 2328 const deUint32 numObjects = Object::getMaxConcurrent(context, params); 2329 const Environment env (context, numObjects); 2330 const typename Object::Resources res (env, params); 2331 vector<ObjectPtr> objects (numObjects); 2332 const deUint32 watchdogInterval = 1024; 2333 2334 context.getTestContext().getLog() 2335 << TestLog::Message << "Creating " << numObjects << " " << getTypeName<typename Object::Type>() << " objects" << TestLog::EndMessage; 2336 2337 for (deUint32 ndx = 0; ndx < numObjects; ndx++) 2338 { 2339 objects[ndx] = ObjectPtr(new UniqueObject(Object::create(env, res, params))); 2340 2341 if ((ndx > 0) && ((ndx % watchdogInterval) == 0)) 2342 context.getTestContext().touchWatchdog(); 2343 } 2344 2345 context.getTestContext().touchWatchdog(); 2346 objects.clear(); 2347 2348 return tcu::TestStatus::pass("Ok"); 2349 } 2350 2351 // How many objects to create per thread 2352 template<typename Object> int getCreateCount (void) { return 100; } 2353 2354 // Creating VkDevice and VkInstance can take significantly longer than other object types 2355 template<> int getCreateCount<Instance> (void) { return 20; } 2356 template<> int getCreateCount<Device> (void) { return 20; } 2357 template<> int getCreateCount<DeviceGroup> (void) { return 20; } 2358 2359 template<typename Object> 2360 class CreateThread : public ThreadGroupThread 2361 { 2362 public: 2363 CreateThread (const Environment& env, const typename Object::Resources& resources, const typename Object::Parameters& params) 2364 : m_env (env) 2365 , m_resources (resources) 2366 , m_params (params) 2367 {} 2368 2369 void runThread (void) 2370 { 2371 const int numIters = getCreateCount<Object>(); 2372 const int itersBetweenSyncs = numIters / 5; 2373 2374 DE_ASSERT(itersBetweenSyncs > 0); 2375 2376 for (int iterNdx = 0; iterNdx < numIters; iterNdx++) 2377 { 2378 // Sync every Nth iteration to make entering driver at the same time more likely 2379 if ((iterNdx % itersBetweenSyncs) == 0) 2380 barrier(); 2381 2382 { 2383 Unique<typename Object::Type> obj (Object::create(m_env, m_resources, m_params)); 2384 } 2385 } 2386 } 2387 2388 private: 2389 const Environment& m_env; 2390 const typename Object::Resources& m_resources; 2391 const typename Object::Parameters& m_params; 2392 }; 2393 2394 template<typename Object> 2395 tcu::TestStatus multithreadedCreateSharedResourcesTest (Context& context, typename Object::Parameters params) 2396 { 2397 TestLog& log = context.getTestContext().getLog(); 2398 const deUint32 numThreads = getDefaultTestThreadCount(); 2399 const Environment env (context, numThreads); 2400 const typename Object::Resources res (env, params); 2401 ThreadGroup threads; 2402 2403 log << TestLog::Message << "numThreads = " << numThreads << TestLog::EndMessage; 2404 2405 for (deUint32 ndx = 0; ndx < numThreads; ndx++) 2406 threads.add(MovePtr<ThreadGroupThread>(new CreateThread<Object>(env, res, params))); 2407 2408 return threads.run(); 2409 } 2410 2411 template<typename Object> 2412 tcu::TestStatus multithreadedCreatePerThreadResourcesTest (Context& context, typename Object::Parameters params) 2413 { 2414 typedef SharedPtr<typename Object::Resources> ResPtr; 2415 2416 TestLog& log = context.getTestContext().getLog(); 2417 const deUint32 numThreads = getDefaultTestThreadCount(); 2418 const Environment env (context, 1u); 2419 vector<ResPtr> resources (numThreads); 2420 ThreadGroup threads; 2421 2422 log << TestLog::Message << "numThreads = " << numThreads << TestLog::EndMessage; 2423 2424 for (deUint32 ndx = 0; ndx < numThreads; ndx++) 2425 { 2426 resources[ndx] = ResPtr(new typename Object::Resources(env, params)); 2427 threads.add(MovePtr<ThreadGroupThread>(new CreateThread<Object>(env, *resources[ndx], params))); 2428 } 2429 2430 return threads.run(); 2431 } 2432 2433 struct EnvClone 2434 { 2435 Device::Resources deviceRes; 2436 Unique<VkDevice> device; 2437 DeviceDriver vkd; 2438 Environment env; 2439 2440 EnvClone (const Environment& parent, const Device::Parameters& deviceParams, deUint32 maxResourceConsumers) 2441 : deviceRes (parent, deviceParams) 2442 , device (Device::create(parent, deviceRes, deviceParams)) 2443 , vkd (parent.vkp, parent.instance, *device) 2444 , env (parent.vkp, parent.apiVersion, parent.instance, vkd, *device, deviceRes.queueFamilyIndex, parent.programBinaries, parent.allocationCallbacks, maxResourceConsumers) 2445 { 2446 } 2447 }; 2448 2449 Device::Parameters getDefaulDeviceParameters (Context& context) 2450 { 2451 return Device::Parameters(context.getTestContext().getCommandLine().getVKDeviceId()-1u, 2452 VK_QUEUE_GRAPHICS_BIT|VK_QUEUE_COMPUTE_BIT); 2453 } 2454 2455 template<typename Object> 2456 tcu::TestStatus multithreadedCreatePerThreadDeviceTest (Context& context, typename Object::Parameters params) 2457 { 2458 typedef SharedPtr<EnvClone> EnvPtr; 2459 typedef SharedPtr<typename Object::Resources> ResPtr; 2460 2461 TestLog& log = context.getTestContext().getLog(); 2462 const deUint32 numThreads = getDefaultTestThreadCount(); 2463 const Device::Parameters deviceParams = getDefaulDeviceParameters(context); 2464 const Environment sharedEnv (context, numThreads); // For creating Device's 2465 vector<EnvPtr> perThreadEnv (numThreads); 2466 vector<ResPtr> resources (numThreads); 2467 ThreadGroup threads; 2468 2469 log << TestLog::Message << "numThreads = " << numThreads << TestLog::EndMessage; 2470 2471 for (deUint32 ndx = 0; ndx < numThreads; ndx++) 2472 { 2473 perThreadEnv[ndx] = EnvPtr(new EnvClone(sharedEnv, deviceParams, 1u)); 2474 resources[ndx] = ResPtr(new typename Object::Resources(perThreadEnv[ndx]->env, params)); 2475 2476 threads.add(MovePtr<ThreadGroupThread>(new CreateThread<Object>(perThreadEnv[ndx]->env, *resources[ndx], params))); 2477 } 2478 2479 return threads.run(); 2480 } 2481 2482 template<typename Object> 2483 tcu::TestStatus createSingleAllocCallbacksTest (Context& context, typename Object::Parameters params) 2484 { 2485 const deUint32 noCmdScope = (1u << VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE) 2486 | (1u << VK_SYSTEM_ALLOCATION_SCOPE_DEVICE) 2487 | (1u << VK_SYSTEM_ALLOCATION_SCOPE_CACHE) 2488 | (1u << VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 2489 2490 // Callbacks used by resources 2491 AllocationCallbackRecorder resCallbacks (getSystemAllocator(), 128); 2492 2493 // Root environment still uses default instance and device, created without callbacks 2494 const Environment rootEnv (context.getPlatformInterface(), 2495 context.getUsedApiVersion(), 2496 context.getInstance(), 2497 context.getDeviceInterface(), 2498 context.getDevice(), 2499 context.getUniversalQueueFamilyIndex(), 2500 context.getBinaryCollection(), 2501 resCallbacks.getCallbacks(), 2502 1u); 2503 2504 { 2505 // Test env has instance & device created with callbacks 2506 const EnvClone resEnv (rootEnv, getDefaulDeviceParameters(context), 1u); 2507 const typename Object::Resources res (resEnv.env, params); 2508 2509 // Supply a separate callback recorder just for object construction 2510 AllocationCallbackRecorder objCallbacks(getSystemAllocator(), 128); 2511 const Environment objEnv (resEnv.env.vkp, 2512 resEnv.env.apiVersion, 2513 resEnv.env.instance, 2514 resEnv.env.vkd, 2515 resEnv.env.device, 2516 resEnv.env.queueFamilyIndex, 2517 resEnv.env.programBinaries, 2518 objCallbacks.getCallbacks(), 2519 resEnv.env.maxResourceConsumers); 2520 2521 { 2522 Unique<typename Object::Type> obj (Object::create(objEnv, res, params)); 2523 2524 // Validate that no command-level allocations are live 2525 if (!validateAndLog(context.getTestContext().getLog(), objCallbacks, noCmdScope)) 2526 return tcu::TestStatus::fail("Invalid allocation callback"); 2527 } 2528 2529 // At this point all allocations made against object callbacks must have been freed 2530 if (!validateAndLog(context.getTestContext().getLog(), objCallbacks, 0u)) 2531 return tcu::TestStatus::fail("Invalid allocation callback"); 2532 } 2533 2534 if (!validateAndLog(context.getTestContext().getLog(), resCallbacks, 0u)) 2535 return tcu::TestStatus::fail("Invalid allocation callback"); 2536 2537 return tcu::TestStatus::pass("Ok"); 2538 } 2539 2540 template<typename Object> deUint32 getOomIterLimit (void) { return 1024; } 2541 template<> deUint32 getOomIterLimit<Device> (void) { return 20; } 2542 template<> deUint32 getOomIterLimit<DeviceGroup> (void) { return 20; } 2543 2544 template<typename Object> 2545 tcu::TestStatus allocCallbackFailTest (Context& context, typename Object::Parameters params) 2546 { 2547 AllocationCallbackRecorder resCallbacks (getSystemAllocator(), 128); 2548 const Environment rootEnv (context.getPlatformInterface(), 2549 context.getUsedApiVersion(), 2550 context.getInstance(), 2551 context.getDeviceInterface(), 2552 context.getDevice(), 2553 context.getUniversalQueueFamilyIndex(), 2554 context.getBinaryCollection(), 2555 resCallbacks.getCallbacks(), 2556 1u); 2557 deUint32 numPassingAllocs = 0; 2558 const deUint32 cmdLineIterCount = (deUint32)context.getTestContext().getCommandLine().getTestIterationCount(); 2559 const deUint32 maxTries = cmdLineIterCount != 0 ? cmdLineIterCount : getOomIterLimit<Object>(); 2560 2561 { 2562 const EnvClone resEnv (rootEnv, getDefaulDeviceParameters(context), 1u); 2563 const typename Object::Resources res (resEnv.env, params); 2564 2565 // Iterate over test until object allocation succeeds 2566 for (; numPassingAllocs < maxTries; ++numPassingAllocs) 2567 { 2568 DeterministicFailAllocator objAllocator(getSystemAllocator(), 2569 DeterministicFailAllocator::MODE_COUNT_AND_FAIL, 2570 numPassingAllocs); 2571 AllocationCallbackRecorder recorder (objAllocator.getCallbacks(), 128); 2572 const Environment objEnv (resEnv.env.vkp, 2573 resEnv.env.apiVersion, 2574 resEnv.env.instance, 2575 resEnv.env.vkd, 2576 resEnv.env.device, 2577 resEnv.env.queueFamilyIndex, 2578 resEnv.env.programBinaries, 2579 recorder.getCallbacks(), 2580 resEnv.env.maxResourceConsumers); 2581 bool createOk = false; 2582 2583 context.getTestContext().getLog() 2584 << TestLog::Message 2585 << "Trying to create object with " << numPassingAllocs << " allocation" << (numPassingAllocs != 1 ? "s" : "") << " passing" 2586 << TestLog::EndMessage; 2587 2588 try 2589 { 2590 Unique<typename Object::Type> obj (Object::create(objEnv, res, params)); 2591 createOk = true; 2592 } 2593 catch (const vk::OutOfMemoryError& e) 2594 { 2595 if (e.getError() != VK_ERROR_OUT_OF_HOST_MEMORY) 2596 { 2597 context.getTestContext().getLog() << e; 2598 return tcu::TestStatus::fail("Got invalid error code"); 2599 } 2600 } 2601 2602 if (!validateAndLog(context.getTestContext().getLog(), recorder, 0u)) 2603 return tcu::TestStatus::fail("Invalid allocation callback"); 2604 2605 if (createOk) 2606 { 2607 context.getTestContext().getLog() 2608 << TestLog::Message << "Object construction succeeded! " << TestLog::EndMessage; 2609 break; 2610 } 2611 } 2612 } 2613 2614 if (!validateAndLog(context.getTestContext().getLog(), resCallbacks, 0u)) 2615 return tcu::TestStatus::fail("Invalid allocation callback"); 2616 2617 if (numPassingAllocs == 0) 2618 return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Allocation callbacks not called"); 2619 else if (numPassingAllocs == maxTries) 2620 { 2621 context.getTestContext().getLog() 2622 << TestLog::Message << "WARNING: Maximum iteration count (" << maxTries << ") reached without object construction passing. " 2623 << "OOM testing incomplete, use --deqp-test-iteration-count= to test with higher limit." << TestLog::EndMessage; 2624 return tcu::TestStatus(QP_TEST_RESULT_PASS, "Max iter count reached"); 2625 } 2626 else 2627 return tcu::TestStatus::pass("Ok"); 2628 } 2629 2630 // Determine whether an API call sets the invalid handles to NULL (true) or leaves them undefined or not modified (false) 2631 template<typename T> inline bool isNullHandleOnAllocationFailure (Context&) { return false; } 2632 template<> inline bool isNullHandleOnAllocationFailure<VkCommandBuffer> (Context& context) { return hasDeviceExtension(context, "VK_KHR_maintenance1"); } 2633 template<> inline bool isNullHandleOnAllocationFailure<VkDescriptorSet> (Context& context) { return hasDeviceExtension(context, "VK_KHR_maintenance1"); } 2634 template<> inline bool isNullHandleOnAllocationFailure<VkPipeline> (Context&) { return true; } 2635 2636 template<typename T> inline bool isPooledObject (void) { return false; }; 2637 template<> inline bool isPooledObject<VkCommandBuffer> (void) { return true; }; 2638 template<> inline bool isPooledObject<VkDescriptorSet> (void) { return true; }; 2639 2640 template<typename Object> 2641 tcu::TestStatus allocCallbackFailMultipleObjectsTest (Context& context, typename Object::Parameters params) 2642 { 2643 typedef SharedPtr<Move<typename Object::Type> > ObjectTypeSp; 2644 2645 static const deUint32 numObjects = 4; 2646 const bool expectNullHandles = isNullHandleOnAllocationFailure<typename Object::Type>(context); 2647 deUint32 numPassingAllocs = 0; 2648 2649 { 2650 vector<typename Object::Type> handles (numObjects); 2651 VkResult result = VK_NOT_READY; 2652 2653 for (; numPassingAllocs <= numObjects; ++numPassingAllocs) 2654 { 2655 ValidateQueryBits::fillBits(handles.begin(), handles.end()); // fill with garbage 2656 2657 // \note We have to use the same allocator for both resource dependencies and the object under test, 2658 // because pooled objects take memory from the pool. 2659 DeterministicFailAllocator objAllocator(getSystemAllocator(), DeterministicFailAllocator::MODE_DO_NOT_COUNT, 0); 2660 AllocationCallbackRecorder recorder (objAllocator.getCallbacks(), 128); 2661 const Environment objEnv (context.getPlatformInterface(), 2662 context.getUsedApiVersion(), 2663 context.getInstance(), 2664 context.getDeviceInterface(), 2665 context.getDevice(), 2666 context.getUniversalQueueFamilyIndex(), 2667 context.getBinaryCollection(), 2668 recorder.getCallbacks(), 2669 numObjects); 2670 2671 context.getTestContext().getLog() 2672 << TestLog::Message 2673 << "Trying to create " << numObjects << " objects with " << numPassingAllocs << " allocation" << (numPassingAllocs != 1 ? "s" : "") << " passing" 2674 << TestLog::EndMessage; 2675 2676 { 2677 const typename Object::Resources res (objEnv, params); 2678 2679 objAllocator.reset(DeterministicFailAllocator::MODE_COUNT_AND_FAIL, numPassingAllocs); 2680 const vector<ObjectTypeSp> scopedHandles = Object::createMultiple(objEnv, res, params, &handles, &result); 2681 } 2682 2683 if (result == VK_SUCCESS) 2684 { 2685 context.getTestContext().getLog() << TestLog::Message << "Construction of all objects succeeded! " << TestLog::EndMessage; 2686 break; 2687 } 2688 else 2689 { 2690 if (expectNullHandles) 2691 { 2692 for (deUint32 nullNdx = numPassingAllocs; nullNdx < numObjects; ++nullNdx) 2693 { 2694 if (handles[nullNdx] != DE_NULL) 2695 return tcu::TestStatus::fail("Some object handles weren't set to NULL"); 2696 } 2697 } 2698 2699 if (result != VK_ERROR_OUT_OF_HOST_MEMORY) 2700 return tcu::TestStatus::fail("Got invalid error code: " + de::toString(getResultName(result))); 2701 2702 if (!validateAndLog(context.getTestContext().getLog(), recorder, 0u)) 2703 return tcu::TestStatus::fail("Invalid allocation callback"); 2704 } 2705 } 2706 } 2707 2708 if (numPassingAllocs == 0) 2709 { 2710 if (isPooledObject<typename Object::Type>()) 2711 return tcu::TestStatus::pass("Not validated: pooled objects didn't seem to use host memory"); 2712 else 2713 return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Allocation callbacks not called"); 2714 } 2715 else 2716 return tcu::TestStatus::pass("Ok"); 2717 } 2718 2719 // Utilities for creating groups 2720 2721 template<typename Object> 2722 struct NamedParameters 2723 { 2724 const char* name; 2725 typename Object::Parameters parameters; 2726 }; 2727 2728 template<typename Object> 2729 struct CaseDescription 2730 { 2731 typename FunctionInstance1<typename Object::Parameters>::Function function; 2732 const NamedParameters<Object>* paramsBegin; 2733 const NamedParameters<Object>* paramsEnd; 2734 }; 2735 2736 #define EMPTY_CASE_DESC(OBJECT) \ 2737 { (FunctionInstance1<OBJECT::Parameters>::Function)DE_NULL, DE_NULL, DE_NULL } 2738 2739 #define CASE_DESC(FUNCTION, CASES) \ 2740 { FUNCTION, DE_ARRAY_BEGIN(CASES), DE_ARRAY_END(CASES) } 2741 2742 struct CaseDescriptions 2743 { 2744 CaseDescription<Instance> instance; 2745 CaseDescription<Device> device; 2746 CaseDescription<DeviceGroup> deviceGroup; 2747 CaseDescription<DeviceMemory> deviceMemory; 2748 CaseDescription<Buffer> buffer; 2749 CaseDescription<BufferView> bufferView; 2750 CaseDescription<Image> image; 2751 CaseDescription<ImageView> imageView; 2752 CaseDescription<Semaphore> semaphore; 2753 CaseDescription<Event> event; 2754 CaseDescription<Fence> fence; 2755 CaseDescription<QueryPool> queryPool; 2756 CaseDescription<ShaderModule> shaderModule; 2757 CaseDescription<PipelineCache> pipelineCache; 2758 CaseDescription<PipelineLayout> pipelineLayout; 2759 CaseDescription<RenderPass> renderPass; 2760 CaseDescription<GraphicsPipeline> graphicsPipeline; 2761 CaseDescription<ComputePipeline> computePipeline; 2762 CaseDescription<DescriptorSetLayout> descriptorSetLayout; 2763 CaseDescription<Sampler> sampler; 2764 CaseDescription<DescriptorPool> descriptorPool; 2765 CaseDescription<DescriptorSet> descriptorSet; 2766 CaseDescription<Framebuffer> framebuffer; 2767 CaseDescription<CommandPool> commandPool; 2768 CaseDescription<CommandBuffer> commandBuffer; 2769 }; 2770 2771 template<typename Object> 2772 void addCases (const MovePtr<tcu::TestCaseGroup>& group, const CaseDescription<Object>& cases) 2773 { 2774 for (const NamedParameters<Object>* cur = cases.paramsBegin; cur != cases.paramsEnd; ++cur) 2775 addFunctionCase(group.get(), cur->name, "", cases.function, cur->parameters); 2776 } 2777 2778 template<typename Object> 2779 void addCasesWithProgs (const MovePtr<tcu::TestCaseGroup>& group, const CaseDescription<Object>& cases) 2780 { 2781 for (const NamedParameters<Object>* cur = cases.paramsBegin; cur != cases.paramsEnd; ++cur) 2782 addFunctionCaseWithPrograms(group.get(), cur->name, "", Object::initPrograms, cases.function, cur->parameters); 2783 } 2784 2785 tcu::TestCaseGroup* createGroup (tcu::TestContext& testCtx, const char* name, const char* desc, const CaseDescriptions& cases) 2786 { 2787 MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, name, desc)); 2788 2789 addCases (group, cases.instance); 2790 addCases (group, cases.device); 2791 addCases (group, cases.deviceGroup); 2792 addCases (group, cases.deviceMemory); 2793 addCases (group, cases.buffer); 2794 addCases (group, cases.bufferView); 2795 addCases (group, cases.image); 2796 addCases (group, cases.imageView); 2797 addCases (group, cases.semaphore); 2798 addCases (group, cases.event); 2799 addCases (group, cases.fence); 2800 addCases (group, cases.queryPool); 2801 addCases (group, cases.sampler); 2802 addCasesWithProgs (group, cases.shaderModule); 2803 addCases (group, cases.pipelineCache); 2804 addCases (group, cases.pipelineLayout); 2805 addCases (group, cases.renderPass); 2806 addCasesWithProgs (group, cases.graphicsPipeline); 2807 addCasesWithProgs (group, cases.computePipeline); 2808 addCases (group, cases.descriptorSetLayout); 2809 addCases (group, cases.descriptorPool); 2810 addCases (group, cases.descriptorSet); 2811 addCases (group, cases.framebuffer); 2812 addCases (group, cases.commandPool); 2813 addCases (group, cases.commandBuffer); 2814 2815 return group.release(); 2816 } 2817 2818 } // anonymous 2819 2820 tcu::TestCaseGroup* createObjectManagementTests (tcu::TestContext& testCtx) 2821 { 2822 MovePtr<tcu::TestCaseGroup> objectMgmtTests (new tcu::TestCaseGroup(testCtx, "object_management", "Object management tests")); 2823 2824 const Image::Parameters img1D (0u, VK_IMAGE_TYPE_1D, VK_FORMAT_R8G8B8A8_UNORM, makeExtent3D(256, 1, 1), 1u, 4u, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_UNDEFINED); 2825 const Image::Parameters img2D (0u, VK_IMAGE_TYPE_2D, VK_FORMAT_R8G8B8A8_UNORM, makeExtent3D( 64, 64, 1), 1u, 12u, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_LAYOUT_UNDEFINED); 2826 const Image::Parameters imgCube (VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, VK_IMAGE_TYPE_2D, VK_FORMAT_R8G8B8A8_UNORM, makeExtent3D( 64, 64, 1), 1u, 12u, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_LAYOUT_UNDEFINED); 2827 const Image::Parameters img3D (0u, VK_IMAGE_TYPE_3D, VK_FORMAT_R8G8B8A8_UNORM, makeExtent3D( 64, 64, 4), 1u, 1u, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_UNDEFINED); 2828 const ImageView::Parameters imgView1D (img1D, VK_IMAGE_VIEW_TYPE_1D, img1D.format, makeComponentMappingRGBA(), makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u)); 2829 const ImageView::Parameters imgView1DArr (img1D, VK_IMAGE_VIEW_TYPE_1D_ARRAY, img1D.format, makeComponentMappingRGBA(), makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 4u)); 2830 const ImageView::Parameters imgView2D (img2D, VK_IMAGE_VIEW_TYPE_2D, img2D.format, makeComponentMappingRGBA(), makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u)); 2831 const ImageView::Parameters imgView2DArr (img2D, VK_IMAGE_VIEW_TYPE_2D_ARRAY, img2D.format, makeComponentMappingRGBA(), makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 8u)); 2832 const ImageView::Parameters imgViewCube (imgCube, VK_IMAGE_VIEW_TYPE_CUBE, img2D.format, makeComponentMappingRGBA(), makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 6u)); 2833 const ImageView::Parameters imgViewCubeArr (imgCube, VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, img2D.format, makeComponentMappingRGBA(), makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 12u)); 2834 const ImageView::Parameters imgView3D (img3D, VK_IMAGE_VIEW_TYPE_3D, img3D.format, makeComponentMappingRGBA(), makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u)); 2835 2836 const DescriptorSetLayout::Parameters singleUboDescLayout = DescriptorSetLayout::Parameters::single(0u, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1u, VK_SHADER_STAGE_VERTEX_BIT); 2837 2838 static const NamedParameters<Instance> s_instanceCases[] = 2839 { 2840 { "instance", Instance::Parameters() }, 2841 }; 2842 // \note Device index may change - must not be static 2843 2844 const NamedParameters<Device> s_deviceCases[] = 2845 { 2846 { "device", Device::Parameters(testCtx.getCommandLine().getVKDeviceId()-1u, VK_QUEUE_GRAPHICS_BIT) }, 2847 }; 2848 const NamedParameters<DeviceGroup> s_deviceGroupCases[] = 2849 { 2850 { "device_group", DeviceGroup::Parameters(testCtx.getCommandLine().getVKDeviceGroupId() - 1u, testCtx.getCommandLine().getVKDeviceId() - 1u, VK_QUEUE_GRAPHICS_BIT) }, 2851 }; 2852 static const NamedParameters<DeviceMemory> s_deviceMemCases[] = 2853 { 2854 { "device_memory_small", DeviceMemory::Parameters(1024, 0u) }, 2855 }; 2856 static const NamedParameters<Buffer> s_bufferCases[] = 2857 { 2858 { "buffer_uniform_small", Buffer::Parameters(1024u, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT), }, 2859 { "buffer_uniform_large", Buffer::Parameters(1024u*1024u*16u, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT), }, 2860 { "buffer_storage_small", Buffer::Parameters(1024u, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), }, 2861 { "buffer_storage_large", Buffer::Parameters(1024u*1024u*16u, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), }, 2862 }; 2863 static const NamedParameters<BufferView> s_bufferViewCases[] = 2864 { 2865 { "buffer_view_uniform_r8g8b8a8_unorm", BufferView::Parameters(Buffer::Parameters(8192u, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT), VK_FORMAT_R8G8B8A8_UNORM, 0u, 4096u) }, 2866 { "buffer_view_storage_r8g8b8a8_unorm", BufferView::Parameters(Buffer::Parameters(8192u, VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT), VK_FORMAT_R8G8B8A8_UNORM, 0u, 4096u) }, 2867 }; 2868 static const NamedParameters<Image> s_imageCases[] = 2869 { 2870 { "image_1d", img1D }, 2871 { "image_2d", img2D }, 2872 { "image_3d", img3D }, 2873 }; 2874 static const NamedParameters<ImageView> s_imageViewCases[] = 2875 { 2876 { "image_view_1d", imgView1D }, 2877 { "image_view_1d_arr", imgView1DArr }, 2878 { "image_view_2d", imgView2D }, 2879 { "image_view_2d_arr", imgView2DArr }, 2880 { "image_view_cube", imgViewCube }, 2881 { "image_view_cube_arr", imgViewCubeArr }, 2882 { "image_view_3d", imgView3D }, 2883 }; 2884 static const NamedParameters<Semaphore> s_semaphoreCases[] = 2885 { 2886 { "semaphore", Semaphore::Parameters(0u), } 2887 }; 2888 static const NamedParameters<Event> s_eventCases[] = 2889 { 2890 { "event", Event::Parameters(0u) } 2891 }; 2892 static const NamedParameters<Fence> s_fenceCases[] = 2893 { 2894 { "fence", Fence::Parameters(0u) }, 2895 { "fence_signaled", Fence::Parameters(VK_FENCE_CREATE_SIGNALED_BIT) } 2896 }; 2897 static const NamedParameters<QueryPool> s_queryPoolCases[] = 2898 { 2899 { "query_pool", QueryPool::Parameters(VK_QUERY_TYPE_OCCLUSION, 1u, 0u) } 2900 }; 2901 static const NamedParameters<ShaderModule> s_shaderModuleCases[] = 2902 { 2903 { "shader_module", ShaderModule::Parameters(VK_SHADER_STAGE_COMPUTE_BIT, "test") } 2904 }; 2905 static const NamedParameters<PipelineCache> s_pipelineCacheCases[] = 2906 { 2907 { "pipeline_cache", PipelineCache::Parameters() } 2908 }; 2909 static const NamedParameters<PipelineLayout> s_pipelineLayoutCases[] = 2910 { 2911 { "pipeline_layout_empty", PipelineLayout::Parameters::empty() }, 2912 { "pipeline_layout_single", PipelineLayout::Parameters::singleDescriptorSet(singleUboDescLayout) } 2913 }; 2914 static const NamedParameters<RenderPass> s_renderPassCases[] = 2915 { 2916 { "render_pass", RenderPass::Parameters() } 2917 }; 2918 static const NamedParameters<GraphicsPipeline> s_graphicsPipelineCases[] = 2919 { 2920 { "graphics_pipeline", GraphicsPipeline::Parameters() } 2921 }; 2922 static const NamedParameters<ComputePipeline> s_computePipelineCases[] = 2923 { 2924 { "compute_pipeline", ComputePipeline::Parameters() } 2925 }; 2926 static const NamedParameters<DescriptorSetLayout> s_descriptorSetLayoutCases[] = 2927 { 2928 { "descriptor_set_layout_empty", DescriptorSetLayout::Parameters::empty() }, 2929 { "descriptor_set_layout_single", singleUboDescLayout } 2930 }; 2931 static const NamedParameters<Sampler> s_samplerCases[] = 2932 { 2933 { "sampler", Sampler::Parameters() } 2934 }; 2935 static const NamedParameters<DescriptorPool> s_descriptorPoolCases[] = 2936 { 2937 { "descriptor_pool", DescriptorPool::Parameters::singleType((VkDescriptorPoolCreateFlags)0, 4u, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 3u) }, 2938 { "descriptor_pool_free_descriptor_set", DescriptorPool::Parameters::singleType(VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 4u, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 3u) } 2939 }; 2940 static const NamedParameters<DescriptorSet> s_descriptorSetCases[] = 2941 { 2942 { "descriptor_set", DescriptorSet::Parameters(singleUboDescLayout) } 2943 }; 2944 static const NamedParameters<Framebuffer> s_framebufferCases[] = 2945 { 2946 { "framebuffer", Framebuffer::Parameters() } 2947 }; 2948 static const NamedParameters<CommandPool> s_commandPoolCases[] = 2949 { 2950 { "command_pool", CommandPool::Parameters((VkCommandPoolCreateFlags)0) }, 2951 { "command_pool_transient", CommandPool::Parameters(VK_COMMAND_POOL_CREATE_TRANSIENT_BIT) } 2952 }; 2953 static const NamedParameters<CommandBuffer> s_commandBufferCases[] = 2954 { 2955 { "command_buffer_primary", CommandBuffer::Parameters(CommandPool::Parameters((VkCommandPoolCreateFlags)0u), VK_COMMAND_BUFFER_LEVEL_PRIMARY) }, 2956 { "command_buffer_secondary", CommandBuffer::Parameters(CommandPool::Parameters((VkCommandPoolCreateFlags)0u), VK_COMMAND_BUFFER_LEVEL_SECONDARY) } 2957 }; 2958 2959 const CaseDescriptions s_createSingleGroup = 2960 { 2961 CASE_DESC(createSingleTest <Instance>, s_instanceCases), 2962 CASE_DESC(createSingleTest <Device>, s_deviceCases), 2963 CASE_DESC(createSingleTest <DeviceGroup>, s_deviceGroupCases), 2964 CASE_DESC(createSingleTest <DeviceMemory>, s_deviceMemCases), 2965 CASE_DESC(createSingleTest <Buffer>, s_bufferCases), 2966 CASE_DESC(createSingleTest <BufferView>, s_bufferViewCases), 2967 CASE_DESC(createSingleTest <Image>, s_imageCases), 2968 CASE_DESC(createSingleTest <ImageView>, s_imageViewCases), 2969 CASE_DESC(createSingleTest <Semaphore>, s_semaphoreCases), 2970 CASE_DESC(createSingleTest <Event>, s_eventCases), 2971 CASE_DESC(createSingleTest <Fence>, s_fenceCases), 2972 CASE_DESC(createSingleTest <QueryPool>, s_queryPoolCases), 2973 CASE_DESC(createSingleTest <ShaderModule>, s_shaderModuleCases), 2974 CASE_DESC(createSingleTest <PipelineCache>, s_pipelineCacheCases), 2975 CASE_DESC(createSingleTest <PipelineLayout>, s_pipelineLayoutCases), 2976 CASE_DESC(createSingleTest <RenderPass>, s_renderPassCases), 2977 CASE_DESC(createSingleTest <GraphicsPipeline>, s_graphicsPipelineCases), 2978 CASE_DESC(createSingleTest <ComputePipeline>, s_computePipelineCases), 2979 CASE_DESC(createSingleTest <DescriptorSetLayout>, s_descriptorSetLayoutCases), 2980 CASE_DESC(createSingleTest <Sampler>, s_samplerCases), 2981 CASE_DESC(createSingleTest <DescriptorPool>, s_descriptorPoolCases), 2982 CASE_DESC(createSingleTest <DescriptorSet>, s_descriptorSetCases), 2983 CASE_DESC(createSingleTest <Framebuffer>, s_framebufferCases), 2984 CASE_DESC(createSingleTest <CommandPool>, s_commandPoolCases), 2985 CASE_DESC(createSingleTest <CommandBuffer>, s_commandBufferCases), 2986 }; 2987 objectMgmtTests->addChild(createGroup(testCtx, "single", "Create single object", s_createSingleGroup)); 2988 2989 const CaseDescriptions s_createMultipleUniqueResourcesGroup = 2990 { 2991 CASE_DESC(createMultipleUniqueResourcesTest <Instance>, s_instanceCases), 2992 CASE_DESC(createMultipleUniqueResourcesTest <Device>, s_deviceCases), 2993 CASE_DESC(createMultipleUniqueResourcesTest <DeviceGroup>, s_deviceGroupCases), 2994 CASE_DESC(createMultipleUniqueResourcesTest <DeviceMemory>, s_deviceMemCases), 2995 CASE_DESC(createMultipleUniqueResourcesTest <Buffer>, s_bufferCases), 2996 CASE_DESC(createMultipleUniqueResourcesTest <BufferView>, s_bufferViewCases), 2997 CASE_DESC(createMultipleUniqueResourcesTest <Image>, s_imageCases), 2998 CASE_DESC(createMultipleUniqueResourcesTest <ImageView>, s_imageViewCases), 2999 CASE_DESC(createMultipleUniqueResourcesTest <Semaphore>, s_semaphoreCases), 3000 CASE_DESC(createMultipleUniqueResourcesTest <Event>, s_eventCases), 3001 CASE_DESC(createMultipleUniqueResourcesTest <Fence>, s_fenceCases), 3002 CASE_DESC(createMultipleUniqueResourcesTest <QueryPool>, s_queryPoolCases), 3003 CASE_DESC(createMultipleUniqueResourcesTest <ShaderModule>, s_shaderModuleCases), 3004 CASE_DESC(createMultipleUniqueResourcesTest <PipelineCache>, s_pipelineCacheCases), 3005 CASE_DESC(createMultipleUniqueResourcesTest <PipelineLayout>, s_pipelineLayoutCases), 3006 CASE_DESC(createMultipleUniqueResourcesTest <RenderPass>, s_renderPassCases), 3007 CASE_DESC(createMultipleUniqueResourcesTest <GraphicsPipeline>, s_graphicsPipelineCases), 3008 CASE_DESC(createMultipleUniqueResourcesTest <ComputePipeline>, s_computePipelineCases), 3009 CASE_DESC(createMultipleUniqueResourcesTest <DescriptorSetLayout>, s_descriptorSetLayoutCases), 3010 CASE_DESC(createMultipleUniqueResourcesTest <Sampler>, s_samplerCases), 3011 CASE_DESC(createMultipleUniqueResourcesTest <DescriptorPool>, s_descriptorPoolCases), 3012 CASE_DESC(createMultipleUniqueResourcesTest <DescriptorSet>, s_descriptorSetCases), 3013 CASE_DESC(createMultipleUniqueResourcesTest <Framebuffer>, s_framebufferCases), 3014 CASE_DESC(createMultipleUniqueResourcesTest <CommandPool>, s_commandPoolCases), 3015 CASE_DESC(createMultipleUniqueResourcesTest <CommandBuffer>, s_commandBufferCases), 3016 }; 3017 objectMgmtTests->addChild(createGroup(testCtx, "multiple_unique_resources", "Multiple objects with per-object unique resources", s_createMultipleUniqueResourcesGroup)); 3018 3019 const CaseDescriptions s_createMultipleSharedResourcesGroup = 3020 { 3021 EMPTY_CASE_DESC(Instance), // No resources used 3022 CASE_DESC(createMultipleSharedResourcesTest <Device>, s_deviceCases), 3023 CASE_DESC(createMultipleSharedResourcesTest <DeviceGroup>, s_deviceGroupCases), 3024 CASE_DESC(createMultipleSharedResourcesTest <DeviceMemory>, s_deviceMemCases), 3025 CASE_DESC(createMultipleSharedResourcesTest <Buffer>, s_bufferCases), 3026 CASE_DESC(createMultipleSharedResourcesTest <BufferView>, s_bufferViewCases), 3027 CASE_DESC(createMultipleSharedResourcesTest <Image>, s_imageCases), 3028 CASE_DESC(createMultipleSharedResourcesTest <ImageView>, s_imageViewCases), 3029 CASE_DESC(createMultipleSharedResourcesTest <Semaphore>, s_semaphoreCases), 3030 CASE_DESC(createMultipleSharedResourcesTest <Event>, s_eventCases), 3031 CASE_DESC(createMultipleSharedResourcesTest <Fence>, s_fenceCases), 3032 CASE_DESC(createMultipleSharedResourcesTest <QueryPool>, s_queryPoolCases), 3033 CASE_DESC(createMultipleSharedResourcesTest <ShaderModule>, s_shaderModuleCases), 3034 CASE_DESC(createMultipleSharedResourcesTest <PipelineCache>, s_pipelineCacheCases), 3035 CASE_DESC(createMultipleSharedResourcesTest <PipelineLayout>, s_pipelineLayoutCases), 3036 CASE_DESC(createMultipleSharedResourcesTest <RenderPass>, s_renderPassCases), 3037 CASE_DESC(createMultipleSharedResourcesTest <GraphicsPipeline>, s_graphicsPipelineCases), 3038 CASE_DESC(createMultipleSharedResourcesTest <ComputePipeline>, s_computePipelineCases), 3039 CASE_DESC(createMultipleSharedResourcesTest <DescriptorSetLayout>, s_descriptorSetLayoutCases), 3040 CASE_DESC(createMultipleSharedResourcesTest <Sampler>, s_samplerCases), 3041 CASE_DESC(createMultipleSharedResourcesTest <DescriptorPool>, s_descriptorPoolCases), 3042 CASE_DESC(createMultipleSharedResourcesTest <DescriptorSet>, s_descriptorSetCases), 3043 CASE_DESC(createMultipleSharedResourcesTest <Framebuffer>, s_framebufferCases), 3044 CASE_DESC(createMultipleSharedResourcesTest <CommandPool>, s_commandPoolCases), 3045 CASE_DESC(createMultipleSharedResourcesTest <CommandBuffer>, s_commandBufferCases), 3046 }; 3047 objectMgmtTests->addChild(createGroup(testCtx, "multiple_shared_resources", "Multiple objects with shared resources", s_createMultipleSharedResourcesGroup)); 3048 3049 const CaseDescriptions s_createMaxConcurrentGroup = 3050 { 3051 CASE_DESC(createMaxConcurrentTest <Instance>, s_instanceCases), 3052 CASE_DESC(createMaxConcurrentTest <Device>, s_deviceCases), 3053 CASE_DESC(createMaxConcurrentTest <DeviceGroup>, s_deviceGroupCases), 3054 CASE_DESC(createMaxConcurrentTest <DeviceMemory>, s_deviceMemCases), 3055 CASE_DESC(createMaxConcurrentTest <Buffer>, s_bufferCases), 3056 CASE_DESC(createMaxConcurrentTest <BufferView>, s_bufferViewCases), 3057 CASE_DESC(createMaxConcurrentTest <Image>, s_imageCases), 3058 CASE_DESC(createMaxConcurrentTest <ImageView>, s_imageViewCases), 3059 CASE_DESC(createMaxConcurrentTest <Semaphore>, s_semaphoreCases), 3060 CASE_DESC(createMaxConcurrentTest <Event>, s_eventCases), 3061 CASE_DESC(createMaxConcurrentTest <Fence>, s_fenceCases), 3062 CASE_DESC(createMaxConcurrentTest <QueryPool>, s_queryPoolCases), 3063 CASE_DESC(createMaxConcurrentTest <ShaderModule>, s_shaderModuleCases), 3064 CASE_DESC(createMaxConcurrentTest <PipelineCache>, s_pipelineCacheCases), 3065 CASE_DESC(createMaxConcurrentTest <PipelineLayout>, s_pipelineLayoutCases), 3066 CASE_DESC(createMaxConcurrentTest <RenderPass>, s_renderPassCases), 3067 CASE_DESC(createMaxConcurrentTest <GraphicsPipeline>, s_graphicsPipelineCases), 3068 CASE_DESC(createMaxConcurrentTest <ComputePipeline>, s_computePipelineCases), 3069 CASE_DESC(createMaxConcurrentTest <DescriptorSetLayout>, s_descriptorSetLayoutCases), 3070 CASE_DESC(createMaxConcurrentTest <Sampler>, s_samplerCases), 3071 CASE_DESC(createMaxConcurrentTest <DescriptorPool>, s_descriptorPoolCases), 3072 CASE_DESC(createMaxConcurrentTest <DescriptorSet>, s_descriptorSetCases), 3073 CASE_DESC(createMaxConcurrentTest <Framebuffer>, s_framebufferCases), 3074 CASE_DESC(createMaxConcurrentTest <CommandPool>, s_commandPoolCases), 3075 CASE_DESC(createMaxConcurrentTest <CommandBuffer>, s_commandBufferCases), 3076 }; 3077 objectMgmtTests->addChild(createGroup(testCtx, "max_concurrent", "Maximum number of concurrently live objects", s_createMaxConcurrentGroup)); 3078 3079 const CaseDescriptions s_multithreadedCreatePerThreadDeviceGroup = 3080 { 3081 EMPTY_CASE_DESC(Instance), // Does not make sense 3082 EMPTY_CASE_DESC(Device), // Does not make sense 3083 EMPTY_CASE_DESC(DeviceGroup), // Does not make sense 3084 CASE_DESC(multithreadedCreatePerThreadDeviceTest <DeviceMemory>, s_deviceMemCases), 3085 CASE_DESC(multithreadedCreatePerThreadDeviceTest <Buffer>, s_bufferCases), 3086 CASE_DESC(multithreadedCreatePerThreadDeviceTest <BufferView>, s_bufferViewCases), 3087 CASE_DESC(multithreadedCreatePerThreadDeviceTest <Image>, s_imageCases), 3088 CASE_DESC(multithreadedCreatePerThreadDeviceTest <ImageView>, s_imageViewCases), 3089 CASE_DESC(multithreadedCreatePerThreadDeviceTest <Semaphore>, s_semaphoreCases), 3090 CASE_DESC(multithreadedCreatePerThreadDeviceTest <Event>, s_eventCases), 3091 CASE_DESC(multithreadedCreatePerThreadDeviceTest <Fence>, s_fenceCases), 3092 CASE_DESC(multithreadedCreatePerThreadDeviceTest <QueryPool>, s_queryPoolCases), 3093 CASE_DESC(multithreadedCreatePerThreadDeviceTest <ShaderModule>, s_shaderModuleCases), 3094 CASE_DESC(multithreadedCreatePerThreadDeviceTest <PipelineCache>, s_pipelineCacheCases), 3095 CASE_DESC(multithreadedCreatePerThreadDeviceTest <PipelineLayout>, s_pipelineLayoutCases), 3096 CASE_DESC(multithreadedCreatePerThreadDeviceTest <RenderPass>, s_renderPassCases), 3097 CASE_DESC(multithreadedCreatePerThreadDeviceTest <GraphicsPipeline>, s_graphicsPipelineCases), 3098 CASE_DESC(multithreadedCreatePerThreadDeviceTest <ComputePipeline>, s_computePipelineCases), 3099 CASE_DESC(multithreadedCreatePerThreadDeviceTest <DescriptorSetLayout>, s_descriptorSetLayoutCases), 3100 CASE_DESC(multithreadedCreatePerThreadDeviceTest <Sampler>, s_samplerCases), 3101 CASE_DESC(multithreadedCreatePerThreadDeviceTest <DescriptorPool>, s_descriptorPoolCases), 3102 CASE_DESC(multithreadedCreatePerThreadDeviceTest <DescriptorSet>, s_descriptorSetCases), 3103 CASE_DESC(multithreadedCreatePerThreadDeviceTest <Framebuffer>, s_framebufferCases), 3104 CASE_DESC(multithreadedCreatePerThreadDeviceTest <CommandPool>, s_commandPoolCases), 3105 CASE_DESC(multithreadedCreatePerThreadDeviceTest <CommandBuffer>, s_commandBufferCases), 3106 }; 3107 objectMgmtTests->addChild(createGroup(testCtx, "multithreaded_per_thread_device", "Multithreaded object construction with per-thread device ", s_multithreadedCreatePerThreadDeviceGroup)); 3108 3109 const CaseDescriptions s_multithreadedCreatePerThreadResourcesGroup = 3110 { 3111 CASE_DESC(multithreadedCreatePerThreadResourcesTest <Instance>, s_instanceCases), 3112 CASE_DESC(multithreadedCreatePerThreadResourcesTest <Device>, s_deviceCases), 3113 CASE_DESC(multithreadedCreatePerThreadResourcesTest <DeviceGroup>, s_deviceGroupCases), 3114 CASE_DESC(multithreadedCreatePerThreadResourcesTest <DeviceMemory>, s_deviceMemCases), 3115 CASE_DESC(multithreadedCreatePerThreadResourcesTest <Buffer>, s_bufferCases), 3116 CASE_DESC(multithreadedCreatePerThreadResourcesTest <BufferView>, s_bufferViewCases), 3117 CASE_DESC(multithreadedCreatePerThreadResourcesTest <Image>, s_imageCases), 3118 CASE_DESC(multithreadedCreatePerThreadResourcesTest <ImageView>, s_imageViewCases), 3119 CASE_DESC(multithreadedCreatePerThreadResourcesTest <Semaphore>, s_semaphoreCases), 3120 CASE_DESC(multithreadedCreatePerThreadResourcesTest <Event>, s_eventCases), 3121 CASE_DESC(multithreadedCreatePerThreadResourcesTest <Fence>, s_fenceCases), 3122 CASE_DESC(multithreadedCreatePerThreadResourcesTest <QueryPool>, s_queryPoolCases), 3123 CASE_DESC(multithreadedCreatePerThreadResourcesTest <ShaderModule>, s_shaderModuleCases), 3124 CASE_DESC(multithreadedCreatePerThreadResourcesTest <PipelineCache>, s_pipelineCacheCases), 3125 CASE_DESC(multithreadedCreatePerThreadResourcesTest <PipelineLayout>, s_pipelineLayoutCases), 3126 CASE_DESC(multithreadedCreatePerThreadResourcesTest <RenderPass>, s_renderPassCases), 3127 CASE_DESC(multithreadedCreatePerThreadResourcesTest <GraphicsPipeline>, s_graphicsPipelineCases), 3128 CASE_DESC(multithreadedCreatePerThreadResourcesTest <ComputePipeline>, s_computePipelineCases), 3129 CASE_DESC(multithreadedCreatePerThreadResourcesTest <DescriptorSetLayout>, s_descriptorSetLayoutCases), 3130 CASE_DESC(multithreadedCreatePerThreadResourcesTest <Sampler>, s_samplerCases), 3131 CASE_DESC(multithreadedCreatePerThreadResourcesTest <DescriptorPool>, s_descriptorPoolCases), 3132 CASE_DESC(multithreadedCreatePerThreadResourcesTest <DescriptorSet>, s_descriptorSetCases), 3133 CASE_DESC(multithreadedCreatePerThreadResourcesTest <Framebuffer>, s_framebufferCases), 3134 CASE_DESC(multithreadedCreatePerThreadResourcesTest <CommandPool>, s_commandPoolCases), 3135 CASE_DESC(multithreadedCreatePerThreadResourcesTest <CommandBuffer>, s_commandBufferCases), 3136 }; 3137 objectMgmtTests->addChild(createGroup(testCtx, "multithreaded_per_thread_resources", "Multithreaded object construction with per-thread resources", s_multithreadedCreatePerThreadResourcesGroup)); 3138 3139 const CaseDescriptions s_multithreadedCreateSharedResourcesGroup = 3140 { 3141 EMPTY_CASE_DESC(Instance), 3142 CASE_DESC(multithreadedCreateSharedResourcesTest <Device>, s_deviceCases), 3143 CASE_DESC(multithreadedCreateSharedResourcesTest <DeviceGroup>, s_deviceGroupCases), 3144 CASE_DESC(multithreadedCreateSharedResourcesTest <DeviceMemory>, s_deviceMemCases), 3145 CASE_DESC(multithreadedCreateSharedResourcesTest <Buffer>, s_bufferCases), 3146 CASE_DESC(multithreadedCreateSharedResourcesTest <BufferView>, s_bufferViewCases), 3147 CASE_DESC(multithreadedCreateSharedResourcesTest <Image>, s_imageCases), 3148 CASE_DESC(multithreadedCreateSharedResourcesTest <ImageView>, s_imageViewCases), 3149 CASE_DESC(multithreadedCreateSharedResourcesTest <Semaphore>, s_semaphoreCases), 3150 CASE_DESC(multithreadedCreateSharedResourcesTest <Event>, s_eventCases), 3151 CASE_DESC(multithreadedCreateSharedResourcesTest <Fence>, s_fenceCases), 3152 CASE_DESC(multithreadedCreateSharedResourcesTest <QueryPool>, s_queryPoolCases), 3153 CASE_DESC(multithreadedCreateSharedResourcesTest <ShaderModule>, s_shaderModuleCases), 3154 CASE_DESC(multithreadedCreateSharedResourcesTest <PipelineCache>, s_pipelineCacheCases), 3155 CASE_DESC(multithreadedCreateSharedResourcesTest <PipelineLayout>, s_pipelineLayoutCases), 3156 CASE_DESC(multithreadedCreateSharedResourcesTest <RenderPass>, s_renderPassCases), 3157 CASE_DESC(multithreadedCreateSharedResourcesTest <GraphicsPipeline>, s_graphicsPipelineCases), 3158 CASE_DESC(multithreadedCreateSharedResourcesTest <ComputePipeline>, s_computePipelineCases), 3159 CASE_DESC(multithreadedCreateSharedResourcesTest <DescriptorSetLayout>, s_descriptorSetLayoutCases), 3160 CASE_DESC(multithreadedCreateSharedResourcesTest <Sampler>, s_samplerCases), 3161 CASE_DESC(multithreadedCreateSharedResourcesTest <DescriptorPool>, s_descriptorPoolCases), 3162 EMPTY_CASE_DESC(DescriptorSet), // \note Needs per-thread DescriptorPool 3163 CASE_DESC(multithreadedCreateSharedResourcesTest <Framebuffer>, s_framebufferCases), 3164 CASE_DESC(multithreadedCreateSharedResourcesTest <CommandPool>, s_commandPoolCases), 3165 EMPTY_CASE_DESC(CommandBuffer), // \note Needs per-thread CommandPool 3166 }; 3167 objectMgmtTests->addChild(createGroup(testCtx, "multithreaded_shared_resources", "Multithreaded object construction with shared resources", s_multithreadedCreateSharedResourcesGroup)); 3168 3169 const CaseDescriptions s_createSingleAllocCallbacksGroup = 3170 { 3171 CASE_DESC(createSingleAllocCallbacksTest <Instance>, s_instanceCases), 3172 CASE_DESC(createSingleAllocCallbacksTest <Device>, s_deviceCases), 3173 CASE_DESC(createSingleAllocCallbacksTest <DeviceGroup>, s_deviceGroupCases), 3174 CASE_DESC(createSingleAllocCallbacksTest <DeviceMemory>, s_deviceMemCases), 3175 CASE_DESC(createSingleAllocCallbacksTest <Buffer>, s_bufferCases), 3176 CASE_DESC(createSingleAllocCallbacksTest <BufferView>, s_bufferViewCases), 3177 CASE_DESC(createSingleAllocCallbacksTest <Image>, s_imageCases), 3178 CASE_DESC(createSingleAllocCallbacksTest <ImageView>, s_imageViewCases), 3179 CASE_DESC(createSingleAllocCallbacksTest <Semaphore>, s_semaphoreCases), 3180 CASE_DESC(createSingleAllocCallbacksTest <Event>, s_eventCases), 3181 CASE_DESC(createSingleAllocCallbacksTest <Fence>, s_fenceCases), 3182 CASE_DESC(createSingleAllocCallbacksTest <QueryPool>, s_queryPoolCases), 3183 CASE_DESC(createSingleAllocCallbacksTest <ShaderModule>, s_shaderModuleCases), 3184 CASE_DESC(createSingleAllocCallbacksTest <PipelineCache>, s_pipelineCacheCases), 3185 CASE_DESC(createSingleAllocCallbacksTest <PipelineLayout>, s_pipelineLayoutCases), 3186 CASE_DESC(createSingleAllocCallbacksTest <RenderPass>, s_renderPassCases), 3187 CASE_DESC(createSingleAllocCallbacksTest <GraphicsPipeline>, s_graphicsPipelineCases), 3188 CASE_DESC(createSingleAllocCallbacksTest <ComputePipeline>, s_computePipelineCases), 3189 CASE_DESC(createSingleAllocCallbacksTest <DescriptorSetLayout>, s_descriptorSetLayoutCases), 3190 CASE_DESC(createSingleAllocCallbacksTest <Sampler>, s_samplerCases), 3191 CASE_DESC(createSingleAllocCallbacksTest <DescriptorPool>, s_descriptorPoolCases), 3192 CASE_DESC(createSingleAllocCallbacksTest <DescriptorSet>, s_descriptorSetCases), 3193 CASE_DESC(createSingleAllocCallbacksTest <Framebuffer>, s_framebufferCases), 3194 CASE_DESC(createSingleAllocCallbacksTest <CommandPool>, s_commandPoolCases), 3195 CASE_DESC(createSingleAllocCallbacksTest <CommandBuffer>, s_commandBufferCases), 3196 }; 3197 objectMgmtTests->addChild(createGroup(testCtx, "single_alloc_callbacks", "Create single object", s_createSingleAllocCallbacksGroup)); 3198 3199 // \note Skip pooled objects in this test group. They are properly handled by the "multiple" group farther down below. 3200 const CaseDescriptions s_allocCallbackFailGroup = 3201 { 3202 CASE_DESC(allocCallbackFailTest <Instance>, s_instanceCases), 3203 CASE_DESC(allocCallbackFailTest <Device>, s_deviceCases), 3204 CASE_DESC(allocCallbackFailTest <DeviceGroup>, s_deviceGroupCases), 3205 CASE_DESC(allocCallbackFailTest <DeviceMemory>, s_deviceMemCases), 3206 CASE_DESC(allocCallbackFailTest <Buffer>, s_bufferCases), 3207 CASE_DESC(allocCallbackFailTest <BufferView>, s_bufferViewCases), 3208 CASE_DESC(allocCallbackFailTest <Image>, s_imageCases), 3209 CASE_DESC(allocCallbackFailTest <ImageView>, s_imageViewCases), 3210 CASE_DESC(allocCallbackFailTest <Semaphore>, s_semaphoreCases), 3211 CASE_DESC(allocCallbackFailTest <Event>, s_eventCases), 3212 CASE_DESC(allocCallbackFailTest <Fence>, s_fenceCases), 3213 CASE_DESC(allocCallbackFailTest <QueryPool>, s_queryPoolCases), 3214 CASE_DESC(allocCallbackFailTest <ShaderModule>, s_shaderModuleCases), 3215 CASE_DESC(allocCallbackFailTest <PipelineCache>, s_pipelineCacheCases), 3216 CASE_DESC(allocCallbackFailTest <PipelineLayout>, s_pipelineLayoutCases), 3217 CASE_DESC(allocCallbackFailTest <RenderPass>, s_renderPassCases), 3218 CASE_DESC(allocCallbackFailTest <GraphicsPipeline>, s_graphicsPipelineCases), 3219 CASE_DESC(allocCallbackFailTest <ComputePipeline>, s_computePipelineCases), 3220 CASE_DESC(allocCallbackFailTest <DescriptorSetLayout>, s_descriptorSetLayoutCases), 3221 CASE_DESC(allocCallbackFailTest <Sampler>, s_samplerCases), 3222 CASE_DESC(allocCallbackFailTest <DescriptorPool>, s_descriptorPoolCases), 3223 EMPTY_CASE_DESC(DescriptorSet), 3224 CASE_DESC(allocCallbackFailTest <Framebuffer>, s_framebufferCases), 3225 CASE_DESC(allocCallbackFailTest <CommandPool>, s_commandPoolCases), 3226 EMPTY_CASE_DESC(CommandBuffer), 3227 }; 3228 objectMgmtTests->addChild(createGroup(testCtx, "alloc_callback_fail", "Allocation callback failure", s_allocCallbackFailGroup)); 3229 3230 // \note Test objects that can be created in bulk 3231 const CaseDescriptions s_allocCallbackFailMultipleObjectsGroup = 3232 { 3233 EMPTY_CASE_DESC(Instance), // most objects can be created one at a time only 3234 EMPTY_CASE_DESC(Device), 3235 EMPTY_CASE_DESC(DeviceGroup), 3236 EMPTY_CASE_DESC(DeviceMemory), 3237 EMPTY_CASE_DESC(Buffer), 3238 EMPTY_CASE_DESC(BufferView), 3239 EMPTY_CASE_DESC(Image), 3240 EMPTY_CASE_DESC(ImageView), 3241 EMPTY_CASE_DESC(Semaphore), 3242 EMPTY_CASE_DESC(Event), 3243 EMPTY_CASE_DESC(Fence), 3244 EMPTY_CASE_DESC(QueryPool), 3245 EMPTY_CASE_DESC(ShaderModule), 3246 EMPTY_CASE_DESC(PipelineCache), 3247 EMPTY_CASE_DESC(PipelineLayout), 3248 EMPTY_CASE_DESC(RenderPass), 3249 CASE_DESC(allocCallbackFailMultipleObjectsTest <GraphicsPipeline>, s_graphicsPipelineCases), 3250 CASE_DESC(allocCallbackFailMultipleObjectsTest <ComputePipeline>, s_computePipelineCases), 3251 EMPTY_CASE_DESC(DescriptorSetLayout), 3252 EMPTY_CASE_DESC(Sampler), 3253 EMPTY_CASE_DESC(DescriptorPool), 3254 CASE_DESC(allocCallbackFailMultipleObjectsTest <DescriptorSet>, s_descriptorSetCases), 3255 EMPTY_CASE_DESC(Framebuffer), 3256 EMPTY_CASE_DESC(CommandPool), 3257 CASE_DESC(allocCallbackFailMultipleObjectsTest <CommandBuffer>, s_commandBufferCases), 3258 }; 3259 objectMgmtTests->addChild(createGroup(testCtx, "alloc_callback_fail_multiple", "Allocation callback failure creating multiple objects with one call", s_allocCallbackFailMultipleObjectsGroup)); 3260 3261 return objectMgmtTests.release(); 3262 } 3263 3264 } // api 3265 } // vkt 3266