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