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