VKWVulkanWindowProfile.h 7.7 KB

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