1 // 2 // Copyright (c) 2022 The Khronos Group Inc. 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 #ifndef _vulkan_wrapper_hpp_ 18 #define _vulkan_wrapper_hpp_ 19 20 #include <vulkan/vulkan.h> 21 #include "vulkan_wrapper_types.hpp" 22 #include "vulkan_list_map.hpp" 23 #include "vulkan_api_list.hpp" 24 25 class VulkanInstance { 26 friend const VulkanInstance &getVulkanInstance(); 27 28 protected: 29 VkInstance m_vkInstance; 30 VulkanPhysicalDeviceList m_physicalDeviceList; 31 32 VulkanInstance(); 33 VulkanInstance(const VulkanInstance &); 34 virtual ~VulkanInstance(); 35 36 public: 37 const VulkanPhysicalDeviceList &getPhysicalDeviceList() const; 38 operator VkInstance() const; 39 }; 40 41 class VulkanPhysicalDevice { 42 friend class VulkanInstance; 43 44 protected: 45 VkPhysicalDevice m_vkPhysicalDevice; 46 VkPhysicalDeviceProperties m_vkPhysicalDeviceProperties; 47 uint8_t m_vkDeviceUUID[VK_UUID_SIZE]; 48 uint8_t m_vkDeviceLUID[VK_LUID_SIZE]; 49 uint32_t m_vkDeviceNodeMask; 50 VkPhysicalDeviceFeatures m_vkPhysicalDeviceFeatures; 51 VkPhysicalDeviceMemoryProperties m_vkPhysicalDeviceMemoryProperties; 52 VulkanQueueFamilyList m_queueFamilyList; 53 VulkanMemoryHeapList m_memoryHeapList; 54 VulkanMemoryTypeList m_memoryTypeList; 55 56 VulkanPhysicalDevice(const VulkanPhysicalDevice &physicalDevice); 57 VulkanPhysicalDevice(VkPhysicalDevice vkPhysicalDevice); 58 virtual ~VulkanPhysicalDevice(); 59 60 public: 61 const VulkanQueueFamilyList &getQueueFamilyList() const; 62 const VulkanMemoryHeapList &getMemoryHeapList() const; 63 const VulkanMemoryTypeList &getMemoryTypeList() const; 64 const uint8_t *getUUID() const; 65 const uint8_t *getLUID() const; 66 uint32_t getNodeMask() const; 67 operator VkPhysicalDevice() const; 68 }; 69 70 class VulkanMemoryHeap { 71 friend class VulkanPhysicalDevice; 72 73 protected: 74 uint32_t m_memoryHeapIndex; 75 uint64_t m_size; 76 VulkanMemoryHeapFlag m_memoryHeapFlag; 77 78 VulkanMemoryHeap(const VulkanMemoryHeap &memoryHeap); 79 VulkanMemoryHeap(uint32_t m_memoryHeapIndex, uint64_t m_size, 80 VulkanMemoryHeapFlag m_memoryHeapFlag); 81 virtual ~VulkanMemoryHeap(); 82 83 public: 84 uint64_t getSize() const; 85 VulkanMemoryHeapFlag getMemoryHeapFlag() const; 86 operator uint32_t() const; 87 }; 88 89 class VulkanMemoryType { 90 friend class VulkanPhysicalDevice; 91 92 protected: 93 uint32_t m_memoryTypeIndex; 94 const VulkanMemoryTypeProperty m_memoryTypeProperty; 95 const VulkanMemoryHeap &m_memoryHeap; 96 97 VulkanMemoryType(const VulkanMemoryType &memoryType); 98 VulkanMemoryType(uint32_t memoryTypeIndex, 99 VulkanMemoryTypeProperty memoryTypeProperty, 100 const VulkanMemoryHeap &memoryHeap); 101 virtual ~VulkanMemoryType(); 102 103 public: 104 VulkanMemoryTypeProperty getMemoryTypeProperty() const; 105 const VulkanMemoryHeap &getMemoryHeap() const; 106 operator uint32_t() const; 107 }; 108 109 class VulkanQueueFamily { 110 friend class VulkanPhysicalDevice; 111 112 protected: 113 uint32_t m_queueFamilyIndex; 114 VkQueueFamilyProperties m_vkQueueFamilyProperties; 115 116 VulkanQueueFamily(const VulkanQueueFamily &queueFamily); 117 VulkanQueueFamily(uint32_t queueFamilyIndex, 118 VkQueueFamilyProperties vkQueueFamilyProperties); 119 virtual ~VulkanQueueFamily(); 120 121 public: 122 uint32_t getQueueFlags() const; 123 uint32_t getQueueCount() const; 124 operator uint32_t() const; 125 }; 126 127 class VulkanDevice { 128 protected: 129 const VulkanPhysicalDevice &m_physicalDevice; 130 VkDevice m_vkDevice; 131 VulkanQueueFamilyToQueueListMap m_queueFamilyIndexToQueueListMap; 132 133 VulkanDevice(const VulkanDevice &device); 134 135 public: 136 VulkanDevice( 137 const VulkanPhysicalDevice &physicalDevice = getVulkanPhysicalDevice(), 138 const VulkanQueueFamilyToQueueCountMap &queueFamilyToQueueCountMap = 139 getDefaultVulkanQueueFamilyToQueueCountMap()); 140 virtual ~VulkanDevice(); 141 const VulkanPhysicalDevice &getPhysicalDevice() const; 142 VulkanQueue & 143 getQueue(const VulkanQueueFamily &queueFamily = getVulkanQueueFamily(), 144 uint32_t queueIndex = 0); 145 operator VkDevice() const; 146 }; 147 148 class VulkanQueue { 149 friend class VulkanDevice; 150 151 protected: 152 VkQueue m_vkQueue; 153 154 VulkanQueue(VkQueue vkQueue); 155 VulkanQueue(const VulkanQueue &queue); 156 virtual ~VulkanQueue(); 157 158 public: 159 const VulkanQueueFamily &getQueueFamily(); 160 void submit(const VulkanSemaphoreList &waitSemaphoreList, 161 const VulkanCommandBufferList &commandBufferList, 162 const VulkanSemaphoreList &signalSemaphoreList); 163 void submit(const VulkanSemaphore &waitSemaphore, 164 const VulkanCommandBuffer &commandBuffer, 165 const VulkanSemaphore &signalSemaphore); 166 void submit(const VulkanCommandBuffer &commandBuffer, 167 const VulkanSemaphore &signalSemaphore); 168 void submit(const VulkanCommandBuffer &commandBuffer); 169 void waitIdle(); 170 operator VkQueue() const; 171 }; 172 173 class VulkanDescriptorSetLayoutBinding { 174 protected: 175 VkDescriptorSetLayoutBinding m_vkDescriptorSetLayoutBinding; 176 177 VulkanDescriptorSetLayoutBinding( 178 const VulkanDescriptorSetLayoutBinding &descriptorSetLayoutBinding); 179 180 public: 181 VulkanDescriptorSetLayoutBinding( 182 uint32_t binding, VulkanDescriptorType descriptorType, 183 uint32_t descriptorCount = 1, 184 VulkanShaderStage shaderStage = VULKAN_SHADER_STAGE_COMPUTE); 185 virtual ~VulkanDescriptorSetLayoutBinding(); 186 operator VkDescriptorSetLayoutBinding() const; 187 }; 188 189 class VulkanDescriptorSetLayout { 190 protected: 191 const VulkanDevice &m_device; 192 VkDescriptorSetLayout m_vkDescriptorSetLayout; 193 194 VulkanDescriptorSetLayout( 195 const VulkanDescriptorSetLayout &descriptorSetLayout); 196 void 197 VulkanDescriptorSetLayoutCommon(const VulkanDescriptorSetLayoutBindingList 198 &descriptorSetLayoutBindingList); 199 200 public: 201 VulkanDescriptorSetLayout( 202 const VulkanDevice &device, 203 const VulkanDescriptorSetLayoutBinding &descriptorSetLayoutBinding); 204 VulkanDescriptorSetLayout( 205 const VulkanDevice &device, 206 const VulkanDescriptorSetLayoutBinding &descriptorSetLayoutBinding0, 207 const VulkanDescriptorSetLayoutBinding &descriptorSetLayoutBinding1); 208 VulkanDescriptorSetLayout(const VulkanDevice &device, 209 const VulkanDescriptorSetLayoutBindingList 210 &descriptorSetLayoutBindingList); 211 virtual ~VulkanDescriptorSetLayout(); 212 operator VkDescriptorSetLayout() const; 213 }; 214 215 class VulkanPipelineLayout { 216 protected: 217 const VulkanDevice &m_device; 218 VkPipelineLayout m_vkPipelineLayout; 219 220 VulkanPipelineLayout(const VulkanPipelineLayout &pipelineLayout); 221 void VulkanPipelineLayoutCommon( 222 const VulkanDescriptorSetLayoutList &descriptorSetLayoutList); 223 224 public: 225 VulkanPipelineLayout(const VulkanDevice &device, 226 const VulkanDescriptorSetLayout &descriptorSetLayout); 227 VulkanPipelineLayout( 228 const VulkanDevice &device, 229 const VulkanDescriptorSetLayoutList &descriptorSetLayoutList = 230 getEmptyVulkanDescriptorSetLayoutList()); 231 virtual ~VulkanPipelineLayout(); 232 operator VkPipelineLayout() const; 233 }; 234 235 class VulkanShaderModule { 236 protected: 237 const VulkanDevice &m_device; 238 VkShaderModule m_vkShaderModule; 239 240 VulkanShaderModule(const VulkanShaderModule &shaderModule); 241 242 public: 243 VulkanShaderModule(const VulkanDevice &device, 244 const std::vector<char> &code); 245 virtual ~VulkanShaderModule(); 246 operator VkShaderModule() const; 247 }; 248 249 class VulkanPipeline { 250 protected: 251 const VulkanDevice &m_device; 252 VkPipeline m_vkPipeline; 253 254 VulkanPipeline(const VulkanPipeline &pipeline); 255 256 public: 257 VulkanPipeline(const VulkanDevice &device); 258 virtual ~VulkanPipeline(); 259 virtual VulkanPipelineBindPoint getPipelineBindPoint() const = 0; 260 operator VkPipeline() const; 261 }; 262 263 class VulkanComputePipeline : public VulkanPipeline { 264 protected: 265 VulkanComputePipeline(const VulkanComputePipeline &computePipeline); 266 267 public: 268 VulkanComputePipeline(const VulkanDevice &device, 269 const VulkanPipelineLayout &pipelineLayout, 270 const VulkanShaderModule &shaderModule, 271 const std::string &entryFuncName = "main"); 272 virtual ~VulkanComputePipeline(); 273 VulkanPipelineBindPoint getPipelineBindPoint() const; 274 }; 275 276 class VulkanDescriptorPool { 277 protected: 278 const VulkanDevice &m_device; 279 VkDescriptorPool m_vkDescriptorPool; 280 281 VulkanDescriptorPool(const VulkanDescriptorPool &descriptorPool); 282 void VulkanDescriptorPoolCommon(const VulkanDescriptorSetLayoutBindingList 283 &descriptorSetLayoutBindingList); 284 285 public: 286 VulkanDescriptorPool( 287 const VulkanDevice &device, 288 const VulkanDescriptorSetLayoutBinding &descriptorSetLayoutBinding); 289 VulkanDescriptorPool( 290 const VulkanDevice &device, 291 const VulkanDescriptorSetLayoutBinding &descriptorSetLayoutBinding0, 292 const VulkanDescriptorSetLayoutBinding &descriptorSetLayoutBinding1); 293 VulkanDescriptorPool(const VulkanDevice &device, 294 const VulkanDescriptorSetLayoutBindingList 295 &descriptorSetLayoutBindingList); 296 virtual ~VulkanDescriptorPool(); 297 operator VkDescriptorPool() const; 298 }; 299 300 class VulkanDescriptorSet { 301 protected: 302 const VulkanDevice &m_device; 303 const VulkanDescriptorPool &m_descriptorPool; 304 VkDescriptorSet m_vkDescriptorSet; 305 306 VulkanDescriptorSet(const VulkanDescriptorSet &descriptorSet); 307 308 public: 309 VulkanDescriptorSet(const VulkanDevice &device, 310 const VulkanDescriptorPool &descriptorPool, 311 const VulkanDescriptorSetLayout &descriptorSetLayout); 312 virtual ~VulkanDescriptorSet(); 313 void update(uint32_t binding, const VulkanBuffer &buffer); 314 void update(uint32_t binding, const VulkanImageView &imageView); 315 operator VkDescriptorSet() const; 316 }; 317 318 class VulkanOffset3D { 319 protected: 320 VkOffset3D m_vkOffset3D; 321 322 public: 323 VulkanOffset3D(const VulkanOffset3D &extent3D); 324 VulkanOffset3D(uint32_t x = 0, uint32_t y = 0, uint32_t z = 0); 325 virtual ~VulkanOffset3D(); 326 uint32_t getX() const; 327 uint32_t getY() const; 328 uint32_t getZ() const; 329 operator VkOffset3D() const; 330 }; 331 332 class VulkanExtent3D { 333 protected: 334 VkExtent3D m_vkExtent3D; 335 336 public: 337 VulkanExtent3D(const VulkanExtent3D &extent3D); 338 VulkanExtent3D(uint32_t width, uint32_t height = 1, uint32_t depth = 1); 339 virtual ~VulkanExtent3D(); 340 uint32_t getWidth() const; 341 uint32_t getHeight() const; 342 uint32_t getDepth() const; 343 operator VkExtent3D() const; 344 }; 345 346 class VulkanCommandPool { 347 protected: 348 const VulkanDevice &m_device; 349 VkCommandPool m_vkCommandPool; 350 351 VulkanCommandPool(const VulkanCommandPool &commandPool); 352 353 public: 354 VulkanCommandPool( 355 const VulkanDevice &device, 356 const VulkanQueueFamily &queueFamily = getVulkanQueueFamily()); 357 virtual ~VulkanCommandPool(); 358 operator VkCommandPool() const; 359 }; 360 361 class VulkanCommandBuffer { 362 protected: 363 const VulkanDevice &m_device; 364 const VulkanCommandPool &m_commandPool; 365 VkCommandBuffer m_vkCommandBuffer; 366 367 VulkanCommandBuffer(const VulkanCommandBuffer &commandBuffer); 368 369 public: 370 VulkanCommandBuffer(const VulkanDevice &device, 371 const VulkanCommandPool &commandPool); 372 virtual ~VulkanCommandBuffer(); 373 void begin(); 374 void bindPipeline(const VulkanPipeline &pipeline); 375 void bindDescriptorSets(const VulkanPipeline &pipeline, 376 const VulkanPipelineLayout &pipelineLayout, 377 const VulkanDescriptorSet &descriptorSet); 378 void pipelineBarrier(const VulkanImage2DList &image2DList, 379 VulkanImageLayout oldImageLayout, 380 VulkanImageLayout newImageLayout); 381 void dispatch(uint32_t groupCountX, uint32_t groupCountY, 382 uint32_t groupCountZ); 383 void fillBuffer(const VulkanBuffer &buffer, uint32_t data, 384 uint64_t offset = 0, uint64_t size = VK_WHOLE_SIZE); 385 void updateBuffer(const VulkanBuffer &buffer, void *pdata, 386 uint64_t offset = 0, uint64_t size = VK_WHOLE_SIZE); 387 void copyBufferToImage(const VulkanBuffer &buffer, const VulkanImage &image, 388 VulkanImageLayout imageLayout = 389 VULKAN_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); 390 void copyBufferToImage(const VulkanBuffer &buffer, const VulkanImage &image, 391 uint64_t bufferOffset = 0, uint32_t mipLevel = 0, 392 uint32_t baseArrayLayer = 0, uint32_t layerCount = 1, 393 VulkanOffset3D offset3D = VulkanOffset3D(0, 0, 0), 394 VulkanExtent3D extent3D = VulkanExtent3D(0, 0, 0)); 395 void copyImageToBuffer(const VulkanImage &image, const VulkanBuffer &buffer, 396 uint64_t bufferOffset = 0, uint32_t mipLevel = 0, 397 uint32_t baseArrayLayer = 0, uint32_t layerCount = 1, 398 VulkanOffset3D offset3D = VulkanOffset3D(0, 0, 0), 399 VulkanExtent3D extent3D = VulkanExtent3D(0, 0, 0)); 400 void end(); 401 operator VkCommandBuffer() const; 402 }; 403 404 class VulkanBuffer { 405 protected: 406 const VulkanDevice &m_device; 407 VkBuffer m_vkBuffer; 408 uint64_t m_size; 409 uint64_t m_alignment; 410 VulkanMemoryTypeList m_memoryTypeList; 411 412 VulkanBuffer(const VulkanBuffer &buffer); 413 414 public: 415 VulkanBuffer(const VulkanDevice &device, uint64_t size, 416 VulkanExternalMemoryHandleType externalMemoryHandleType = 417 VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_NONE, 418 VulkanBufferUsage bufferUsage = 419 VULKAN_BUFFER_USAGE_STORAGE_BUFFER_TRANSFER_SRC_DST, 420 VulkanSharingMode sharingMode = VULKAN_SHARING_MODE_EXCLUSIVE, 421 const VulkanQueueFamilyList &queueFamilyList = 422 getEmptyVulkanQueueFamilyList()); 423 virtual ~VulkanBuffer(); 424 uint64_t getSize() const; 425 uint64_t getAlignment() const; 426 const VulkanMemoryTypeList &getMemoryTypeList() const; 427 operator VkBuffer() const; 428 }; 429 430 class VulkanImage { 431 protected: 432 const VulkanDevice &m_device; 433 const VulkanImageType m_imageType; 434 const VulkanExtent3D m_extent3D; 435 const VulkanFormat m_format; 436 const uint32_t m_numMipLevels; 437 const uint32_t m_numLayers; 438 VkImage m_vkImage; 439 uint64_t m_size; 440 uint64_t m_alignment; 441 VulkanMemoryTypeList m_memoryTypeList; 442 VkImageCreateInfo VulkanImageCreateInfo; 443 VulkanImage(const VulkanImage &image); 444 445 public: 446 VulkanImage( 447 const VulkanDevice &device, VulkanImageType imageType, 448 VulkanFormat format, const VulkanExtent3D &extent3D, 449 uint32_t numMipLevels = 1, uint32_t arrayLayers = 1, 450 VulkanExternalMemoryHandleType externalMemoryHandleType = 451 VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_NONE, 452 VulkanImageCreateFlag imageCreateFlags = VULKAN_IMAGE_CREATE_FLAG_NONE, 453 VulkanImageTiling imageTiling = VULKAN_IMAGE_TILING_OPTIMAL, 454 VulkanImageUsage imageUsage = 455 VULKAN_IMAGE_USAGE_SAMPLED_STORAGE_TRANSFER_SRC_DST, 456 VulkanSharingMode sharingMode = VULKAN_SHARING_MODE_EXCLUSIVE); 457 virtual ~VulkanImage(); 458 virtual VulkanExtent3D getExtent3D(uint32_t mipLevel = 0) const; 459 VulkanFormat getFormat() const; 460 uint32_t getNumMipLevels() const; 461 uint32_t getNumLayers() const; 462 uint64_t getSize() const; 463 uint64_t getAlignment() const; 464 const VulkanMemoryTypeList &getMemoryTypeList() const; 465 VkImageCreateInfo getVkImageCreateInfo() const; 466 operator VkImage() const; 467 }; 468 469 class VulkanImage2D : public VulkanImage { 470 protected: 471 VkImageView m_vkImageView; 472 473 VulkanImage2D(const VulkanImage2D &image2D); 474 475 public: 476 VulkanImage2D( 477 const VulkanDevice &device, VulkanFormat format, uint32_t width, 478 uint32_t height, uint32_t numMipLevels = 1, 479 VulkanExternalMemoryHandleType externalMemoryHandleType = 480 VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_NONE, 481 VulkanImageCreateFlag imageCreateFlag = VULKAN_IMAGE_CREATE_FLAG_NONE, 482 VulkanImageUsage imageUsage = 483 VULKAN_IMAGE_USAGE_SAMPLED_STORAGE_TRANSFER_SRC_DST, 484 VulkanSharingMode sharingMode = VULKAN_SHARING_MODE_EXCLUSIVE); 485 virtual ~VulkanImage2D(); 486 virtual VulkanExtent3D getExtent3D(uint32_t mipLevel = 0) const; 487 }; 488 489 class VulkanImageView { 490 protected: 491 const VulkanDevice &m_device; 492 VkImageView m_vkImageView; 493 494 VulkanImageView(const VulkanImageView &imageView); 495 496 public: 497 VulkanImageView(const VulkanDevice &device, const VulkanImage &image, 498 VulkanImageViewType imageViewType, 499 uint32_t baseMipLevel = 0, 500 uint32_t mipLevelCount = VULKAN_REMAINING_MIP_LEVELS, 501 uint32_t baseArrayLayer = 0, 502 uint32_t layerCount = VULKAN_REMAINING_ARRAY_LAYERS); 503 virtual ~VulkanImageView(); 504 operator VkImageView() const; 505 }; 506 507 class VulkanDeviceMemory { 508 protected: 509 const VulkanDevice &m_device; 510 VkDeviceMemory m_vkDeviceMemory; 511 uint64_t m_size; 512 bool m_isDedicated; 513 514 VulkanDeviceMemory(const VulkanDeviceMemory &deviceMemory); 515 516 public: 517 VulkanDeviceMemory(const VulkanDevice &device, uint64_t size, 518 const VulkanMemoryType &memoryType, 519 VulkanExternalMemoryHandleType externalMemoryHandleType = 520 VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_NONE, 521 const void *name = NULL); 522 VulkanDeviceMemory(const VulkanDevice &device, const VulkanImage &image, 523 const VulkanMemoryType &memoryType, 524 VulkanExternalMemoryHandleType externalMemoryHandleType = 525 VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_NONE, 526 const void *name = NULL); 527 virtual ~VulkanDeviceMemory(); 528 uint64_t getSize() const; 529 #ifdef _WIN32 530 HANDLE 531 getHandle(VulkanExternalMemoryHandleType externalMemoryHandleType) const; 532 #else 533 int 534 getHandle(VulkanExternalMemoryHandleType externalMemoryHandleType) const; 535 #endif 536 bool isDedicated() const; 537 void *map(size_t offset = 0, size_t size = VK_WHOLE_SIZE); 538 void unmap(); 539 void bindBuffer(const VulkanBuffer &buffer, uint64_t offset = 0); 540 void bindImage(const VulkanImage &image, uint64_t offset = 0); 541 operator VkDeviceMemory() const; 542 }; 543 544 class VulkanSemaphore { 545 friend class VulkanQueue; 546 547 protected: 548 const VulkanDevice &m_device; 549 VkSemaphore m_vkSemaphore; 550 const std::wstring m_name; 551 552 VulkanSemaphore(const VulkanSemaphore &semaphore); 553 554 public: 555 VulkanSemaphore( 556 const VulkanDevice &device, 557 VulkanExternalSemaphoreHandleType externalSemaphoreHandleType = 558 VULKAN_EXTERNAL_SEMAPHORE_HANDLE_TYPE_NONE, 559 const std::wstring name = L""); 560 virtual ~VulkanSemaphore(); 561 #ifdef _WIN32 562 HANDLE getHandle( 563 VulkanExternalSemaphoreHandleType externalSemaphoreHandleType) const; 564 #else 565 int getHandle( 566 VulkanExternalSemaphoreHandleType externalSemaphoreHandleType) const; 567 #endif 568 const std::wstring &getName() const; 569 operator VkSemaphore() const; 570 }; 571 572 573 #define VK_FUNC_DECL(name) extern "C" PFN_##name _##name; 574 VK_FUNC_LIST 575 #if defined(_WIN32) || defined(_WIN64) 576 VK_WINDOWS_FUNC_LIST 577 #endif 578 #undef VK_FUNC_DECL 579 580 #endif // _vulkan_wrapper_hpp_ 581