From ba98667c657aa9e84333564b3814d99e327ff7c1 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 13 Apr 2023 15:57:28 +0200 Subject: [PATCH] Examples: Vulkan: further work for device extensions + tentative use o fVK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME. (#6109, #6172, #6101) --- examples/example_glfw_vulkan/main.cpp | 89 +++++++++++++++------------ examples/example_sdl2_vulkan/main.cpp | 89 +++++++++++++++------------ 2 files changed, 100 insertions(+), 78 deletions(-) diff --git a/examples/example_glfw_vulkan/main.cpp b/examples/example_glfw_vulkan/main.cpp index d3213919c..43ac22f06 100644 --- a/examples/example_glfw_vulkan/main.cpp +++ b/examples/example_glfw_vulkan/main.cpp @@ -18,6 +18,7 @@ #define GLFW_INCLUDE_VULKAN #include #include +//#include // [Win32] Our example includes a copy of glfw3.lib pre-compiled with VS2010 to maximize ease of testing and compatibility with old VS compilers. // To link with VS2010-era libraries, VS2015+ requires linking with legacy_stdio_definitions.lib, which we do using this pragma. @@ -76,7 +77,32 @@ static bool IsExtensionAvailable(const ImVector& properti return false; } -static void SetupVulkan(ImVector extensions) +static VkPhysicalDevice SetupVulkan_SelectPhysicalDevice() +{ + uint32_t gpu_count; + VkResult err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, nullptr); + check_vk_result(err); + IM_ASSERT(gpu_count > 0); + + ImVector gpus; + gpus.resize(gpu_count); + err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, gpus.Data); + check_vk_result(err); + + // If a number >1 of GPUs got reported, find discrete GPU if present, or use first one available. This covers + // most common cases (multi-gpu/integrated+dedicated graphics). Handling more complicated setups (multiple + // dedicated GPUs) is out of scope of this sample. + for (VkPhysicalDevice& device : gpus) + { + VkPhysicalDeviceProperties properties; + vkGetPhysicalDeviceProperties(device, &properties); + if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) + return device; + } + return VK_NULL_HANDLE; +} + +static void SetupVulkan(ImVector instance_extensions) { VkResult err; @@ -95,11 +121,11 @@ static void SetupVulkan(ImVector extensions) // Enable required extensions if (IsExtensionAvailable(properties, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) - extensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); + instance_extensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); #ifdef VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME if (IsExtensionAvailable(properties, VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME)) { - extensions.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME); + instance_extensions.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME); create_info.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR; } #endif @@ -109,12 +135,12 @@ static void SetupVulkan(ImVector extensions) const char* layers[] = { "VK_LAYER_KHRONOS_validation" }; create_info.enabledLayerCount = 1; create_info.ppEnabledLayerNames = layers; - extensions.push_back("VK_EXT_debug_report"); + instance_extensions.push_back("VK_EXT_debug_report"); #endif // Create Vulkan Instance - create_info.enabledExtensionCount = (uint32_t)extensions.size(); - create_info.ppEnabledExtensionNames = extensions.Data; + create_info.enabledExtensionCount = (uint32_t)instance_extensions.Size; + create_info.ppEnabledExtensionNames = instance_extensions.Data; err = vkCreateInstance(&create_info, g_Allocator, &g_Instance); check_vk_result(err); @@ -132,35 +158,8 @@ static void SetupVulkan(ImVector extensions) #endif } - // Select GPU - { - uint32_t gpu_count; - err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, nullptr); - check_vk_result(err); - IM_ASSERT(gpu_count > 0); - - VkPhysicalDevice* gpus = (VkPhysicalDevice*)malloc(sizeof(VkPhysicalDevice) * gpu_count); - err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, gpus); - check_vk_result(err); - - // If a number >1 of GPUs got reported, find discrete GPU if present, or use first one available. This covers - // most common cases (multi-gpu/integrated+dedicated graphics). Handling more complicated setups (multiple - // dedicated GPUs) is out of scope of this sample. - int use_gpu = 0; - for (int i = 0; i < (int)gpu_count; i++) - { - VkPhysicalDeviceProperties properties; - vkGetPhysicalDeviceProperties(gpus[i], &properties); - if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) - { - use_gpu = i; - break; - } - } - - g_PhysicalDevice = gpus[use_gpu]; - free(gpus); - } + // Select Physical Device (GPU) + g_PhysicalDevice = SetupVulkan_SelectPhysicalDevice(); // Select graphics queue family { @@ -180,8 +179,20 @@ static void SetupVulkan(ImVector extensions) // Create Logical Device (with 1 queue) { - int device_extension_count = 1; - const char* device_extensions[] = { "VK_KHR_swapchain" }; + ImVector device_extensions; + device_extensions.push_back("VK_KHR_swapchain"); + + // Enumerate physical device extension + uint32_t properties_count; + ImVector properties; + vkEnumerateDeviceExtensionProperties(g_PhysicalDevice, nullptr, &properties_count, nullptr); + properties.resize(properties_count); + vkEnumerateDeviceExtensionProperties(g_PhysicalDevice, nullptr, &properties_count, properties.Data); +#ifdef VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME + if (IsExtensionAvailable(properties, VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME)) + device_extensions.push_back(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME); +#endif + const float queue_priority[] = { 1.0f }; VkDeviceQueueCreateInfo queue_info[1] = {}; queue_info[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; @@ -192,8 +203,8 @@ static void SetupVulkan(ImVector extensions) create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; create_info.queueCreateInfoCount = sizeof(queue_info) / sizeof(queue_info[0]); create_info.pQueueCreateInfos = queue_info; - create_info.enabledExtensionCount = device_extension_count; - create_info.ppEnabledExtensionNames = device_extensions; + create_info.enabledExtensionCount = (uint32_t)device_extensions.Size; + create_info.ppEnabledExtensionNames = device_extensions.Data; err = vkCreateDevice(g_PhysicalDevice, &create_info, g_Allocator, &g_Device); check_vk_result(err); vkGetDeviceQueue(g_Device, g_QueueFamily, 0, &g_Queue); diff --git a/examples/example_sdl2_vulkan/main.cpp b/examples/example_sdl2_vulkan/main.cpp index 7c782ebbc..db78acdf4 100644 --- a/examples/example_sdl2_vulkan/main.cpp +++ b/examples/example_sdl2_vulkan/main.cpp @@ -17,6 +17,7 @@ #include #include #include +//#include //#define IMGUI_UNLIMITED_FRAME_RATE #ifdef _DEBUG @@ -64,7 +65,32 @@ static bool IsExtensionAvailable(const ImVector& properti return false; } -static void SetupVulkan(ImVector extensions) +static VkPhysicalDevice SetupVulkan_SelectPhysicalDevice() +{ + uint32_t gpu_count; + VkResult err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, nullptr); + check_vk_result(err); + IM_ASSERT(gpu_count > 0); + + ImVector gpus; + gpus.resize(gpu_count); + err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, gpus.Data); + check_vk_result(err); + + // If a number >1 of GPUs got reported, find discrete GPU if present, or use first one available. This covers + // most common cases (multi-gpu/integrated+dedicated graphics). Handling more complicated setups (multiple + // dedicated GPUs) is out of scope of this sample. + for (VkPhysicalDevice& device : gpus) + { + VkPhysicalDeviceProperties properties; + vkGetPhysicalDeviceProperties(device, &properties); + if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) + return device; + } + return VK_NULL_HANDLE; +} + +static void SetupVulkan(ImVector instance_extensions) { VkResult err; @@ -83,11 +109,11 @@ static void SetupVulkan(ImVector extensions) // Enable required extensions if (IsExtensionAvailable(properties, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) - extensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); + instance_extensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); #ifdef VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME if (IsExtensionAvailable(properties, VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME)) { - extensions.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME); + instance_extensions.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME); create_info.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR; } #endif @@ -97,12 +123,12 @@ static void SetupVulkan(ImVector extensions) const char* layers[] = { "VK_LAYER_KHRONOS_validation" }; create_info.enabledLayerCount = 1; create_info.ppEnabledLayerNames = layers; - extensions.push_back("VK_EXT_debug_report"); + instance_extensions.push_back("VK_EXT_debug_report"); #endif // Create Vulkan Instance - create_info.enabledExtensionCount = (uint32_t)extensions.size(); - create_info.ppEnabledExtensionNames = extensions.Data; + create_info.enabledExtensionCount = (uint32_t)instance_extensions.Size; + create_info.ppEnabledExtensionNames = instance_extensions.Data; err = vkCreateInstance(&create_info, g_Allocator, &g_Instance); check_vk_result(err); @@ -120,35 +146,8 @@ static void SetupVulkan(ImVector extensions) #endif } - // Select GPU - { - uint32_t gpu_count; - err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, nullptr); - check_vk_result(err); - IM_ASSERT(gpu_count > 0); - - VkPhysicalDevice* gpus = (VkPhysicalDevice*)malloc(sizeof(VkPhysicalDevice) * gpu_count); - err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, gpus); - check_vk_result(err); - - // If a number >1 of GPUs got reported, find discrete GPU if present, or use first one available. This covers - // most common cases (multi-gpu/integrated+dedicated graphics). Handling more complicated setups (multiple - // dedicated GPUs) is out of scope of this sample. - int use_gpu = 0; - for (int i = 0; i < (int)gpu_count; i++) - { - VkPhysicalDeviceProperties properties; - vkGetPhysicalDeviceProperties(gpus[i], &properties); - if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) - { - use_gpu = i; - break; - } - } - - g_PhysicalDevice = gpus[use_gpu]; - free(gpus); - } + // Select Physical Device (GPU) + g_PhysicalDevice = SetupVulkan_SelectPhysicalDevice(); // Select graphics queue family { @@ -168,8 +167,20 @@ static void SetupVulkan(ImVector extensions) // Create Logical Device (with 1 queue) { - int device_extension_count = 1; - const char* device_extensions[] = { "VK_KHR_swapchain" }; + ImVector device_extensions; + device_extensions.push_back("VK_KHR_swapchain"); + + // Enumerate physical device extension + uint32_t properties_count; + ImVector properties; + vkEnumerateDeviceExtensionProperties(g_PhysicalDevice, nullptr, &properties_count, nullptr); + properties.resize(properties_count); + vkEnumerateDeviceExtensionProperties(g_PhysicalDevice, nullptr, &properties_count, properties.Data); +#ifdef VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME + if (IsExtensionAvailable(properties, VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME)) + device_extensions.push_back(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME); +#endif + const float queue_priority[] = { 1.0f }; VkDeviceQueueCreateInfo queue_info[1] = {}; queue_info[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; @@ -180,8 +191,8 @@ static void SetupVulkan(ImVector extensions) create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; create_info.queueCreateInfoCount = sizeof(queue_info) / sizeof(queue_info[0]); create_info.pQueueCreateInfos = queue_info; - create_info.enabledExtensionCount = device_extension_count; - create_info.ppEnabledExtensionNames = device_extensions; + create_info.enabledExtensionCount = (uint32_t)device_extensions.Size; + create_info.ppEnabledExtensionNames = device_extensions.Data; err = vkCreateDevice(g_PhysicalDevice, &create_info, g_Allocator, &g_Device); check_vk_result(err); vkGetDeviceQueue(g_Device, g_QueueFamily, 0, &g_Queue);