Home | History | Annotate | Download | only in tests
      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 (at) LunarG.com>
     26  * Author: Cody Northrop <cody (at) 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 
     37 namespace vk_testing {
     38 
     39 typedef void (*ErrorCallback)(const char *expr, const char *file,
     40                               unsigned int line, const char *function);
     41 void set_error_callback(ErrorCallback callback);
     42 
     43 class PhysicalDevice;
     44 class Device;
     45 class Queue;
     46 class DeviceMemory;
     47 class Fence;
     48 class Semaphore;
     49 class Event;
     50 class QueryPool;
     51 class Buffer;
     52 class BufferView;
     53 class Image;
     54 class ImageView;
     55 class DepthStencilView;
     56 class Shader;
     57 class Pipeline;
     58 class PipelineDelta;
     59 class Sampler;
     60 class DescriptorSetLayout;
     61 class PipelineLayout;
     62 class DescriptorSetPool;
     63 class DescriptorSet;
     64 class CommandBuffer;
     65 class CommandPool;
     66 
     67 std::vector<VkLayerProperties> GetGlobalLayers();
     68 std::vector<VkExtensionProperties> GetGlobalExtensions();
     69 std::vector<VkExtensionProperties> GetGlobalExtensions(const char *pLayerName);
     70 
     71 namespace internal {
     72 
     73 template <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 
     97 template <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 
    117 class 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 
    150 class 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 
    259 class 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 
    279 class 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 
    299 class 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 
    313 class 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 
    323 class 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 
    340 class 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 
    355 class 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 
    424 class BufferView : public internal::NonDispHandle<VkBufferView> {
    425   public:
    426     ~BufferView();
    427 
    428     // vkCreateBufferView()
    429     void init(const Device &dev, const VkBufferViewCreateInfo &info);
    430 };
    431 
    432 class 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 
    537 class ImageView : public internal::NonDispHandle<VkImageView> {
    538   public:
    539     ~ImageView();
    540 
    541     // vkCreateImageView()
    542     void init(const Device &dev, const VkImageViewCreateInfo &info);
    543 };
    544 
    545 class 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 
    557 class 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 
    582 class 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 
    591 class Sampler : public internal::NonDispHandle<VkSampler> {
    592   public:
    593     ~Sampler();
    594 
    595     // vkCreateSampler()
    596     void init(const Device &dev, const VkSamplerCreateInfo &info);
    597 };
    598 
    599 class DescriptorSetLayout
    600     : public internal::NonDispHandle<VkDescriptorSetLayout> {
    601   public:
    602     ~DescriptorSetLayout();
    603 
    604     // vkCreateDescriptorSetLayout()
    605     void init(const Device &dev, const VkDescriptorSetLayoutCreateInfo &info);
    606 };
    607 
    608 class 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 
    643 class 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 
    658 class 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 
    673 inline VkCommandPoolCreateInfo
    674 CommandPool::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 
    682 class 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 
    712 inline VkMemoryAllocateInfo
    713 DeviceMemory::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 
    721 inline 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 
    730 inline 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 
    737 inline VkFenceCreateInfo Fence::create_info() {
    738     VkFenceCreateInfo info = {};
    739     info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
    740     return info;
    741 }
    742 
    743 inline 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 
    750 inline 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 
    757 inline 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 
    766 inline 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 
    778 inline 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 
    788 inline VkImageSubresource
    789 Image::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 
    796 inline 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 
    808 inline 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 
    828 inline VkImageSubresourceLayers
    829 Image::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 
    836 inline VkImageSubresourceRange
    837 Image::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 
    849 inline VkImageSubresourceRange
    850 Image::subresource_range(const VkImageCreateInfo &info,
    851                          VkImageAspectFlags aspect_mask) {
    852     return subresource_range(aspect_mask, 0, info.mipLevels, 0,
    853                              info.arrayLayers);
    854 }
    855 
    856 inline VkImageSubresourceRange
    857 Image::subresource_range(const VkImageSubresource &subres) {
    858     return subresource_range(subres.aspectMask, subres.mipLevel, 1,
    859                              subres.arrayLayer, 1);
    860 }
    861 
    862 inline 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 
    869 inline 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 
    877 inline VkExtent2D Image::extent(const VkExtent3D &extent) {
    878     return Image::extent(extent.width, extent.height);
    879 }
    880 
    881 inline 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 
    889 inline 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 
    899 inline 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 
    910 inline VkWriteDescriptorSet
    911 Device::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 
    926 inline VkWriteDescriptorSet
    927 Device::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 
    942 inline VkWriteDescriptorSet
    943 Device::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 
    957 inline 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 
    965 inline 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 
    973 inline VkWriteDescriptorSet
    974 Device::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 
    981 inline VkCopyDescriptorSet
    982 Device::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 
    999 inline VkCommandBufferAllocateInfo
   1000 CommandBuffer::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