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