47#if HI_OPERATING_SYSTEM == HI_OS_WINDOWS
48 requiredExtensions = {VK_KHR_WIN32_SURFACE_EXTENSION_NAME};
50#error "Not Implemented"
53 applicationInfo = vk::ApplicationInfo(
54 get_application_name().c_str(),
55 VK_MAKE_VERSION(get_application_version().major, get_application_version().minor, get_application_version().patch),
56 get_library_name().c_str(),
57 VK_MAKE_VERSION(get_library_version().major, get_library_version().minor, get_library_version().patch),
63 requiredExtensions.
push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
66 requiredExtensions.
push_back(VK_KHR_SURFACE_EXTENSION_NAME);
69 requiredExtensions.
push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
72 if (!has_foundation_extensions(requiredExtensions)) {
73 throw gui_error(
"Vulkan instance does not have the required extensions");
76 auto instanceCreateInfo = vk::InstanceCreateInfo(vk::InstanceCreateFlags(), &applicationInfo);
77 instanceCreateInfo.setEnabledExtensionCount(narrow_cast<uint32_t>(requiredExtensions.
size()));
78 instanceCreateInfo.setPpEnabledExtensionNames(requiredExtensions.
data());
81 requiredFeatures.robustBufferAccess = VK_TRUE;
86 "VK_LAYER_KHRONOS_validation",
"VK_LAYER_KHRONOS_synchronization2"
90 requiredLayers = filter_available_layers(requested_layers);
93 instanceCreateInfo.setEnabledLayerCount(narrow_cast<uint32_t>(requiredLayers.
size()));
94 instanceCreateInfo.setPpEnabledLayerNames(requiredLayers.
data());
96 hi_log_info(
"Creating Vulkan instance.");
97 intrinsic = vk_create_instance_no_asan(instanceCreateInfo);
99#if (VK_HEADER_VERSION == 97)
100 _loader = vk::DispatchLoaderDynamic(intrinsic);
102 _loader = vk::DispatchLoaderDynamic(intrinsic, vkGetInstanceProcAddr);
106 debugUtilsMessager = intrinsic.createDebugUtilsMessengerEXT(
107 {vk::DebugUtilsMessengerCreateFlagsEXT(),
108 vk::DebugUtilsMessageSeverityFlagBitsEXT::eVerbose |
110 vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning | vk::DebugUtilsMessageSeverityFlagBitsEXT::eError,
111 vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral | vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation |
112 vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance,
113 debug_utils_message_callback,
128 void log_memory_usage() const noexcept
130 for (
auto const& device : devices) {
131 device->log_memory_usage();
140 auto const lock = std::scoped_lock(gfx_system_mutex);
143 gfx_device *best_device =
nullptr;
145 for (
auto const& device : devices) {
146 auto const score = device->score(surface);
147 if (score >= best_score) {
149 best_device = device.get();
153 if (best_score <= 0) {
154 hi_log_fatal(
"Could not find a graphics device suitable for presenting this window.");
159 vk::DispatchLoaderDynamic loader() const noexcept
165 void destroySurfaceKHR(vk::SurfaceKHR surface)
168 intrinsic.destroySurfaceKHR(surface);
176 vk::DispatchLoaderDynamic _loader;
178 vk::DebugUtilsMessengerEXT debugUtilsMessager;
180 void enumerate_devices() noexcept
182 auto const lock = std::scoped_lock(gfx_system_mutex);
184 if (not devices.
empty()) {
188 for (
auto physical_device : intrinsic.enumeratePhysicalDevices()) {
189 devices.
push_back(std::make_shared<gfx_device>(physical_device));
193 [[nodiscard]]
static VkBool32 debug_utils_message_callback(
194 VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
195 VkDebugUtilsMessageTypeFlagsEXT messageType,
196 const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData,
199 auto message = std::string_view(pCallbackData->pMessage);
201 if (messageSeverity == VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT) {
202 hi_log_info(
"Vulkan: {}", message);
204 }
else if (messageSeverity == VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) {
205 hi_log_warning(
"Vulkan: {}", message);
207 }
else if (messageSeverity == VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) {
208 if (message.starts_with(
"Failed to open dynamic library")) {
212 hi_log_warning(
"Vulkan: {}", pCallbackData->pMessage);
215 hi_log_error(
"Vulkan: {}", pCallbackData->pMessage);
225 for (
auto availableExtensionProperties : vk::enumerateInstanceExtensionProperties()) {
226 availableExtensions.insert(
std::string(availableExtensionProperties.extensionName.data()));
229 for (
auto requiredExtension : requiredExtensions) {
230 if (availableExtensions.count(requiredExtension) == 0) {
239 auto available_layers = vk::enumerateInstanceLayerProperties();
241 hi_log_info(
"Available vulkan layers:");
243 for (
auto const& available_layer : available_layers) {
246 auto const it =
std::find(
begin(requested_layers),
end(requested_layers), layer_name);
248 if (it !=
end(requested_layers)) {
251 hi_log_info(
" * {}", layer_name);
253 hi_log_info(
" {}", layer_name);
259 [[nodiscard]] hi_no_sanitize_address
static vk::Instance vk_create_instance_no_asan(vk::InstanceCreateInfo instance_create_info)
261 return vk::createInstance(instance_create_info);
gfx_device * find_best_device(gfx_surface const &surface)
Find the best device for a surface.
Definition gfx_surface_vulkan_intf.hpp:191
unfair_recursive_mutex gfx_system_mutex
Global mutex for GUI elements, like gfx_system, gfx_device, Windows and Widgets.
Definition gfx_system_globals.hpp:18
std::vector< const char * > requiredExtensions
List of extension that where requested when the instance was created.
Definition gfx_system_vulkan_intf.hpp:25
std::vector< const char * > requiredLayers
List of extension that where requested when the instance was created.
Definition gfx_system_vulkan_intf.hpp:28