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 30namespace vk_testing { 31 32typedef void (*ErrorCallback)(const char *expr, const char *file, unsigned int line, const char *function); 33void set_error_callback(ErrorCallback callback); 34 35class PhysicalDevice; 36class Device; 37class Queue; 38class DeviceMemory; 39class Fence; 40class Semaphore; 41class Event; 42class QueryPool; 43class Buffer; 44class BufferView; 45class Image; 46class ImageView; 47class DepthStencilView; 48class Shader; 49class Pipeline; 50class PipelineDelta; 51class Sampler; 52class DescriptorSetLayout; 53class PipelineLayout; 54class DescriptorSetPool; 55class DescriptorSet; 56class CommandBuffer; 57class CommandPool; 58 59std::vector<VkLayerProperties> GetGlobalLayers(); 60std::vector<VkExtensionProperties> GetGlobalExtensions(); 61std::vector<VkExtensionProperties> GetGlobalExtensions(const char *pLayerName); 62 63namespace internal { 64 65template <typename T> class Handle { 66 public: 67 const T &handle() const { return handle_; } 68 bool initialized() const { return (handle_ != VK_NULL_HANDLE); } 69 70 protected: 71 typedef T handle_type; 72 73 explicit Handle() : handle_(VK_NULL_HANDLE) {} 74 explicit Handle(T handle) : handle_(handle) {} 75 76 void init(T handle) { 77 assert(!initialized()); 78 handle_ = handle; 79 } 80 81 private: 82 // handles are non-copyable 83 Handle(const Handle &); 84 Handle &operator=(const Handle &); 85 86 T handle_; 87}; 88 89template <typename T> class NonDispHandle : public Handle<T> { 90 protected: 91 explicit NonDispHandle() : Handle<T>(), dev_handle_(VK_NULL_HANDLE) {} 92 explicit NonDispHandle(VkDevice dev, T handle) : Handle<T>(handle), dev_handle_(dev) {} 93 94 const VkDevice &device() const { return dev_handle_; } 95 96 void init(VkDevice dev, T handle) { 97 assert(!Handle<T>::initialized() && dev_handle_ == VK_NULL_HANDLE); 98 Handle<T>::init(handle); 99 dev_handle_ = dev; 100 } 101 102 private: 103 VkDevice dev_handle_; 104}; 105 106} // namespace internal 107 108class PhysicalDevice : public internal::Handle<VkPhysicalDevice> { 109 public: 110 explicit PhysicalDevice(VkPhysicalDevice phy) : Handle(phy) { 111 memory_properties_ = memory_properties(); 112 device_properties_ = properties(); 113 } 114 115 VkPhysicalDeviceProperties properties() const; 116 VkPhysicalDeviceMemoryProperties memory_properties() const; 117 std::vector<VkQueueFamilyProperties> queue_properties() const; 118 VkPhysicalDeviceFeatures features() const; 119 120 bool set_memory_type(const uint32_t type_bits, VkMemoryAllocateInfo *info, const VkMemoryPropertyFlags properties, 121 const VkMemoryPropertyFlags forbid = 0) const; 122 123 // vkEnumerateDeviceExtensionProperties() 124 std::vector<VkExtensionProperties> extensions() const; 125 std::vector<VkExtensionProperties> extensions(const char *pLayerName) const; 126 127 // vkEnumerateLayers() 128 std::vector<VkLayerProperties> layers() const; 129 130 private: 131 void add_extension_dependencies(uint32_t dependency_count, VkExtensionProperties *depencency_props, 132 std::vector<VkExtensionProperties> &ext_list); 133 134 VkPhysicalDeviceMemoryProperties memory_properties_; 135 136 VkPhysicalDeviceProperties device_properties_; 137}; 138 139class Device : public internal::Handle<VkDevice> { 140 public: 141 explicit Device(VkPhysicalDevice phy) : phy_(phy) {} 142 ~Device(); 143 144 // vkCreateDevice() 145 void init(const VkDeviceCreateInfo &info); 146 void init(std::vector<const char *> &extensions, 147 VkPhysicalDeviceFeatures *features = nullptr); // all queues, all extensions, etc 148 void init() { 149 std::vector<const char *> extensions; 150 init(extensions); 151 }; 152 153 const PhysicalDevice &phy() const { return phy_; } 154 155 // vkGetDeviceProcAddr() 156 PFN_vkVoidFunction get_proc(const char *name) const { return vkGetDeviceProcAddr(handle(), name); } 157 158 // vkGetDeviceQueue() 159 const std::vector<Queue *> &graphics_queues() const { return queues_[GRAPHICS]; } 160 const std::vector<Queue *> &compute_queues() { return queues_[COMPUTE]; } 161 const std::vector<Queue *> &dma_queues() { return queues_[DMA]; } 162 uint32_t graphics_queue_node_index_; 163 164 struct Format { 165 VkFormat format; 166 VkImageTiling tiling; 167 VkFlags features; 168 }; 169 // vkGetFormatInfo() 170 VkFormatProperties format_properties(VkFormat format); 171 const std::vector<Format> &formats() const { return formats_; } 172 173 // vkDeviceWaitIdle() 174 void wait(); 175 176 // vkWaitForFences() 177 VkResult wait(const std::vector<const Fence *> &fences, bool wait_all, uint64_t timeout); 178 VkResult wait(const Fence &fence) { return wait(std::vector<const Fence *>(1, &fence), true, (uint64_t)-1); } 179 180 // vkUpdateDescriptorSets() 181 void update_descriptor_sets(const std::vector<VkWriteDescriptorSet> &writes, const std::vector<VkCopyDescriptorSet> &copies); 182 void update_descriptor_sets(const std::vector<VkWriteDescriptorSet> &writes) { 183 return update_descriptor_sets(writes, std::vector<VkCopyDescriptorSet>()); 184 } 185 186 static VkWriteDescriptorSet write_descriptor_set(const DescriptorSet &set, uint32_t binding, uint32_t array_element, 187 VkDescriptorType type, uint32_t count, 188 const VkDescriptorImageInfo *image_info); 189 static VkWriteDescriptorSet write_descriptor_set(const DescriptorSet &set, uint32_t binding, uint32_t array_element, 190 VkDescriptorType type, uint32_t count, 191 const VkDescriptorBufferInfo *buffer_info); 192 static VkWriteDescriptorSet write_descriptor_set(const DescriptorSet &set, uint32_t binding, uint32_t array_element, 193 VkDescriptorType type, uint32_t count, const VkBufferView *buffer_views); 194 static VkWriteDescriptorSet write_descriptor_set(const DescriptorSet &set, uint32_t binding, uint32_t array_element, 195 VkDescriptorType type, const std::vector<VkDescriptorImageInfo> &image_info); 196 static VkWriteDescriptorSet write_descriptor_set(const DescriptorSet &set, uint32_t binding, uint32_t array_element, 197 VkDescriptorType type, const std::vector<VkDescriptorBufferInfo> &buffer_info); 198 static VkWriteDescriptorSet write_descriptor_set(const DescriptorSet &set, uint32_t binding, uint32_t array_element, 199 VkDescriptorType type, const std::vector<VkBufferView> &buffer_views); 200 201 static VkCopyDescriptorSet copy_descriptor_set(const DescriptorSet &src_set, uint32_t src_binding, uint32_t src_array_element, 202 const DescriptorSet &dst_set, uint32_t dst_binding, uint32_t dst_array_element, 203 uint32_t count); 204 205 private: 206 enum QueueIndex { 207 GRAPHICS, 208 COMPUTE, 209 DMA, 210 QUEUE_COUNT, 211 }; 212 213 void init_queues(); 214 void init_formats(); 215 216 PhysicalDevice phy_; 217 218 std::vector<Queue *> queues_[QUEUE_COUNT]; 219 std::vector<Format> formats_; 220}; 221 222class Queue : public internal::Handle<VkQueue> { 223 public: 224 explicit Queue(VkQueue queue, int index) : Handle(queue) { family_index_ = index; } 225 226 // vkQueueSubmit() 227 void submit(const std::vector<const CommandBuffer *> &cmds, Fence &fence); 228 void submit(const CommandBuffer &cmd, Fence &fence); 229 void submit(const CommandBuffer &cmd); 230 231 // vkQueueWaitIdle() 232 void wait(); 233 234 int get_family_index() { return family_index_; } 235 236 private: 237 int family_index_; 238}; 239 240class DeviceMemory : public internal::NonDispHandle<VkDeviceMemory> { 241 public: 242 ~DeviceMemory(); 243 244 // vkAllocateMemory() 245 void init(const Device &dev, const VkMemoryAllocateInfo &info); 246 247 // vkMapMemory() 248 const void *map(VkFlags flags) const; 249 void *map(VkFlags flags); 250 const void *map() const { return map(0); } 251 void *map() { return map(0); } 252 253 // vkUnmapMemory() 254 void unmap() const; 255 256 static VkMemoryAllocateInfo alloc_info(VkDeviceSize size, uint32_t memory_type_index); 257}; 258 259class Fence : public internal::NonDispHandle<VkFence> { 260 public: 261 ~Fence(); 262 263 // vkCreateFence() 264 void init(const Device &dev, const VkFenceCreateInfo &info); 265 266 // vkGetFenceStatus() 267 VkResult status() const { return vkGetFenceStatus(device(), handle()); } 268 269 static VkFenceCreateInfo create_info(VkFenceCreateFlags flags); 270 static VkFenceCreateInfo create_info(); 271}; 272 273class 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 283class Event : public internal::NonDispHandle<VkEvent> { 284 public: 285 ~Event(); 286 287 // vkCreateEvent() 288 void init(const Device &dev, const VkEventCreateInfo &info); 289 290 // vkGetEventStatus() 291 // vkSetEvent() 292 // vkResetEvent() 293 VkResult status() const { return vkGetEventStatus(device(), handle()); } 294 void set(); 295 void reset(); 296 297 static VkEventCreateInfo create_info(VkFlags flags); 298}; 299 300class 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 313class Buffer : public internal::NonDispHandle<VkBuffer> { 314 public: 315 explicit Buffer() : NonDispHandle() {} 316 explicit Buffer(const Device &dev, const VkBufferCreateInfo &info) { init(dev, info); } 317 explicit Buffer(const Device &dev, VkDeviceSize size) { init(dev, size); } 318 319 ~Buffer(); 320 321 // vkCreateBuffer() 322 void init(const Device &dev, const VkBufferCreateInfo &info, VkMemoryPropertyFlags mem_props); 323 void init(const Device &dev, const VkBufferCreateInfo &info) { init(dev, info, 0); } 324 void init(const Device &dev, VkDeviceSize size, VkMemoryPropertyFlags mem_props) { init(dev, create_info(size, 0), mem_props); } 325 void init(const Device &dev, VkDeviceSize size) { init(dev, size, 0); } 326 void init_as_src(const Device &dev, VkDeviceSize size, VkMemoryPropertyFlags &reqs) { 327 init(dev, create_info(size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT), reqs); 328 } 329 void init_as_dst(const Device &dev, VkDeviceSize size, VkMemoryPropertyFlags &reqs) { 330 init(dev, create_info(size, VK_BUFFER_USAGE_TRANSFER_DST_BIT), reqs); 331 } 332 void init_as_src_and_dst(const Device &dev, VkDeviceSize size, VkMemoryPropertyFlags &reqs) { 333 init(dev, create_info(size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT), reqs); 334 } 335 void init_no_mem(const Device &dev, const VkBufferCreateInfo &info); 336 337 // get the internal memory 338 const DeviceMemory &memory() const { return internal_mem_; } 339 DeviceMemory &memory() { return internal_mem_; } 340 341 // vkGetObjectMemoryRequirements() 342 VkMemoryRequirements memory_requirements() const; 343 344 // vkBindObjectMemory() 345 void bind_memory(const DeviceMemory &mem, VkDeviceSize mem_offset); 346 347 static VkBufferCreateInfo create_info(VkDeviceSize size, VkFlags usage); 348 349 VkBufferMemoryBarrier buffer_memory_barrier(VkFlags output_mask, VkFlags input_mask, VkDeviceSize offset, 350 VkDeviceSize size) const { 351 VkBufferMemoryBarrier barrier = {}; 352 barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; 353 barrier.buffer = handle(); 354 barrier.srcAccessMask = output_mask; 355 barrier.dstAccessMask = input_mask; 356 barrier.offset = offset; 357 barrier.size = size; 358 return barrier; 359 } 360 361 private: 362 VkBufferCreateInfo create_info_; 363 364 DeviceMemory internal_mem_; 365}; 366 367class BufferView : public internal::NonDispHandle<VkBufferView> { 368 public: 369 ~BufferView(); 370 371 // vkCreateBufferView() 372 void init(const Device &dev, const VkBufferViewCreateInfo &info); 373}; 374 375class Image : public internal::NonDispHandle<VkImage> { 376 public: 377 explicit Image() : NonDispHandle(), format_features_(0) {} 378 explicit Image(const Device &dev, const VkImageCreateInfo &info) : format_features_(0) { init(dev, info); } 379 380 ~Image(); 381 382 // vkCreateImage() 383 void init(const Device &dev, const VkImageCreateInfo &info, VkMemoryPropertyFlags mem_props); 384 void init(const Device &dev, const VkImageCreateInfo &info) { init(dev, info, 0); } 385 void init_no_mem(const Device &dev, const VkImageCreateInfo &info); 386 387 // get the internal memory 388 const DeviceMemory &memory() const { return internal_mem_; } 389 DeviceMemory &memory() { return internal_mem_; } 390 391 // vkGetObjectMemoryRequirements() 392 VkMemoryRequirements memory_requirements() const; 393 394 // vkBindObjectMemory() 395 void bind_memory(const DeviceMemory &mem, VkDeviceSize mem_offset); 396 397 // vkGetImageSubresourceLayout() 398 VkSubresourceLayout subresource_layout(const VkImageSubresource &subres) const; 399 VkSubresourceLayout subresource_layout(const VkImageSubresourceLayers &subres) const; 400 401 bool transparent() const; 402 bool copyable() const { return (format_features_ & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT); } 403 404 VkImageSubresourceRange subresource_range(VkImageAspectFlagBits aspect) const { 405 return subresource_range(create_info_, aspect); 406 } 407 VkExtent3D extent() const { return create_info_.extent; } 408 VkExtent3D extent(uint32_t mip_level) const { return extent(create_info_.extent, mip_level); } 409 VkFormat format() const { return create_info_.format; } 410 411 VkImageMemoryBarrier image_memory_barrier(VkFlags output_mask, VkFlags input_mask, VkImageLayout old_layout, 412 VkImageLayout new_layout, const VkImageSubresourceRange &range) const { 413 VkImageMemoryBarrier barrier = {}; 414 barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; 415 barrier.srcAccessMask = output_mask; 416 barrier.dstAccessMask = input_mask; 417 barrier.oldLayout = old_layout; 418 barrier.newLayout = new_layout; 419 barrier.image = handle(); 420 barrier.subresourceRange = range; 421 return barrier; 422 } 423 424 static VkImageCreateInfo create_info(); 425 static VkImageSubresource subresource(VkImageAspectFlags aspect, uint32_t mip_level, uint32_t array_layer); 426 static VkImageSubresource subresource(const VkImageSubresourceRange &range, uint32_t mip_level, uint32_t array_layer); 427 static VkImageSubresourceLayers subresource(VkImageAspectFlags aspect, uint32_t mip_level, uint32_t array_layer, 428 uint32_t array_size); 429 static VkImageSubresourceLayers subresource(const VkImageSubresourceRange &range, uint32_t mip_level, uint32_t array_layer, 430 uint32_t array_size); 431 static VkImageSubresourceRange subresource_range(VkImageAspectFlags aspect_mask, uint32_t base_mip_level, uint32_t mip_levels, 432 uint32_t base_array_layer, uint32_t num_layers); 433 static VkImageSubresourceRange subresource_range(const VkImageCreateInfo &info, VkImageAspectFlags aspect_mask); 434 static VkImageSubresourceRange subresource_range(const VkImageSubresource &subres); 435 436 static VkExtent2D extent(int32_t width, int32_t height); 437 static VkExtent2D extent(const VkExtent2D &extent, uint32_t mip_level); 438 static VkExtent2D extent(const VkExtent3D &extent); 439 440 static VkExtent3D extent(int32_t width, int32_t height, int32_t depth); 441 static VkExtent3D extent(const VkExtent3D &extent, uint32_t mip_level); 442 443 private: 444 void init_info(const Device &dev, const VkImageCreateInfo &info); 445 446 VkImageCreateInfo create_info_; 447 VkFlags format_features_; 448 449 DeviceMemory internal_mem_; 450}; 451 452class ImageView : public internal::NonDispHandle<VkImageView> { 453 public: 454 ~ImageView(); 455 456 // vkCreateImageView() 457 void init(const Device &dev, const VkImageViewCreateInfo &info); 458}; 459 460class 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 471class 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 493class 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 501class Sampler : public internal::NonDispHandle<VkSampler> { 502 public: 503 ~Sampler(); 504 505 // vkCreateSampler() 506 void init(const Device &dev, const VkSamplerCreateInfo &info); 507}; 508 509class DescriptorSetLayout : public internal::NonDispHandle<VkDescriptorSetLayout> { 510 public: 511 ~DescriptorSetLayout(); 512 513 // vkCreateDescriptorSetLayout() 514 void init(const Device &dev, const VkDescriptorSetLayoutCreateInfo &info); 515}; 516 517class DescriptorPool : public internal::NonDispHandle<VkDescriptorPool> { 518 public: 519 ~DescriptorPool(); 520 521 // Descriptor sets allocated from this pool will need access to the original 522 // object 523 VkDescriptorPool GetObj() { return pool_; } 524 525 // vkCreateDescriptorPool() 526 void init(const Device &dev, const VkDescriptorPoolCreateInfo &info); 527 528 // vkResetDescriptorPool() 529 void reset(); 530 531 // vkFreeDescriptorSet() 532 void setDynamicUsage(bool isDynamic) { dynamic_usage_ = isDynamic; } 533 bool getDynamicUsage() { return dynamic_usage_; } 534 535 // vkAllocateDescriptorSets() 536 std::vector<DescriptorSet *> alloc_sets(const Device &dev, const std::vector<const DescriptorSetLayout *> &layouts); 537 std::vector<DescriptorSet *> alloc_sets(const Device &dev, const DescriptorSetLayout &layout, uint32_t count); 538 DescriptorSet *alloc_sets(const Device &dev, const DescriptorSetLayout &layout); 539 540 private: 541 VkDescriptorPool pool_; 542 543 // Track whether this pool's usage is VK_DESCRIPTOR_POOL_USAGE_DYNAMIC 544 bool dynamic_usage_; 545}; 546 547class DescriptorSet : public internal::NonDispHandle<VkDescriptorSet> { 548 public: 549 ~DescriptorSet(); 550 551 explicit DescriptorSet() : NonDispHandle() {} 552 explicit DescriptorSet(const Device &dev, DescriptorPool *pool, VkDescriptorSet set) : NonDispHandle(dev.handle(), set) { 553 containing_pool_ = pool; 554 } 555 556 private: 557 DescriptorPool *containing_pool_; 558}; 559 560class CommandPool : public internal::NonDispHandle<VkCommandPool> { 561 public: 562 ~CommandPool(); 563 564 explicit CommandPool() : NonDispHandle() {} 565 explicit CommandPool(const Device &dev, const VkCommandPoolCreateInfo &info) { init(dev, info); } 566 567 void init(const Device &dev, const VkCommandPoolCreateInfo &info); 568 569 static VkCommandPoolCreateInfo create_info(uint32_t queue_family_index); 570}; 571 572inline 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 580class CommandBuffer : public internal::Handle<VkCommandBuffer> { 581 public: 582 ~CommandBuffer(); 583 584 explicit CommandBuffer() : Handle() {} 585 explicit CommandBuffer(const Device &dev, const VkCommandBufferAllocateInfo &info) { init(dev, info); } 586 587 // vkAllocateCommandBuffers() 588 void init(const Device &dev, const VkCommandBufferAllocateInfo &info); 589 590 // vkBeginCommandBuffer() 591 void begin(const VkCommandBufferBeginInfo *info); 592 void begin(); 593 594 // vkEndCommandBuffer() 595 // vkResetCommandBuffer() 596 void end(); 597 void reset(VkCommandBufferResetFlags flags); 598 void reset() { reset(VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT); } 599 600 static VkCommandBufferAllocateInfo create_info(VkCommandPool const &pool); 601 602 private: 603 VkDevice dev_handle_; 604 VkCommandPool cmd_pool_; 605}; 606 607inline 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 615inline 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 623inline 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 630inline VkFenceCreateInfo Fence::create_info() { 631 VkFenceCreateInfo info = {}; 632 info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 633 return info; 634} 635 636inline 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 643inline 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 650inline 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 658inline 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 670inline 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 681inline 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 685inline 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 705inline 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 710inline 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 724inline VkImageSubresourceRange Image::subresource_range(const VkImageCreateInfo &info, VkImageAspectFlags aspect_mask) { 725 return subresource_range(aspect_mask, 0, info.mipLevels, 0, info.arrayLayers); 726} 727 728inline VkImageSubresourceRange Image::subresource_range(const VkImageSubresource &subres) { 729 return subresource_range(subres.aspectMask, subres.mipLevel, 1, subres.arrayLayer, 1); 730} 731 732inline 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 739inline 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 745inline VkExtent2D Image::extent(const VkExtent3D &extent) { return Image::extent(extent.width, extent.height); } 746 747inline 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 755inline 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 762inline 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 771inline 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 785inline 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 799inline 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 812inline 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 818inline 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 824inline 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 829inline 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 845inline 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