VKWVulkanWindowProfile.h 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. #ifndef VKW_VULKAN_WINDOW_PROFILE_H
  2. #define VKW_VULKAN_WINDOW_PROFILE_H
  3. #include "vulkan_include.h"
  4. #include <vulkan/vulkan_profiles.hpp>
  5. #include <vector>
  6. #include <string>
  7. #include "VKWVulkanWindow.h"
  8. namespace vkw
  9. {
  10. struct CombinedFeatures : VkPhysicalDeviceFeatures,
  11. VkPhysicalDeviceVulkan11Features,
  12. VkPhysicalDeviceVulkan12Features,
  13. VkPhysicalDeviceVulkan13Features
  14. {
  15. };
  16. class VKWVulkanWindowProfile : public VKWVulkanWindow
  17. {
  18. public:
  19. void createProfileInstance(VpProfileProperties const & props,
  20. std::vector<std::string> const & additionalExtensions,
  21. std::vector<std::string> const & layers)
  22. {
  23. VkBool32 profile_supported;
  24. vpGetInstanceProfileSupport(nullptr, &props, &profile_supported);
  25. if (!profile_supported)
  26. {
  27. exit(1);
  28. }
  29. std::vector<char const*> enabled_layers;
  30. std::vector<char const*> enabled_extensions;
  31. for(auto & x : additionalExtensions)
  32. enabled_extensions.push_back(x.data());
  33. for(auto & x : layers)
  34. enabled_layers.push_back(x.data());
  35. VkInstanceCreateInfo create_info{};
  36. create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
  37. create_info.ppEnabledExtensionNames = enabled_extensions.data();
  38. create_info.enabledExtensionCount = static_cast<uint32_t>(enabled_extensions.size());
  39. create_info.enabledLayerCount = static_cast<uint32_t>(enabled_layers.size());
  40. create_info.ppEnabledLayerNames = enabled_layers.data();
  41. VpInstanceCreateInfo instance_create_info{};
  42. instance_create_info.pProfile = &props;
  43. instance_create_info.pCreateInfo = &create_info;
  44. instance_create_info.flags = VP_INSTANCE_CREATE_MERGE_EXTENSIONS_BIT;
  45. VkInstance vulkan_instance = VK_NULL_HANDLE;
  46. auto result = vpCreateInstance(&instance_create_info, nullptr, &vulkan_instance);
  47. assert(result == VK_SUCCESS);
  48. setInstance(vulkan_instance);
  49. }
  50. void createProfileDevice(VkPhysicalDevice pd,
  51. VkSurfaceKHR surface,
  52. VpProfileProperties const & profile_properties,
  53. std::vector<std::string> const extraRequiredDeviceExtenstions = {},
  54. std::function<void(CombinedFeatures&)> useEnabledFeatures = {})
  55. {
  56. m_physicalDevice = pd;
  57. m_surface = surface;
  58. // Check if the profile is supported at device level
  59. VkBool32 profile_supported;
  60. vpGetPhysicalDeviceProfileSupport(getInstance(), pd, &profile_properties, &profile_supported);
  61. if (!profile_supported)
  62. {
  63. throw std::runtime_error{"The selected profile is not supported (error at creating the device)!"};
  64. }
  65. _selectQueueFamily();
  66. const float queue_priority[] = { 1.0f };
  67. std::vector<VkDeviceQueueCreateInfo> queueCreateInfos;
  68. std::set<uint32_t> uniqueQueueFamilies = { static_cast<uint32_t>(m_graphicsQueueIndex), static_cast<uint32_t>(m_presentQueueIndex) };
  69. float queuePriority = queue_priority[0];
  70. for(auto queueFamily : uniqueQueueFamilies)
  71. {
  72. VkDeviceQueueCreateInfo queueCreateInfo = {};
  73. queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
  74. queueCreateInfo.queueFamilyIndex = queueFamily;
  75. queueCreateInfo.queueCount = 1;
  76. queueCreateInfo.pQueuePriorities = &queuePriority;
  77. queueCreateInfos.push_back(queueCreateInfo);
  78. }
  79. std::vector<const char*> deviceExtensions;
  80. for(auto & x : extraRequiredDeviceExtenstions)
  81. {
  82. deviceExtensions.push_back(x.data());
  83. }
  84. VkDeviceCreateInfo create_info{VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO};
  85. create_info.pNext = nullptr;
  86. create_info.pQueueCreateInfos = queueCreateInfos.data();
  87. create_info.queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfos.size());
  88. create_info.pEnabledFeatures = nullptr;
  89. create_info.enabledExtensionCount = static_cast<uint32_t>(deviceExtensions.size());
  90. create_info.ppEnabledExtensionNames = deviceExtensions.data();
  91. //==============================================================================
  92. // This section grabs all the device features which are enabled by the
  93. // profile and passes them to the user
  94. // suplied function so additional features can be turned on
  95. //==============================================================================
  96. CombinedFeatures userOverrideFeatures = {};
  97. VkPhysicalDeviceFeatures2 vulkan10Features = {};
  98. VkPhysicalDeviceVulkan11Features & vulkan11Features = userOverrideFeatures;//{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES };
  99. VkPhysicalDeviceVulkan12Features & vulkan12Features = userOverrideFeatures;//{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES };
  100. VkPhysicalDeviceVulkan13Features & vulkan13Features = userOverrideFeatures;//{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES };
  101. vulkan10Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
  102. vulkan11Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES;
  103. vulkan12Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES;
  104. vulkan13Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES;
  105. // We pre-populate the structures with the feature data of the profile
  106. // by passing all structures as a pNext chain to vpGetProfileFeatures
  107. vulkan11Features.pNext = &vulkan12Features;
  108. vulkan12Features.pNext = &vulkan13Features;
  109. vulkan13Features.pNext = &vulkan10Features;
  110. vpGetProfileFeatures(&profile_properties, &vulkan11Features);
  111. VkPhysicalDeviceFeatures & feat0 = userOverrideFeatures;
  112. feat0 = vulkan10Features.features; // copy them from the DeviceFeatures2 struct
  113. if(useEnabledFeatures)
  114. {
  115. useEnabledFeatures(userOverrideFeatures);
  116. vulkan10Features.features = feat0;
  117. }
  118. //==============================================================================
  119. // Create the device using the profile tool library
  120. VpDeviceCreateInfo deviceCreateInfo{};
  121. deviceCreateInfo.pCreateInfo = &create_info;
  122. deviceCreateInfo.pProfile = &profile_properties;
  123. deviceCreateInfo.flags = VP_DEVICE_CREATE_MERGE_EXTENSIONS_BIT | VP_DEVICE_CREATE_OVERRIDE_FEATURES_BIT;
  124. create_info.pNext = &vulkan11Features;
  125. VkDevice vulkan_device;
  126. VkResult result = vpCreateDevice(pd, &deviceCreateInfo, nullptr, &vulkan_device);
  127. assert(result == VK_SUCCESS);
  128. m_device = vulkan_device;
  129. vkGetDeviceQueue(m_device, static_cast<uint32_t>(m_graphicsQueueIndex), 0, &m_graphicsQueue);
  130. vkGetDeviceQueue(m_device, static_cast<uint32_t>(m_presentQueueIndex ), 0, &m_presentQueue);
  131. }
  132. void setDebugCallback(PFN_vkDebugReportCallbackEXT callbackfunc)
  133. {
  134. if( m_debugCallback )
  135. {
  136. auto func = reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>(vkGetInstanceProcAddr(m_instance, "vkDestroyDebugReportCallbackEXT"));
  137. if (func != nullptr)
  138. {
  139. func(m_instance, m_debugCallback, nullptr);
  140. }
  141. m_debugCallback = nullptr;
  142. }
  143. if(!m_debugCallback)
  144. {
  145. m_debugCallback = _createDebug(callbackfunc);
  146. }
  147. }
  148. };
  149. }
  150. #endif