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@LunarG.com>
19 * Author: Cody Northrop <cody@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:
handle()67 const T &handle() const { return handle_; }
initialized()68 bool initialized() const { return (handle_ != VK_NULL_HANDLE); }
69
70 protected:
71 typedef T handle_type;
72
Handle()73 explicit Handle() : handle_(VK_NULL_HANDLE) {}
Handle(T handle)74 explicit Handle(T handle) : handle_(handle) {}
75
init(T handle)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:
NonDispHandle()91 explicit NonDispHandle() : Handle<T>(), dev_handle_(VK_NULL_HANDLE) {}
NonDispHandle(VkDevice dev,T handle)92 explicit NonDispHandle(VkDevice dev, T handle) : Handle<T>(handle), dev_handle_(dev) {}
93
device()94 const VkDevice &device() const { return dev_handle_; }
95
init(VkDevice dev,T handle)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:
PhysicalDevice(VkPhysicalDevice phy)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:
Device(VkPhysicalDevice phy)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
init()148 void init() {
149 std::vector<const char *> extensions;
150 init(extensions);
151 };
152
phy()153 const PhysicalDevice &phy() const { return phy_; }
154
155 // vkGetDeviceProcAddr()
get_proc(const char * name)156 PFN_vkVoidFunction get_proc(const char *name) const { return vkGetDeviceProcAddr(handle(), name); }
157
158 // vkGetDeviceQueue()
graphics_queues()159 const std::vector<Queue *> &graphics_queues() const { return queues_[GRAPHICS]; }
compute_queues()160 const std::vector<Queue *> &compute_queues() { return queues_[COMPUTE]; }
dma_queues()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);
formats()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);
wait(const Fence & fence)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);
update_descriptor_sets(const std::vector<VkWriteDescriptorSet> & writes)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:
Queue(VkQueue queue,int index)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
get_family_index()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);
map()250 const void *map() const { return map(0); }
map()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()
status()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()
status()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:
Buffer()315 explicit Buffer() : NonDispHandle() {}
Buffer(const Device & dev,const VkBufferCreateInfo & info)316 explicit Buffer(const Device &dev, const VkBufferCreateInfo &info) { init(dev, info); }
Buffer(const Device & dev,VkDeviceSize size)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);
init(const Device & dev,const VkBufferCreateInfo & info)323 void init(const Device &dev, const VkBufferCreateInfo &info) { init(dev, info, 0); }
init(const Device & dev,VkDeviceSize size,VkMemoryPropertyFlags mem_props)324 void init(const Device &dev, VkDeviceSize size, VkMemoryPropertyFlags mem_props) { init(dev, create_info(size, 0), mem_props); }
init(const Device & dev,VkDeviceSize size)325 void init(const Device &dev, VkDeviceSize size) { init(dev, size, 0); }
init_as_src(const Device & dev,VkDeviceSize size,VkMemoryPropertyFlags & reqs)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 }
init_as_dst(const Device & dev,VkDeviceSize size,VkMemoryPropertyFlags & reqs)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 }
init_as_src_and_dst(const Device & dev,VkDeviceSize size,VkMemoryPropertyFlags & reqs)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
memory()338 const DeviceMemory &memory() const { return internal_mem_; }
memory()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
buffer_memory_barrier(VkFlags output_mask,VkFlags input_mask,VkDeviceSize offset,VkDeviceSize size)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:
Image()377 explicit Image() : NonDispHandle(), format_features_(0) {}
Image(const Device & dev,const VkImageCreateInfo & info)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);
init(const Device & dev,const VkImageCreateInfo & info)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
memory()388 const DeviceMemory &memory() const { return internal_mem_; }
memory()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;
copyable()402 bool copyable() const { return (format_features_ & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT); }
403
subresource_range(VkImageAspectFlagBits aspect)404 VkImageSubresourceRange subresource_range(VkImageAspectFlagBits aspect) const {
405 return subresource_range(create_info_, aspect);
406 }
extent()407 VkExtent3D extent() const { return create_info_.extent; }
extent(uint32_t mip_level)408 VkExtent3D extent(uint32_t mip_level) const { return extent(create_info_.extent, mip_level); }
format()409 VkFormat format() const { return create_info_.format; }
410
image_memory_barrier(VkFlags output_mask,VkFlags input_mask,VkImageLayout old_layout,VkImageLayout new_layout,const VkImageSubresourceRange & range)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
GetObj()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()
setDynamicUsage(bool isDynamic)532 void setDynamicUsage(bool isDynamic) { dynamic_usage_ = isDynamic; }
getDynamicUsage()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
DescriptorSet()551 explicit DescriptorSet() : NonDispHandle() {}
DescriptorSet(const Device & dev,DescriptorPool * pool,VkDescriptorSet set)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
CommandPool()564 explicit CommandPool() : NonDispHandle() {}
CommandPool(const Device & dev,const VkCommandPoolCreateInfo & info)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
create_info(uint32_t queue_family_index)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
CommandBuffer()584 explicit CommandBuffer() : Handle() {}
CommandBuffer(const Device & dev,const VkCommandBufferAllocateInfo & info)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);
reset()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
alloc_info(VkDeviceSize size,uint32_t memory_type_index)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
create_info(VkDeviceSize size,VkFlags usage)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
create_info(VkFenceCreateFlags flags)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
create_info()630 inline VkFenceCreateInfo Fence::create_info() {
631 VkFenceCreateInfo info = {};
632 info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
633 return info;
634 }
635
create_info(VkFlags flags)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
create_info(VkFlags flags)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
create_info(VkQueryType type,uint32_t slot_count)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
create_info()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
subresource(VkImageAspectFlags aspect,uint32_t mip_level,uint32_t array_layer)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
subresource(const VkImageSubresourceRange & range,uint32_t mip_level,uint32_t array_layer)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
subresource(VkImageAspectFlags aspect,uint32_t mip_level,uint32_t array_layer,uint32_t array_size)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
subresource(const VkImageSubresourceRange & range,uint32_t mip_level,uint32_t array_layer,uint32_t array_size)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
subresource_range(VkImageAspectFlags aspect_mask,uint32_t base_mip_level,uint32_t mip_levels,uint32_t base_array_layer,uint32_t num_layers)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
subresource_range(const VkImageCreateInfo & info,VkImageAspectFlags aspect_mask)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
subresource_range(const VkImageSubresource & subres)728 inline VkImageSubresourceRange Image::subresource_range(const VkImageSubresource &subres) {
729 return subresource_range(subres.aspectMask, subres.mipLevel, 1, subres.arrayLayer, 1);
730 }
731
extent(int32_t width,int32_t height)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
extent(const VkExtent2D & extent,uint32_t mip_level)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
extent(const VkExtent3D & extent)745 inline VkExtent2D Image::extent(const VkExtent3D &extent) { return Image::extent(extent.width, extent.height); }
746
extent(int32_t width,int32_t height,int32_t depth)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
extent(const VkExtent3D & extent,uint32_t mip_level)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
create_info(size_t code_size,const uint32_t * code,VkFlags flags)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
write_descriptor_set(const DescriptorSet & set,uint32_t binding,uint32_t array_element,VkDescriptorType type,uint32_t count,const VkDescriptorImageInfo * image_info)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
write_descriptor_set(const DescriptorSet & set,uint32_t binding,uint32_t array_element,VkDescriptorType type,uint32_t count,const VkDescriptorBufferInfo * buffer_info)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
write_descriptor_set(const DescriptorSet & set,uint32_t binding,uint32_t array_element,VkDescriptorType type,uint32_t count,const VkBufferView * buffer_views)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
write_descriptor_set(const DescriptorSet & set,uint32_t binding,uint32_t array_element,VkDescriptorType type,const std::vector<VkDescriptorImageInfo> & image_info)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
write_descriptor_set(const DescriptorSet & set,uint32_t binding,uint32_t array_element,VkDescriptorType type,const std::vector<VkDescriptorBufferInfo> & buffer_info)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
write_descriptor_set(const DescriptorSet & set,uint32_t binding,uint32_t array_element,VkDescriptorType type,const std::vector<VkBufferView> & buffer_views)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
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)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
create_info(VkCommandPool const & pool)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