bool VulkanCommon::CreateInstance() { uint32_t extensions_count = 0; if( (vkEnumerateInstanceExtensionProperties( nullptr, &extensions_count, nullptr ) != VK_SUCCESS) || (extensions_count == 0) ) { std::cout << "Error occurred during instance extensions enumeration!" << std::endl; return false; } std::vector<VkExtensionProperties> available_extensions( extensions_count ); if( vkEnumerateInstanceExtensionProperties( nullptr, &extensions_count, &available_extensions[0] ) != VK_SUCCESS ) { std::cout << "Error occurred during instance extensions enumeration!" << std::endl; return false; } std::vector<const char*> extensions = { VK_KHR_SURFACE_EXTENSION_NAME, #if defined(VK_USE_PLATFORM_WIN32_KHR) VK_KHR_WIN32_SURFACE_EXTENSION_NAME #elif defined(VK_USE_PLATFORM_XCB_KHR) VK_KHR_XCB_SURFACE_EXTENSION_NAME #elif defined(VK_USE_PLATFORM_XLIB_KHR) VK_KHR_XLIB_SURFACE_EXTENSION_NAME #endif }; for( size_t i = 0; i < extensions.size(); ++i ) { if( !CheckExtensionAvailability( extensions[i], available_extensions ) ) { std::cout << "Could not find instance extension named \"" << extensions[i] << "\"!" << std::endl; return false; } } VkApplicationInfo application_info = { VK_STRUCTURE_TYPE_APPLICATION_INFO, // VkStructureType sType nullptr, // const void *pNext "API without Secrets: Introduction to Vulkan", // const char *pApplicationName VK_MAKE_VERSION( 1, 0, 0 ), // uint32_t applicationVersion "Vulkan Tutorial by Intel", // const char *pEngineName VK_MAKE_VERSION( 1, 0, 0 ), // uint32_t engineVersion VK_API_VERSION // uint32_t apiVersion }; VkInstanceCreateInfo instance_create_info = { VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // VkStructureType sType nullptr, // const void *pNext 0, // VkInstanceCreateFlags flags &application_info, // const VkApplicationInfo *pApplicationInfo 0, // uint32_t enabledLayerCount nullptr, // const char * const *ppEnabledLayerNames static_cast<uint32_t>(extensions.size()), // uint32_t enabledExtensionCount &extensions[0] // const char * const *ppEnabledExtensionNames }; if( vkCreateInstance( &instance_create_info, nullptr, &Vulkan.Instance ) != VK_SUCCESS ) { std::cout << "Could not create Vulkan instance!" << std::endl; return false; } return true; }
bool create_instance(const char *app_name) { uint32_t extensions_count = 0; VK_VERIFY (vkEnumerateInstanceExtensionProperties(nullptr, &extensions_count, nullptr)); VERIFY_LOG (extensions_count > 0, LOG_TYPE, "Error occurred during instance extensions enumeration!", ""); std::vector<VkExtensionProperties> available_extensions(extensions_count); VK_VERIFY (vkEnumerateInstanceExtensionProperties(nullptr, &extensions_count, &available_extensions[0])); std::vector<const char *> extensions = { VK_KHR_SURFACE_EXTENSION_NAME, #ifdef PLATFORM_WINDOWS VK_KHR_WIN32_SURFACE_EXTENSION_NAME #elif PLATFORM_LINUX VK_KHR_XCB_SURFACE_EXTENSION_NAME #endif }; for (size_t i = 0; i < extensions.size(); ++i) { VERIFY_LOG(utils::check_extension(extensions[i], available_extensions), LOG_TYPE, "Could not find instance extension named \"%s\"!", extensions[i]); } VkApplicationInfo application_info = { VK_STRUCTURE_TYPE_APPLICATION_INFO, // VkStructureType sType nullptr, // const void *pNext app_name, // const char *pApplicationName VK_MAKE_VERSION(0, 0, 1), // uint32_t applicationVersion "gladius", // const char *pEngineName VK_MAKE_VERSION(0, 0, 1), // uint32_t engineVersion VK_MAKE_VERSION(1, 0, 21) // uint32_t apiVersion }; VkInstanceCreateInfo instance_create_info = { VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // VkStructureType sType nullptr, // const void *pNext 0, // VkInstanceCreateFlags flags &application_info, // const VkApplicationInfo *pApplicationInfo 0, // uint32_t enabledLayerCount nullptr, // const char * const *ppEnabledLayerNames static_cast<uint32_t>(extensions.size()), // uint32_t enabledExtensionCount &extensions[0] // const char * const *ppEnabledExtensionNames }; VK_VERIFY(vkCreateInstance(&instance_create_info, nullptr, &(vk_globals::instance))); GET_INSTANCE_PROC_ADDR(vk_globals::instance, GetPhysicalDeviceSurfaceSupportKHR); GET_INSTANCE_PROC_ADDR(vk_globals::instance, GetPhysicalDeviceSurfaceFormatsKHR); return true; }
void vulkan_instance_check_extensions(const std::vector<const char*>& extensions) { uint32_t extensions_count = 0; Assert(vkEnumerateInstanceExtensionProperties(nullptr, &extensions_count, nullptr) == VK_SUCCESS); Assert(extensions_count > 0); std::vector<VkExtensionProperties> available_extensions(extensions_count); Assert(vkEnumerateInstanceExtensionProperties(nullptr, &extensions_count, &available_extensions[0]) == VK_SUCCESS); for (size_t i = 0; i < extensions.size(); ++i) { bool found = false; for (size_t j = 0; j < available_extensions.size(); ++j) { if (std::strcmp(available_extensions[j].extensionName, extensions[i]) == 0) found = true; } Assert(found, fmt::format("vulkan: extension '{}' not supported by the instance", extensions[i])); } }
bool check_physical_device_properties(VkPhysicalDevice physical_device, uint32_t &selected_graphics_queue_family_index, uint32_t &selected_present_queue_family_index, const std::vector<const char *> &device_extensions) { uint32_t extensions_count = 0; if ((vkEnumerateDeviceExtensionProperties(physical_device, nullptr, &extensions_count, nullptr) != VK_SUCCESS) || (extensions_count == 0)) { SET_ERROR (LOG_TYPE, "Error occurred during physical device %d extensions enumeration!", physical_device); return false; } std::vector<VkExtensionProperties> available_extensions(extensions_count); if (vkEnumerateDeviceExtensionProperties(physical_device, nullptr, &extensions_count, &available_extensions[0]) != VK_SUCCESS) { SET_ERROR (LOG_TYPE, "Error occurred during physical device %d extensions enumeration!", physical_device); return false; } for (size_t i = 0; i < device_extensions.size(); ++i) { if (!utils::check_extension(device_extensions[i], available_extensions)) { SET_ERROR (LOG_TYPE, "Physical device %d doesn't support extension named \"%s\"!", physical_device, device_extensions[i]); return false; } } VkPhysicalDeviceProperties device_properties; VkPhysicalDeviceFeatures device_features; vkGetPhysicalDeviceProperties(physical_device, &device_properties); vkGetPhysicalDeviceFeatures(physical_device, &device_features); uint32_t major_version = VK_VERSION_MAJOR(device_properties.apiVersion); if ((major_version < 1) && (device_properties.limits.maxImageDimension2D < 4096)) { SET_ERROR (LOG_TYPE, "Physical device %d doesn't support required parameters!", physical_device); return false; } uint32_t queue_families_count = 0; vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_families_count, nullptr); if (queue_families_count == 0) { SET_ERROR (LOG_TYPE, "Physical device %d doesn't have any handle families!", physical_device); return false; } std::vector<VkQueueFamilyProperties> queue_family_properties(queue_families_count); std::vector<VkBool32> queue_present_support(queue_families_count); vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_families_count, &queue_family_properties[0]); uint32_t graphics_queue_family_index = UINT32_MAX; uint32_t present_queue_family_index = UINT32_MAX; for (uint32_t i = 0; i < queue_families_count; ++i) { vkGetPhysicalDeviceSurfaceSupportKHR(physical_device, i, vk_globals::surface, &queue_present_support[i]); if ((queue_family_properties[i].queueCount > 0) && (queue_family_properties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)) { // Select first handle that supports graphics if (graphics_queue_family_index == UINT32_MAX) { graphics_queue_family_index = i; } // If there is handle that supports both graphics and present - prefer it if (queue_present_support[i]) { selected_graphics_queue_family_index = i; selected_present_queue_family_index = i; return true; } } } // We don't have handle that supports both graphics and present so we have to use separate queues for (uint32_t i = 0; i < queue_families_count; ++i) { if (queue_present_support[i]) { present_queue_family_index = i; break; } } // If this device doesn't support queues with graphics and present capabilities don't use it if ((graphics_queue_family_index == UINT32_MAX) || (present_queue_family_index == UINT32_MAX)) { SET_ERROR (LOG_TYPE, "Could not find handle families with required properties on physical device %d!", physical_device); return false; } selected_graphics_queue_family_index = graphics_queue_family_index; selected_present_queue_family_index = present_queue_family_index; return true; }
bool VulkanCommon::CheckPhysicalDeviceProperties( VkPhysicalDevice physical_device, uint32_t &selected_graphics_queue_family_index, uint32_t &selected_present_queue_family_index ) { uint32_t extensions_count = 0; if( (vkEnumerateDeviceExtensionProperties( physical_device, nullptr, &extensions_count, nullptr ) != VK_SUCCESS) || (extensions_count == 0) ) { std::cout << "Error occurred during physical device " << physical_device << " extensions enumeration!" << std::endl; return false; } std::vector<VkExtensionProperties> available_extensions( extensions_count ); if( vkEnumerateDeviceExtensionProperties( physical_device, nullptr, &extensions_count, &available_extensions[0] ) != VK_SUCCESS ) { std::cout << "Error occurred during physical device " << physical_device << " extensions enumeration!" << std::endl; return false; } std::vector<const char*> device_extensions = { VK_KHR_SWAPCHAIN_EXTENSION_NAME }; for( size_t i = 0; i < device_extensions.size(); ++i ) { if( !CheckExtensionAvailability( device_extensions[i], available_extensions ) ) { std::cout << "Physical device " << physical_device << " doesn't support extension named \"" << device_extensions[i] << "\"!" << std::endl; return false; } } VkPhysicalDeviceProperties device_properties; VkPhysicalDeviceFeatures device_features; vkGetPhysicalDeviceProperties( physical_device, &device_properties ); vkGetPhysicalDeviceFeatures( physical_device, &device_features ); uint32_t major_version = VK_VERSION_MAJOR( device_properties.apiVersion ); if( (major_version < 1) && (device_properties.limits.maxImageDimension2D < 4096) ) { std::cout << "Physical device " << physical_device << " doesn't support required parameters!" << std::endl; return false; } uint32_t queue_families_count = 0; vkGetPhysicalDeviceQueueFamilyProperties( physical_device, &queue_families_count, nullptr ); if( queue_families_count == 0 ) { std::cout << "Physical device " << physical_device << " doesn't have any queue families!" << std::endl; return false; } std::vector<VkQueueFamilyProperties> queue_family_properties( queue_families_count ); std::vector<VkBool32> queue_present_support( queue_families_count ); vkGetPhysicalDeviceQueueFamilyProperties( physical_device, &queue_families_count, &queue_family_properties[0] ); uint32_t graphics_queue_family_index = UINT32_MAX; uint32_t present_queue_family_index = UINT32_MAX; for( uint32_t i = 0; i < queue_families_count; ++i ) { vkGetPhysicalDeviceSurfaceSupportKHR( physical_device, i, Vulkan.PresentationSurface, &queue_present_support[i] ); if( (queue_family_properties[i].queueCount > 0) && (queue_family_properties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) ) { // Select first queue that supports graphics if( graphics_queue_family_index == UINT32_MAX ) { graphics_queue_family_index = i; } // If there is queue that supports both graphics and present - prefer it if( queue_present_support[i] ) { selected_graphics_queue_family_index = i; selected_present_queue_family_index = i; return true; } } } // We don't have queue that supports both graphics and present so we have to use separate queues for( uint32_t i = 0; i < queue_families_count; ++i ) { if( queue_present_support[i] ) { present_queue_family_index = i; break; } } // If this device doesn't support queues with graphics and present capabilities don't use it if( (graphics_queue_family_index == UINT32_MAX) || (present_queue_family_index == UINT32_MAX) ) { std::cout << "Could not find queue families with required properties on physical device " << physical_device << "!" << std::endl; return false; } selected_graphics_queue_family_index = graphics_queue_family_index; selected_present_queue_family_index = present_queue_family_index; return true; }