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 
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:
handle()75     const T &handle() const { return handle_; }
initialized()76     bool initialized() const { return (handle_ != VK_NULL_HANDLE); }
77 
78   protected:
79     typedef T handle_type;
80 
Handle()81     explicit Handle() : handle_(VK_NULL_HANDLE) {}
Handle(T handle)82     explicit Handle(T handle) : handle_(handle) {}
83 
init(T handle)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:
NonDispHandle()99     explicit NonDispHandle() : Handle<T>(), dev_handle_(VK_NULL_HANDLE) {}
NonDispHandle(VkDevice dev,T handle)100     explicit NonDispHandle(VkDevice dev, T handle)
101         : Handle<T>(handle), dev_handle_(dev) {}
102 
device()103     const VkDevice &device() const { return dev_handle_; }
104 
init(VkDevice dev,T handle)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:
PhysicalDevice(VkPhysicalDevice phy)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:
Device(VkPhysicalDevice phy)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
init()160     void init() {
161         std::vector<const char *> layers;
162         std::vector<const char *> extensions;
163         init(layers, extensions);
164     };
165 
phy()166     const PhysicalDevice &phy() const { return phy_; }
167 
168     // vkGetDeviceProcAddr()
get_proc(const char * name)169     PFN_vkVoidFunction get_proc(const char *name) const {
170         return vkGetDeviceProcAddr(handle(), name);
171     }
172 
173     // vkGetDeviceQueue()
graphics_queues()174     const std::vector<Queue *> &graphics_queues() const {
175         return queues_[GRAPHICS];
176     }
compute_queues()177     const std::vector<Queue *> &compute_queues() { return queues_[COMPUTE]; }
dma_queues()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);
formats()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);
wait(const Fence & fence)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
update_descriptor_sets(const std::vector<VkWriteDescriptorSet> & writes)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:
Queue(VkQueue queue,int index)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 
get_family_index()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);
map()289     const void *map() const { return map(0); }
map()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()
status()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()
status()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:
Buffer()357     explicit Buffer() : NonDispHandle() {}
Buffer(const Device & dev,const VkBufferCreateInfo & info)358     explicit Buffer(const Device &dev, const VkBufferCreateInfo &info) {
359         init(dev, info);
360     }
Buffer(const Device & dev,VkDeviceSize size)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);
init(const Device & dev,const VkBufferCreateInfo & info)368     void init(const Device &dev, const VkBufferCreateInfo &info) {
369         init(dev, info, 0);
370     }
init(const Device & dev,VkDeviceSize size,VkMemoryPropertyFlags mem_props)371     void init(const Device &dev, VkDeviceSize size,
372               VkMemoryPropertyFlags mem_props) {
373         init(dev, create_info(size, 0), mem_props);
374     }
init(const Device & dev,VkDeviceSize size)375     void init(const Device &dev, VkDeviceSize size) { init(dev, size, 0); }
init_as_src(const Device & dev,VkDeviceSize size,VkMemoryPropertyFlags & reqs)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     }
init_as_dst(const Device & dev,VkDeviceSize size,VkMemoryPropertyFlags & reqs)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     }
init_as_src_and_dst(const Device & dev,VkDeviceSize size,VkMemoryPropertyFlags & reqs)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
memory()393     const DeviceMemory &memory() const { return internal_mem_; }
memory()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 
buffer_memory_barrier(VkFlags output_mask,VkFlags input_mask,VkDeviceSize offset,VkDeviceSize size)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:
Image()434     explicit Image() : NonDispHandle(), format_features_(0) {}
Image(const Device & dev,const VkImageCreateInfo & info)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);
init(const Device & dev,const VkImageCreateInfo & info)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
memory()451     const DeviceMemory &memory() const { return internal_mem_; }
memory()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;
copyable()467     bool copyable() const {
468         return (format_features_ & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT);
469     }
470 
471     VkImageSubresourceRange
subresource_range(VkImageAspectFlagBits aspect)472     subresource_range(VkImageAspectFlagBits aspect) const {
473         return subresource_range(create_info_, aspect);
474     }
extent()475     VkExtent3D extent() const { return create_info_.extent; }
extent(uint32_t mip_level)476     VkExtent3D extent(uint32_t mip_level) const {
477         return extent(create_info_.extent, mip_level);
478     }
format()479     VkFormat format() const { return create_info_.format; }
480 
481     VkImageMemoryBarrier
image_memory_barrier(VkFlags output_mask,VkFlags input_mask,VkImageLayout old_layout,VkImageLayout new_layout,const VkImageSubresourceRange & range)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
GetObj()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()
setDynamicUsage(bool isDynamic)623     void setDynamicUsage(bool isDynamic) { dynamic_usage_ = isDynamic; }
getDynamicUsage()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 
DescriptorSet()647     explicit DescriptorSet() : NonDispHandle() {}
DescriptorSet(const Device & dev,DescriptorPool * pool,VkDescriptorSet set)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 
CommandPool()662     explicit CommandPool() : NonDispHandle() {}
CommandPool(const Device & dev,const VkCommandPoolCreateInfo & info)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
create_info(uint32_t queue_family_index)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 
CommandBuffer()686     explicit CommandBuffer() : Handle() {}
CommandBuffer(const Device & dev,const VkCommandBufferAllocateInfo & info)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);
reset()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
alloc_info(VkDeviceSize size,uint32_t memory_type_index)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 
create_info(VkDeviceSize size,VkFlags usage)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 
create_info(VkFenceCreateFlags flags)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 
create_info()737 inline VkFenceCreateInfo Fence::create_info() {
738     VkFenceCreateInfo info = {};
739     info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
740     return info;
741 }
742 
create_info(VkFlags flags)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 
create_info(VkFlags flags)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 
create_info(VkQueryType type,uint32_t slot_count)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 
create_info()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 
subresource(VkImageAspectFlagBits aspect,uint32_t mip_level,uint32_t array_layer)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
subresource(const VkImageSubresourceRange & range,uint32_t mip_level,uint32_t array_layer)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 
subresource(VkImageAspectFlagBits aspect,uint32_t mip_level,uint32_t array_layer,uint32_t array_size)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 
image_aspect(VkImageAspectFlags flags)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
subresource(const VkImageSubresourceRange & range,uint32_t mip_level,uint32_t array_layer,uint32_t array_size)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
subresource_range(VkImageAspectFlags aspect_mask,uint32_t base_mip_level,uint32_t mip_levels,uint32_t base_array_layer,uint32_t num_layers)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
subresource_range(const VkImageCreateInfo & info,VkImageAspectFlags aspect_mask)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
subresource_range(const VkImageSubresource & subres)857 Image::subresource_range(const VkImageSubresource &subres) {
858     return subresource_range(subres.aspectMask, subres.mipLevel, 1,
859                              subres.arrayLayer, 1);
860 }
861 
extent(int32_t width,int32_t height)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 
extent(const VkExtent2D & extent,uint32_t mip_level)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 
extent(const VkExtent3D & extent)877 inline VkExtent2D Image::extent(const VkExtent3D &extent) {
878     return Image::extent(extent.width, extent.height);
879 }
880 
extent(int32_t width,int32_t height,int32_t depth)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 
extent(const VkExtent3D & extent,uint32_t mip_level)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 
create_info(size_t code_size,const uint32_t * code,VkFlags flags)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
write_descriptor_set(const DescriptorSet & set,uint32_t binding,uint32_t array_element,VkDescriptorType type,uint32_t count,const VkDescriptorImageInfo * image_info)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
write_descriptor_set(const DescriptorSet & set,uint32_t binding,uint32_t array_element,VkDescriptorType type,uint32_t count,const VkDescriptorBufferInfo * buffer_info)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
write_descriptor_set(const DescriptorSet & set,uint32_t binding,uint32_t array_element,VkDescriptorType type,uint32_t count,const VkBufferView * buffer_views)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 
write_descriptor_set(const DescriptorSet & set,uint32_t binding,uint32_t array_element,VkDescriptorType type,const std::vector<VkDescriptorImageInfo> & image_info)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 
write_descriptor_set(const DescriptorSet & set,uint32_t binding,uint32_t array_element,VkDescriptorType type,const std::vector<VkDescriptorBufferInfo> & buffer_info)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
write_descriptor_set(const DescriptorSet & set,uint32_t binding,uint32_t array_element,VkDescriptorType type,const std::vector<VkBufferView> & buffer_views)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
copy_descriptor_set(const DescriptorSet & src_set,uint32_t src_binding,uint32_t src_array_element,const DescriptorSet & dst_set,uint32_t dst_binding,uint32_t dst_array_element,uint32_t count)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
create_info(VkCommandPool const & pool)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