1/* 2 * Copyright (c) 2015-2016 The Khronos Group Inc. 3 * Copyright (c) 2015-2016 Valve Corporation 4 * Copyright (c) 2015-2016 LunarG, Inc. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and/or associated documentation files (the "Materials"), to 8 * deal in the Materials without restriction, including without limitation the 9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 * sell copies of the Materials, and to permit persons to whom the Materials are 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice(s) and this permission notice shall be included in 14 * all copies or substantial portions of the Materials. 15 * 16 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 * 20 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 21 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 22 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE 23 * USE OR OTHER DEALINGS IN THE MATERIALS. 24 * 25 * Author: Courtney Goeltzenleuchter <courtney@LunarG.com> 26 * Author: Cody Northrop <cody@lunarg.com> 27 */ 28 29#ifndef VKTESTBINDING_H 30#define VKTESTBINDING_H 31 32#include <vector> 33#include <assert.h> 34 35#include "vulkan/vulkan.h" 36 37namespace vk_testing { 38 39typedef void (*ErrorCallback)(const char *expr, const char *file, 40 unsigned int line, const char *function); 41void set_error_callback(ErrorCallback callback); 42 43class PhysicalDevice; 44class Device; 45class Queue; 46class DeviceMemory; 47class Fence; 48class Semaphore; 49class Event; 50class QueryPool; 51class Buffer; 52class BufferView; 53class Image; 54class ImageView; 55class DepthStencilView; 56class Shader; 57class Pipeline; 58class PipelineDelta; 59class Sampler; 60class DescriptorSetLayout; 61class PipelineLayout; 62class DescriptorSetPool; 63class DescriptorSet; 64class CommandBuffer; 65class CommandPool; 66 67std::vector<VkLayerProperties> GetGlobalLayers(); 68std::vector<VkExtensionProperties> GetGlobalExtensions(); 69std::vector<VkExtensionProperties> GetGlobalExtensions(const char *pLayerName); 70 71namespace internal { 72 73template <typename T> class Handle { 74 public: 75 const T &handle() const { return handle_; } 76 bool initialized() const { return (handle_ != VK_NULL_HANDLE); } 77 78 protected: 79 typedef T handle_type; 80 81 explicit Handle() : handle_(VK_NULL_HANDLE) {} 82 explicit Handle(T handle) : handle_(handle) {} 83 84 void init(T handle) { 85 assert(!initialized()); 86 handle_ = handle; 87 } 88 89 private: 90 // handles are non-copyable 91 Handle(const Handle &); 92 Handle &operator=(const Handle &); 93 94 T handle_; 95}; 96 97template <typename T> class NonDispHandle : public Handle<T> { 98 protected: 99 explicit NonDispHandle() : Handle<T>(), dev_handle_(VK_NULL_HANDLE) {} 100 explicit NonDispHandle(VkDevice dev, T handle) 101 : Handle<T>(handle), dev_handle_(dev) {} 102 103 const VkDevice &device() const { return dev_handle_; } 104 105 void init(VkDevice dev, T handle) { 106 assert(!Handle<T>::initialized() && dev_handle_ == VK_NULL_HANDLE); 107 Handle<T>::init(handle); 108 dev_handle_ = dev; 109 } 110 111 private: 112 VkDevice dev_handle_; 113}; 114 115} // namespace internal 116 117class PhysicalDevice : public internal::Handle<VkPhysicalDevice> { 118 public: 119 explicit PhysicalDevice(VkPhysicalDevice phy) : Handle(phy) { 120 memory_properties_ = memory_properties(); 121 device_properties_ = properties(); 122 } 123 124 VkPhysicalDeviceProperties properties() const; 125 VkPhysicalDeviceMemoryProperties memory_properties() const; 126 std::vector<VkQueueFamilyProperties> queue_properties() const; 127 128 bool set_memory_type(const uint32_t type_bits, VkMemoryAllocateInfo *info, 129 const VkMemoryPropertyFlags properties, 130 const VkMemoryPropertyFlags forbid = 0) const; 131 132 // vkEnumerateDeviceExtensionProperties() 133 std::vector<VkExtensionProperties> extensions() const; 134 std::vector<VkExtensionProperties> extensions(const char *pLayerName) const; 135 136 // vkEnumerateLayers() 137 std::vector<VkLayerProperties> layers() const; 138 139 private: 140 void 141 add_extension_dependencies(uint32_t dependency_count, 142 VkExtensionProperties *depencency_props, 143 std::vector<VkExtensionProperties> &ext_list); 144 145 VkPhysicalDeviceMemoryProperties memory_properties_; 146 147 VkPhysicalDeviceProperties device_properties_; 148}; 149 150class Device : public internal::Handle<VkDevice> { 151 public: 152 explicit Device(VkPhysicalDevice phy) : phy_(phy) {} 153 ~Device(); 154 155 // vkCreateDevice() 156 void init(const VkDeviceCreateInfo &info); 157 void init(std::vector<const char *> &layers, 158 std::vector<const char *> & 159 extensions); // all queues, all extensions, etc 160 void init() { 161 std::vector<const char *> layers; 162 std::vector<const char *> extensions; 163 init(layers, extensions); 164 }; 165 166 const PhysicalDevice &phy() const { return phy_; } 167 168 // vkGetDeviceProcAddr() 169 PFN_vkVoidFunction get_proc(const char *name) const { 170 return vkGetDeviceProcAddr(handle(), name); 171 } 172 173 // vkGetDeviceQueue() 174 const std::vector<Queue *> &graphics_queues() const { 175 return queues_[GRAPHICS]; 176 } 177 const std::vector<Queue *> &compute_queues() { return queues_[COMPUTE]; } 178 const std::vector<Queue *> &dma_queues() { return queues_[DMA]; } 179 uint32_t graphics_queue_node_index_; 180 181 struct Format { 182 VkFormat format; 183 VkImageTiling tiling; 184 VkFlags features; 185 }; 186 // vkGetFormatInfo() 187 VkFormatProperties format_properties(VkFormat format); 188 const std::vector<Format> &formats() const { return formats_; } 189 190 // vkDeviceWaitIdle() 191 void wait(); 192 193 // vkWaitForFences() 194 VkResult wait(const std::vector<const Fence *> &fences, bool wait_all, 195 uint64_t timeout); 196 VkResult wait(const Fence &fence) { 197 return wait(std::vector<const Fence *>(1, &fence), true, (uint64_t)-1); 198 } 199 200 // vkUpdateDescriptorSets() 201 void update_descriptor_sets(const std::vector<VkWriteDescriptorSet> &writes, 202 const std::vector<VkCopyDescriptorSet> &copies); 203 void 204 update_descriptor_sets(const std::vector<VkWriteDescriptorSet> &writes) { 205 return update_descriptor_sets(writes, 206 std::vector<VkCopyDescriptorSet>()); 207 } 208 209 static VkWriteDescriptorSet 210 write_descriptor_set(const DescriptorSet &set, uint32_t binding, 211 uint32_t array_element, VkDescriptorType type, 212 uint32_t count, 213 const VkDescriptorImageInfo *image_info); 214 static VkWriteDescriptorSet 215 write_descriptor_set(const DescriptorSet &set, uint32_t binding, 216 uint32_t array_element, VkDescriptorType type, 217 uint32_t count, 218 const VkDescriptorBufferInfo *buffer_info); 219 static VkWriteDescriptorSet 220 write_descriptor_set(const DescriptorSet &set, uint32_t binding, 221 uint32_t array_element, VkDescriptorType type, 222 uint32_t count, const VkBufferView *buffer_views); 223 static VkWriteDescriptorSet 224 write_descriptor_set(const DescriptorSet &set, uint32_t binding, 225 uint32_t array_element, VkDescriptorType type, 226 const std::vector<VkDescriptorImageInfo> &image_info); 227 static VkWriteDescriptorSet write_descriptor_set( 228 const DescriptorSet &set, uint32_t binding, uint32_t array_element, 229 VkDescriptorType type, 230 const std::vector<VkDescriptorBufferInfo> &buffer_info); 231 static VkWriteDescriptorSet 232 write_descriptor_set(const DescriptorSet &set, uint32_t binding, 233 uint32_t array_element, VkDescriptorType type, 234 const std::vector<VkBufferView> &buffer_views); 235 236 static VkCopyDescriptorSet 237 copy_descriptor_set(const DescriptorSet &src_set, uint32_t src_binding, 238 uint32_t src_array_element, 239 const DescriptorSet &dst_set, uint32_t dst_binding, 240 uint32_t dst_array_element, uint32_t count); 241 242 private: 243 enum QueueIndex { 244 GRAPHICS, 245 COMPUTE, 246 DMA, 247 QUEUE_COUNT, 248 }; 249 250 void init_queues(); 251 void init_formats(); 252 253 PhysicalDevice phy_; 254 255 std::vector<Queue *> queues_[QUEUE_COUNT]; 256 std::vector<Format> formats_; 257}; 258 259class Queue : public internal::Handle<VkQueue> { 260 public: 261 explicit Queue(VkQueue queue, int index) : Handle(queue) { 262 family_index_ = index; 263 } 264 265 // vkQueueSubmit() 266 void submit(const std::vector<const CommandBuffer *> &cmds, Fence &fence); 267 void submit(const CommandBuffer &cmd, Fence &fence); 268 void submit(const CommandBuffer &cmd); 269 270 // vkQueueWaitIdle() 271 void wait(); 272 273 int get_family_index() { return family_index_; } 274 275 private: 276 int family_index_; 277}; 278 279class DeviceMemory : public internal::NonDispHandle<VkDeviceMemory> { 280 public: 281 ~DeviceMemory(); 282 283 // vkAllocateMemory() 284 void init(const Device &dev, const VkMemoryAllocateInfo &info); 285 286 // vkMapMemory() 287 const void *map(VkFlags flags) const; 288 void *map(VkFlags flags); 289 const void *map() const { return map(0); } 290 void *map() { return map(0); } 291 292 // vkUnmapMemory() 293 void unmap() const; 294 295 static VkMemoryAllocateInfo alloc_info(VkDeviceSize size, 296 uint32_t memory_type_index); 297}; 298 299class Fence : public internal::NonDispHandle<VkFence> { 300 public: 301 ~Fence(); 302 303 // vkCreateFence() 304 void init(const Device &dev, const VkFenceCreateInfo &info); 305 306 // vkGetFenceStatus() 307 VkResult status() const { return vkGetFenceStatus(device(), handle()); } 308 309 static VkFenceCreateInfo create_info(VkFenceCreateFlags flags); 310 static VkFenceCreateInfo create_info(); 311}; 312 313class Semaphore : public internal::NonDispHandle<VkSemaphore> { 314 public: 315 ~Semaphore(); 316 317 // vkCreateSemaphore() 318 void init(const Device &dev, const VkSemaphoreCreateInfo &info); 319 320 static VkSemaphoreCreateInfo create_info(VkFlags flags); 321}; 322 323class Event : public internal::NonDispHandle<VkEvent> { 324 public: 325 ~Event(); 326 327 // vkCreateEvent() 328 void init(const Device &dev, const VkEventCreateInfo &info); 329 330 // vkGetEventStatus() 331 // vkSetEvent() 332 // vkResetEvent() 333 VkResult status() const { return vkGetEventStatus(device(), handle()); } 334 void set(); 335 void reset(); 336 337 static VkEventCreateInfo create_info(VkFlags flags); 338}; 339 340class QueryPool : public internal::NonDispHandle<VkQueryPool> { 341 public: 342 ~QueryPool(); 343 344 // vkCreateQueryPool() 345 void init(const Device &dev, const VkQueryPoolCreateInfo &info); 346 347 // vkGetQueryPoolResults() 348 VkResult results(uint32_t first, uint32_t count, size_t size, void *data, 349 size_t stride); 350 351 static VkQueryPoolCreateInfo create_info(VkQueryType type, 352 uint32_t slot_count); 353}; 354 355class Buffer : public internal::NonDispHandle<VkBuffer> { 356 public: 357 explicit Buffer() : NonDispHandle() {} 358 explicit Buffer(const Device &dev, const VkBufferCreateInfo &info) { 359 init(dev, info); 360 } 361 explicit Buffer(const Device &dev, VkDeviceSize size) { init(dev, size); } 362 363 ~Buffer(); 364 365 // vkCreateBuffer() 366 void init(const Device &dev, const VkBufferCreateInfo &info, 367 VkMemoryPropertyFlags mem_props); 368 void init(const Device &dev, const VkBufferCreateInfo &info) { 369 init(dev, info, 0); 370 } 371 void init(const Device &dev, VkDeviceSize size, 372 VkMemoryPropertyFlags mem_props) { 373 init(dev, create_info(size, 0), mem_props); 374 } 375 void init(const Device &dev, VkDeviceSize size) { init(dev, size, 0); } 376 void init_as_src(const Device &dev, VkDeviceSize size, 377 VkMemoryPropertyFlags &reqs) { 378 init(dev, create_info(size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT), reqs); 379 } 380 void init_as_dst(const Device &dev, VkDeviceSize size, 381 VkMemoryPropertyFlags &reqs) { 382 init(dev, create_info(size, VK_BUFFER_USAGE_TRANSFER_DST_BIT), reqs); 383 } 384 void init_as_src_and_dst(const Device &dev, VkDeviceSize size, 385 VkMemoryPropertyFlags &reqs) { 386 init(dev, create_info(size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | 387 VK_BUFFER_USAGE_TRANSFER_DST_BIT), 388 reqs); 389 } 390 void init_no_mem(const Device &dev, const VkBufferCreateInfo &info); 391 392 // get the internal memory 393 const DeviceMemory &memory() const { return internal_mem_; } 394 DeviceMemory &memory() { return internal_mem_; } 395 396 // vkGetObjectMemoryRequirements() 397 VkMemoryRequirements memory_requirements() const; 398 399 // vkBindObjectMemory() 400 void bind_memory(const DeviceMemory &mem, VkDeviceSize mem_offset); 401 402 static VkBufferCreateInfo create_info(VkDeviceSize size, VkFlags usage); 403 404 VkBufferMemoryBarrier buffer_memory_barrier(VkFlags output_mask, 405 VkFlags input_mask, 406 VkDeviceSize offset, 407 VkDeviceSize size) const { 408 VkBufferMemoryBarrier barrier = {}; 409 barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; 410 barrier.buffer = handle(); 411 barrier.srcAccessMask = output_mask; 412 barrier.dstAccessMask = input_mask; 413 barrier.offset = offset; 414 barrier.size = size; 415 return barrier; 416 } 417 418 private: 419 VkBufferCreateInfo create_info_; 420 421 DeviceMemory internal_mem_; 422}; 423 424class BufferView : public internal::NonDispHandle<VkBufferView> { 425 public: 426 ~BufferView(); 427 428 // vkCreateBufferView() 429 void init(const Device &dev, const VkBufferViewCreateInfo &info); 430}; 431 432class Image : public internal::NonDispHandle<VkImage> { 433 public: 434 explicit Image() : NonDispHandle(), format_features_(0) {} 435 explicit Image(const Device &dev, const VkImageCreateInfo &info) 436 : format_features_(0) { 437 init(dev, info); 438 } 439 440 ~Image(); 441 442 // vkCreateImage() 443 void init(const Device &dev, const VkImageCreateInfo &info, 444 VkMemoryPropertyFlags mem_props); 445 void init(const Device &dev, const VkImageCreateInfo &info) { 446 init(dev, info, 0); 447 } 448 void init_no_mem(const Device &dev, const VkImageCreateInfo &info); 449 450 // get the internal memory 451 const DeviceMemory &memory() const { return internal_mem_; } 452 DeviceMemory &memory() { return internal_mem_; } 453 454 // vkGetObjectMemoryRequirements() 455 VkMemoryRequirements memory_requirements() const; 456 457 // vkBindObjectMemory() 458 void bind_memory(const DeviceMemory &mem, VkDeviceSize mem_offset); 459 460 // vkGetImageSubresourceLayout() 461 VkSubresourceLayout 462 subresource_layout(const VkImageSubresource &subres) const; 463 VkSubresourceLayout 464 subresource_layout(const VkImageSubresourceLayers &subres) const; 465 466 bool transparent() const; 467 bool copyable() const { 468 return (format_features_ & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT); 469 } 470 471 VkImageSubresourceRange 472 subresource_range(VkImageAspectFlagBits aspect) const { 473 return subresource_range(create_info_, aspect); 474 } 475 VkExtent3D extent() const { return create_info_.extent; } 476 VkExtent3D extent(uint32_t mip_level) const { 477 return extent(create_info_.extent, mip_level); 478 } 479 VkFormat format() const { return create_info_.format; } 480 481 VkImageMemoryBarrier 482 image_memory_barrier(VkFlags output_mask, VkFlags input_mask, 483 VkImageLayout old_layout, VkImageLayout new_layout, 484 const VkImageSubresourceRange &range) const { 485 VkImageMemoryBarrier barrier = {}; 486 barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; 487 barrier.srcAccessMask = output_mask; 488 barrier.dstAccessMask = input_mask; 489 barrier.oldLayout = old_layout; 490 barrier.newLayout = new_layout; 491 barrier.image = handle(); 492 barrier.subresourceRange = range; 493 return barrier; 494 } 495 496 static VkImageCreateInfo create_info(); 497 static VkImageAspectFlagBits image_aspect(VkImageAspectFlags flags); 498 static VkImageSubresource subresource(VkImageAspectFlagBits aspect, 499 uint32_t mip_level, 500 uint32_t array_layer); 501 static VkImageSubresource subresource(const VkImageSubresourceRange &range, 502 uint32_t mip_level, 503 uint32_t array_layer); 504 static VkImageSubresourceLayers subresource(VkImageAspectFlagBits aspect, 505 uint32_t mip_level, 506 uint32_t array_layer, 507 uint32_t array_size); 508 static VkImageSubresourceLayers 509 subresource(const VkImageSubresourceRange &range, uint32_t mip_level, 510 uint32_t array_layer, uint32_t array_size); 511 static VkImageSubresourceRange 512 subresource_range(VkImageAspectFlags aspect_mask, uint32_t base_mip_level, 513 uint32_t mip_levels, uint32_t base_array_layer, 514 uint32_t num_layers); 515 static VkImageSubresourceRange 516 subresource_range(const VkImageCreateInfo &info, 517 VkImageAspectFlags aspect_mask); 518 static VkImageSubresourceRange 519 subresource_range(const VkImageSubresource &subres); 520 521 static VkExtent2D extent(int32_t width, int32_t height); 522 static VkExtent2D extent(const VkExtent2D &extent, uint32_t mip_level); 523 static VkExtent2D extent(const VkExtent3D &extent); 524 525 static VkExtent3D extent(int32_t width, int32_t height, int32_t depth); 526 static VkExtent3D extent(const VkExtent3D &extent, uint32_t mip_level); 527 528 private: 529 void init_info(const Device &dev, const VkImageCreateInfo &info); 530 531 VkImageCreateInfo create_info_; 532 VkFlags format_features_; 533 534 DeviceMemory internal_mem_; 535}; 536 537class ImageView : public internal::NonDispHandle<VkImageView> { 538 public: 539 ~ImageView(); 540 541 // vkCreateImageView() 542 void init(const Device &dev, const VkImageViewCreateInfo &info); 543}; 544 545class ShaderModule : public internal::NonDispHandle<VkShaderModule> { 546 public: 547 ~ShaderModule(); 548 549 // vkCreateShaderModule() 550 void init(const Device &dev, const VkShaderModuleCreateInfo &info); 551 VkResult init_try(const Device &dev, const VkShaderModuleCreateInfo &info); 552 553 static VkShaderModuleCreateInfo 554 create_info(size_t code_size, const uint32_t *code, VkFlags flags); 555}; 556 557class Pipeline : public internal::NonDispHandle<VkPipeline> { 558 public: 559 ~Pipeline(); 560 561 // vkCreateGraphicsPipeline() 562 void init(const Device &dev, const VkGraphicsPipelineCreateInfo &info); 563 // vkCreateGraphicsPipelineDerivative() 564 void init(const Device &dev, const VkGraphicsPipelineCreateInfo &info, 565 const VkPipeline basePipeline); 566 // vkCreateComputePipeline() 567 void init(const Device &dev, const VkComputePipelineCreateInfo &info); 568 // vkLoadPipeline() 569 void init(const Device &dev, size_t size, const void *data); 570 // vkLoadPipelineDerivative() 571 void init(const Device &dev, size_t size, const void *data, 572 VkPipeline basePipeline); 573 574 // vkCreateGraphicsPipeline with error return 575 VkResult init_try(const Device &dev, 576 const VkGraphicsPipelineCreateInfo &info); 577 578 // vkStorePipeline() 579 size_t store(size_t size, void *data); 580}; 581 582class PipelineLayout : public internal::NonDispHandle<VkPipelineLayout> { 583 public: 584 ~PipelineLayout(); 585 586 // vCreatePipelineLayout() 587 void init(const Device &dev, VkPipelineLayoutCreateInfo &info, 588 const std::vector<const DescriptorSetLayout *> &layouts); 589}; 590 591class Sampler : public internal::NonDispHandle<VkSampler> { 592 public: 593 ~Sampler(); 594 595 // vkCreateSampler() 596 void init(const Device &dev, const VkSamplerCreateInfo &info); 597}; 598 599class DescriptorSetLayout 600 : public internal::NonDispHandle<VkDescriptorSetLayout> { 601 public: 602 ~DescriptorSetLayout(); 603 604 // vkCreateDescriptorSetLayout() 605 void init(const Device &dev, const VkDescriptorSetLayoutCreateInfo &info); 606}; 607 608class DescriptorPool : public internal::NonDispHandle<VkDescriptorPool> { 609 public: 610 ~DescriptorPool(); 611 612 // Descriptor sets allocated from this pool will need access to the original 613 // object 614 VkDescriptorPool GetObj() { return pool_; } 615 616 // vkCreateDescriptorPool() 617 void init(const Device &dev, const VkDescriptorPoolCreateInfo &info); 618 619 // vkResetDescriptorPool() 620 void reset(); 621 622 // vkFreeDescriptorSet() 623 void setDynamicUsage(bool isDynamic) { dynamic_usage_ = isDynamic; } 624 bool getDynamicUsage() { return dynamic_usage_; } 625 626 // vkAllocateDescriptorSets() 627 std::vector<DescriptorSet *> 628 alloc_sets(const Device &dev, 629 const std::vector<const DescriptorSetLayout *> &layouts); 630 std::vector<DescriptorSet *> alloc_sets(const Device &dev, 631 const DescriptorSetLayout &layout, 632 uint32_t count); 633 DescriptorSet *alloc_sets(const Device &dev, 634 const DescriptorSetLayout &layout); 635 636 private: 637 VkDescriptorPool pool_; 638 639 // Track whether this pool's usage is VK_DESCRIPTOR_POOL_USAGE_DYNAMIC 640 bool dynamic_usage_; 641}; 642 643class DescriptorSet : public internal::NonDispHandle<VkDescriptorSet> { 644 public: 645 ~DescriptorSet(); 646 647 explicit DescriptorSet() : NonDispHandle() {} 648 explicit DescriptorSet(const Device &dev, DescriptorPool *pool, 649 VkDescriptorSet set) 650 : NonDispHandle(dev.handle(), set) { 651 containing_pool_ = pool; 652 } 653 654 private: 655 DescriptorPool *containing_pool_; 656}; 657 658class CommandPool : public internal::NonDispHandle<VkCommandPool> { 659 public: 660 ~CommandPool(); 661 662 explicit CommandPool() : NonDispHandle() {} 663 explicit CommandPool(const Device &dev, 664 const VkCommandPoolCreateInfo &info) { 665 init(dev, info); 666 } 667 668 void init(const Device &dev, const VkCommandPoolCreateInfo &info); 669 670 static VkCommandPoolCreateInfo create_info(uint32_t queue_family_index); 671}; 672 673inline VkCommandPoolCreateInfo 674CommandPool::create_info(uint32_t queue_family_index) { 675 VkCommandPoolCreateInfo info = {}; 676 info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 677 info.queueFamilyIndex = queue_family_index; 678 info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; 679 return info; 680} 681 682class CommandBuffer : public internal::Handle<VkCommandBuffer> { 683 public: 684 ~CommandBuffer(); 685 686 explicit CommandBuffer() : Handle() {} 687 explicit CommandBuffer(const Device &dev, 688 const VkCommandBufferAllocateInfo &info) { 689 init(dev, info); 690 } 691 692 // vkAllocateCommandBuffers() 693 void init(const Device &dev, const VkCommandBufferAllocateInfo &info); 694 695 // vkBeginCommandBuffer() 696 void begin(const VkCommandBufferBeginInfo *info); 697 void begin(); 698 699 // vkEndCommandBuffer() 700 // vkResetCommandBuffer() 701 void end(); 702 void reset(VkCommandBufferResetFlags flags); 703 void reset() { reset(VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT); } 704 705 static VkCommandBufferAllocateInfo create_info(VkCommandPool const &pool); 706 707 private: 708 VkDevice dev_handle_; 709 VkCommandPool cmd_pool_; 710}; 711 712inline VkMemoryAllocateInfo 713DeviceMemory::alloc_info(VkDeviceSize size, uint32_t memory_type_index) { 714 VkMemoryAllocateInfo info = {}; 715 info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 716 info.allocationSize = size; 717 info.memoryTypeIndex = memory_type_index; 718 return info; 719} 720 721inline VkBufferCreateInfo Buffer::create_info(VkDeviceSize size, 722 VkFlags usage) { 723 VkBufferCreateInfo info = {}; 724 info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 725 info.size = size; 726 info.usage = usage; 727 return info; 728} 729 730inline VkFenceCreateInfo Fence::create_info(VkFenceCreateFlags flags) { 731 VkFenceCreateInfo info = {}; 732 info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 733 info.flags = flags; 734 return info; 735} 736 737inline VkFenceCreateInfo Fence::create_info() { 738 VkFenceCreateInfo info = {}; 739 info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 740 return info; 741} 742 743inline VkSemaphoreCreateInfo Semaphore::create_info(VkFlags flags) { 744 VkSemaphoreCreateInfo info = {}; 745 info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; 746 info.flags = flags; 747 return info; 748} 749 750inline VkEventCreateInfo Event::create_info(VkFlags flags) { 751 VkEventCreateInfo info = {}; 752 info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO; 753 info.flags = flags; 754 return info; 755} 756 757inline VkQueryPoolCreateInfo QueryPool::create_info(VkQueryType type, 758 uint32_t slot_count) { 759 VkQueryPoolCreateInfo info = {}; 760 info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO; 761 info.queryType = type; 762 info.queryCount = slot_count; 763 return info; 764} 765 766inline VkImageCreateInfo Image::create_info() { 767 VkImageCreateInfo info = {}; 768 info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 769 info.extent.width = 1; 770 info.extent.height = 1; 771 info.extent.depth = 1; 772 info.mipLevels = 1; 773 info.arrayLayers = 1; 774 info.samples = VK_SAMPLE_COUNT_1_BIT; 775 return info; 776} 777 778inline VkImageSubresource Image::subresource(VkImageAspectFlagBits aspect, 779 uint32_t mip_level, 780 uint32_t array_layer) { 781 VkImageSubresource subres = {}; 782 subres.aspectMask = aspect; 783 subres.mipLevel = mip_level; 784 subres.arrayLayer = array_layer; 785 return subres; 786} 787 788inline VkImageSubresource 789Image::subresource(const VkImageSubresourceRange &range, uint32_t mip_level, 790 uint32_t array_layer) { 791 return subresource(image_aspect(range.aspectMask), 792 range.baseMipLevel + mip_level, 793 range.baseArrayLayer + array_layer); 794} 795 796inline VkImageSubresourceLayers Image::subresource(VkImageAspectFlagBits aspect, 797 uint32_t mip_level, 798 uint32_t array_layer, 799 uint32_t array_size) { 800 VkImageSubresourceLayers subres = {}; 801 subres.aspectMask = aspect; 802 subres.mipLevel = mip_level; 803 subres.baseArrayLayer = array_layer; 804 subres.layerCount = array_size; 805 return subres; 806} 807 808inline VkImageAspectFlagBits Image::image_aspect(VkImageAspectFlags flags) { 809 /* 810 * This will map VkImageAspectFlags into a single VkImageAspect. 811 * If there is more than one bit defined we'll get an assertion. 812 */ 813 switch (flags) { 814 case VK_IMAGE_ASPECT_COLOR_BIT: 815 return VK_IMAGE_ASPECT_COLOR_BIT; 816 case VK_IMAGE_ASPECT_DEPTH_BIT: 817 return VK_IMAGE_ASPECT_DEPTH_BIT; 818 case VK_IMAGE_ASPECT_STENCIL_BIT: 819 return VK_IMAGE_ASPECT_STENCIL_BIT; 820 case VK_IMAGE_ASPECT_METADATA_BIT: 821 return VK_IMAGE_ASPECT_METADATA_BIT; 822 default: 823 assert(!"Invalid VkImageAspect"); 824 } 825 return VK_IMAGE_ASPECT_COLOR_BIT; 826} 827 828inline VkImageSubresourceLayers 829Image::subresource(const VkImageSubresourceRange &range, uint32_t mip_level, 830 uint32_t array_layer, uint32_t array_size) { 831 return subresource(image_aspect(range.aspectMask), 832 range.baseMipLevel + mip_level, 833 range.baseArrayLayer + array_layer, array_size); 834} 835 836inline VkImageSubresourceRange 837Image::subresource_range(VkImageAspectFlags aspect_mask, 838 uint32_t base_mip_level, uint32_t mip_levels, 839 uint32_t base_array_layer, uint32_t num_layers) { 840 VkImageSubresourceRange range = {}; 841 range.aspectMask = aspect_mask; 842 range.baseMipLevel = base_mip_level; 843 range.levelCount = mip_levels; 844 range.baseArrayLayer = base_array_layer; 845 range.layerCount = num_layers; 846 return range; 847} 848 849inline VkImageSubresourceRange 850Image::subresource_range(const VkImageCreateInfo &info, 851 VkImageAspectFlags aspect_mask) { 852 return subresource_range(aspect_mask, 0, info.mipLevels, 0, 853 info.arrayLayers); 854} 855 856inline VkImageSubresourceRange 857Image::subresource_range(const VkImageSubresource &subres) { 858 return subresource_range(subres.aspectMask, subres.mipLevel, 1, 859 subres.arrayLayer, 1); 860} 861 862inline VkExtent2D Image::extent(int32_t width, int32_t height) { 863 VkExtent2D extent = {}; 864 extent.width = width; 865 extent.height = height; 866 return extent; 867} 868 869inline VkExtent2D Image::extent(const VkExtent2D &extent, uint32_t mip_level) { 870 const int32_t width = 871 (extent.width >> mip_level) ? extent.width >> mip_level : 1; 872 const int32_t height = 873 (extent.height >> mip_level) ? extent.height >> mip_level : 1; 874 return Image::extent(width, height); 875} 876 877inline VkExtent2D Image::extent(const VkExtent3D &extent) { 878 return Image::extent(extent.width, extent.height); 879} 880 881inline VkExtent3D Image::extent(int32_t width, int32_t height, int32_t depth) { 882 VkExtent3D extent = {}; 883 extent.width = width; 884 extent.height = height; 885 extent.depth = depth; 886 return extent; 887} 888 889inline VkExtent3D Image::extent(const VkExtent3D &extent, uint32_t mip_level) { 890 const int32_t width = 891 (extent.width >> mip_level) ? extent.width >> mip_level : 1; 892 const int32_t height = 893 (extent.height >> mip_level) ? extent.height >> mip_level : 1; 894 const int32_t depth = 895 (extent.depth >> mip_level) ? extent.depth >> mip_level : 1; 896 return Image::extent(width, height, depth); 897} 898 899inline VkShaderModuleCreateInfo ShaderModule::create_info(size_t code_size, 900 const uint32_t *code, 901 VkFlags flags) { 902 VkShaderModuleCreateInfo info = {}; 903 info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; 904 info.codeSize = code_size; 905 info.pCode = code; 906 info.flags = flags; 907 return info; 908} 909 910inline VkWriteDescriptorSet 911Device::write_descriptor_set(const DescriptorSet &set, uint32_t binding, 912 uint32_t array_element, VkDescriptorType type, 913 uint32_t count, 914 const VkDescriptorImageInfo *image_info) { 915 VkWriteDescriptorSet write = {}; 916 write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 917 write.dstSet = set.handle(); 918 write.dstBinding = binding; 919 write.dstArrayElement = array_element; 920 write.descriptorCount = count; 921 write.descriptorType = type; 922 write.pImageInfo = image_info; 923 return write; 924} 925 926inline VkWriteDescriptorSet 927Device::write_descriptor_set(const DescriptorSet &set, uint32_t binding, 928 uint32_t array_element, VkDescriptorType type, 929 uint32_t count, 930 const VkDescriptorBufferInfo *buffer_info) { 931 VkWriteDescriptorSet write = {}; 932 write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 933 write.dstSet = set.handle(); 934 write.dstBinding = binding; 935 write.dstArrayElement = array_element; 936 write.descriptorCount = count; 937 write.descriptorType = type; 938 write.pBufferInfo = buffer_info; 939 return write; 940} 941 942inline VkWriteDescriptorSet 943Device::write_descriptor_set(const DescriptorSet &set, uint32_t binding, 944 uint32_t array_element, VkDescriptorType type, 945 uint32_t count, const VkBufferView *buffer_views) { 946 VkWriteDescriptorSet write = {}; 947 write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 948 write.dstSet = set.handle(); 949 write.dstBinding = binding; 950 write.dstArrayElement = array_element; 951 write.descriptorCount = count; 952 write.descriptorType = type; 953 write.pTexelBufferView = buffer_views; 954 return write; 955} 956 957inline VkWriteDescriptorSet Device::write_descriptor_set( 958 const DescriptorSet &set, uint32_t binding, uint32_t array_element, 959 VkDescriptorType type, 960 const std::vector<VkDescriptorImageInfo> &image_info) { 961 return write_descriptor_set(set, binding, array_element, type, 962 image_info.size(), &image_info[0]); 963} 964 965inline VkWriteDescriptorSet Device::write_descriptor_set( 966 const DescriptorSet &set, uint32_t binding, uint32_t array_element, 967 VkDescriptorType type, 968 const std::vector<VkDescriptorBufferInfo> &buffer_info) { 969 return write_descriptor_set(set, binding, array_element, type, 970 buffer_info.size(), &buffer_info[0]); 971} 972 973inline VkWriteDescriptorSet 974Device::write_descriptor_set(const DescriptorSet &set, uint32_t binding, 975 uint32_t array_element, VkDescriptorType type, 976 const std::vector<VkBufferView> &buffer_views) { 977 return write_descriptor_set(set, binding, array_element, type, 978 buffer_views.size(), &buffer_views[0]); 979} 980 981inline VkCopyDescriptorSet 982Device::copy_descriptor_set(const DescriptorSet &src_set, uint32_t src_binding, 983 uint32_t src_array_element, 984 const DescriptorSet &dst_set, uint32_t dst_binding, 985 uint32_t dst_array_element, uint32_t count) { 986 VkCopyDescriptorSet copy = {}; 987 copy.sType = VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET; 988 copy.srcSet = src_set.handle(); 989 copy.srcBinding = src_binding; 990 copy.srcArrayElement = src_array_element; 991 copy.dstSet = dst_set.handle(); 992 copy.dstBinding = dst_binding; 993 copy.dstArrayElement = dst_array_element; 994 copy.descriptorCount = count; 995 996 return copy; 997} 998 999inline VkCommandBufferAllocateInfo 1000CommandBuffer::create_info(VkCommandPool const &pool) { 1001 VkCommandBufferAllocateInfo info = {}; 1002 info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 1003 info.commandPool = pool; 1004 info.commandBufferCount = 1; 1005 return info; 1006} 1007 1008}; // namespace vk_testing 1009 1010#endif // VKTESTBINDING_H 1011