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