From 84b65492bc6477ad7485e36f81bc06a7083e1e11 Mon Sep 17 00:00:00 2001 From: Water Chika Date: Tue, 5 Nov 2024 07:35:45 +0000 Subject: [PATCH 1/4] vkcube: Check if gpu support the surface --- cube/cube.c | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/cube/cube.c b/cube/cube.c index 255eb5bb2..0f7243643 100644 --- a/cube/cube.c +++ b/cube/cube.c @@ -4143,7 +4143,10 @@ static void demo_init_vk(struct demo *demo) { } volkLoadInstance(demo->inst); +} +static void demo_select_physical_device(struct demo* demo) { + VkResult err; /* Make initial call to query gpu_count, then second call for gpu info */ uint32_t gpu_count = 0; err = vkEnumeratePhysicalDevices(demo->inst, &gpu_count, NULL); @@ -4188,7 +4191,10 @@ static void demo_init_vk(struct demo *demo) { for (uint32_t i = 0; i < gpu_count; i++) { vkGetPhysicalDeviceProperties(physical_devices[i], &physicalDeviceProperties); assert(physicalDeviceProperties.deviceType <= VK_PHYSICAL_DEVICE_TYPE_CPU); - count_device_type[physicalDeviceProperties.deviceType]++; + VkBool32 supported = 0; + vkGetPhysicalDeviceSurfaceSupportKHR(physical_devices[i], 0, demo->surface, &supported); + if (supported) + count_device_type[physicalDeviceProperties.deviceType]++; } VkPhysicalDeviceType search_for_device_type = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU; @@ -4298,6 +4304,24 @@ static void demo_init_vk(struct demo *demo) { } if (demo->validate) { + /* + * This is info for a temp callback to use during CreateInstance. + * After the instance is created, we use the instance-based + * function to register the final callback. + */ + VkDebugUtilsMessengerCreateInfoEXT dbg_messenger_create_info; + // VK_EXT_debug_utils style + dbg_messenger_create_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT; + dbg_messenger_create_info.pNext = NULL; + dbg_messenger_create_info.flags = 0; + dbg_messenger_create_info.messageSeverity = + VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; + dbg_messenger_create_info.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT; + dbg_messenger_create_info.pfnUserCallback = debug_messenger_callback; + dbg_messenger_create_info.pUserData = demo; + err = vkCreateDebugUtilsMessengerEXT(demo->inst, &dbg_messenger_create_info, NULL, &demo->dbg_messenger); switch (err) { case VK_SUCCESS: @@ -4492,8 +4516,6 @@ static VkSurfaceFormatKHR pick_surface_format(const VkSurfaceFormatKHR *surfaceF static void demo_init_vk_swapchain(struct demo *demo) { VkResult U_ASSERT_ONLY err; - demo_create_surface(demo); - // Iterate over each queue to learn whether it supports presenting: VkBool32 *supportsPresent = (VkBool32 *)malloc(demo->queue_family_count * sizeof(VkBool32)); for (uint32_t i = 0; i < demo->queue_family_count; i++) { @@ -4868,6 +4890,8 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine, demo.connection = hInstance; strncpy(demo.name, "Vulkan Cube", APP_NAME_STR_LEN); demo_create_window(&demo); + demo_create_surface(&demo); + demo_select_physical_device(&demo); demo_init_vk_swapchain(&demo); demo_prepare(&demo); @@ -4906,6 +4930,8 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine, #if defined(VK_USE_PLATFORM_METAL_EXT) static void demo_main(struct demo *demo, void *caMetalLayer, int argc, const char *argv[]) { demo_init(demo, argc, (char **)argv); + demo_create_surface(demo); + demo_select_physical_device(demo); demo->caMetalLayer = caMetalLayer; demo_init_vk_swapchain(demo); demo_prepare(demo); @@ -4959,6 +4985,8 @@ static void processCommand(struct android_app *app, int32_t cmd) { for (int i = 0; i < argc; i++) free(argv[i]); demo.window = (void *)app->window; + demo_create_surface(&demo); + demo_select_physical_device(&demo); demo_init_vk_swapchain(&demo); demo_prepare(&demo); initialized = true; @@ -5044,6 +5072,8 @@ int main(int argc, char **argv) { break; #endif } + demo_create_surface(&demo); + demo_select_physical_device(&demo); demo_init_vk_swapchain(&demo); From 04f23b096f38084ffd9bc17349ff6787ac0a1fc1 Mon Sep 17 00:00:00 2001 From: Water Chika Date: Wed, 6 Nov 2024 05:36:30 +0000 Subject: [PATCH 2/4] vkcube: Check if gpu support the surface Fix bug on checking and refine logic of selection. --- cube/cube.c | 49 +++++++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/cube/cube.c b/cube/cube.c index 0f7243643..776010d16 100644 --- a/cube/cube.c +++ b/cube/cube.c @@ -4184,37 +4184,42 @@ static void demo_select_physical_device(struct demo* demo) { } else { /* Try to auto select most suitable device */ if (demo->gpu_number == -1) { - uint32_t count_device_type[VK_PHYSICAL_DEVICE_TYPE_CPU + 1]; - memset(count_device_type, 0, sizeof(count_device_type)); - VkPhysicalDeviceProperties physicalDeviceProperties; + int prev_priority = 0; for (uint32_t i = 0; i < gpu_count; i++) { vkGetPhysicalDeviceProperties(physical_devices[i], &physicalDeviceProperties); assert(physicalDeviceProperties.deviceType <= VK_PHYSICAL_DEVICE_TYPE_CPU); + + // Continue next gpu if this gpu does not support the surface. VkBool32 supported = 0; vkGetPhysicalDeviceSurfaceSupportKHR(physical_devices[i], 0, demo->surface, &supported); - if (supported) - count_device_type[physicalDeviceProperties.deviceType]++; - } + if (!supported) continue; - VkPhysicalDeviceType search_for_device_type = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU; - if (count_device_type[VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU]) { - search_for_device_type = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU; - } else if (count_device_type[VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU]) { - search_for_device_type = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU; - } else if (count_device_type[VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU]) { - search_for_device_type = VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU; - } else if (count_device_type[VK_PHYSICAL_DEVICE_TYPE_CPU]) { - search_for_device_type = VK_PHYSICAL_DEVICE_TYPE_CPU; - } else if (count_device_type[VK_PHYSICAL_DEVICE_TYPE_OTHER]) { - search_for_device_type = VK_PHYSICAL_DEVICE_TYPE_OTHER; - } + int priority = 0; + switch (physicalDeviceProperties.deviceType) { + case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: + priority = 5; + break; + case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: + priority = 4; + break; + case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: + priority = 3; + break; + case VK_PHYSICAL_DEVICE_TYPE_CPU: + priority = 2; + break; + case VK_PHYSICAL_DEVICE_TYPE_OTHER: + priority = 1; + break; + default: + priority = -1; + break; + } - for (uint32_t i = 0; i < gpu_count; i++) { - vkGetPhysicalDeviceProperties(physical_devices[i], &physicalDeviceProperties); - if (physicalDeviceProperties.deviceType == search_for_device_type) { + if (priority > prev_priority) { demo->gpu_number = i; - break; + prev_priority = priority; } } } From 5abe82960608fa0b980d06134da0a1d58aaf3f6d Mon Sep 17 00:00:00 2001 From: Water Chika Date: Wed, 6 Nov 2024 05:59:18 +0000 Subject: [PATCH 3/4] vkcubepp: Check if gpu support the surface --- cube/cube.c | 2 +- cube/cube.cpp | 50 +++++++++++++++++++++++++++++++------------------- 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/cube/cube.c b/cube/cube.c index 776010d16..f1123ac25 100644 --- a/cube/cube.c +++ b/cube/cube.c @@ -4191,7 +4191,7 @@ static void demo_select_physical_device(struct demo* demo) { assert(physicalDeviceProperties.deviceType <= VK_PHYSICAL_DEVICE_TYPE_CPU); // Continue next gpu if this gpu does not support the surface. - VkBool32 supported = 0; + VkBool32 supported = VK_FALSE; vkGetPhysicalDeviceSurfaceSupportKHR(physical_devices[i], 0, demo->surface, &supported); if (!supported) continue; diff --git a/cube/cube.cpp b/cube/cube.cpp index 024d3eac4..8e981836d 100644 --- a/cube/cube.cpp +++ b/cube/cube.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #if defined(VK_USE_PLATFORM_XLIB_KHR) #include "xlib_loader.h" @@ -317,6 +318,7 @@ struct Demo { void init(int argc, char **argv); void check_and_set_wsi_platform(); void init_vk(); + void select_physical_device(); void init_vk_swapchain(); void prepare(); void prepare_buffers(); @@ -1700,7 +1702,9 @@ void Demo::init_vk() { VERIFY(create_debug_messenger_return.result == vk::Result::eSuccess); debug_messenger = create_debug_messenger_return.value; } +} +void Demo::select_physical_device() { auto physical_device_return = inst.enumeratePhysicalDevices(); VERIFY(physical_device_return.result == vk::Result::eSuccess); auto physical_devices = physical_device_return.value; @@ -1734,32 +1738,33 @@ void Demo::init_vk() { } else { /* Try to auto select most suitable device */ if (gpu_number == -1) { - constexpr uint32_t device_type_count = static_cast(vk::PhysicalDeviceType::eCpu) + 1; - std::array count_device_type{}; - + int prev_priority = 0; for (uint32_t i = 0; i < physical_devices.size(); i++) { const auto physicalDeviceProperties = physical_devices[i].getProperties(); assert(physicalDeviceProperties.deviceType <= vk::PhysicalDeviceType::eCpu); - count_device_type[static_cast(physicalDeviceProperties.deviceType)]++; - } - std::array const device_type_preference = { - vk::PhysicalDeviceType::eDiscreteGpu, vk::PhysicalDeviceType::eIntegratedGpu, vk::PhysicalDeviceType::eVirtualGpu, - vk::PhysicalDeviceType::eCpu, vk::PhysicalDeviceType::eOther}; + auto support_result = physical_devices[i].getSurfaceSupportKHR(0, surface); + if (support_result.result != vk::Result::eSuccess || + support_result.value != vk::True) { + continue; + } - vk::PhysicalDeviceType search_for_device_type = vk::PhysicalDeviceType::eDiscreteGpu; - for (uint32_t i = 0; i < sizeof(device_type_preference) / sizeof(vk::PhysicalDeviceType); i++) { - if (count_device_type[static_cast(device_type_preference[i])]) { - search_for_device_type = device_type_preference[i]; - break; + std::map device_type_priorities = { + {vk::PhysicalDeviceType::eDiscreteGpu, 5}, + {vk::PhysicalDeviceType::eIntegratedGpu, 4}, + {vk::PhysicalDeviceType::eVirtualGpu, 3}, + {vk::PhysicalDeviceType::eCpu, 2}, + {vk::PhysicalDeviceType::eOther, 1}, + }; + int priority = -1; + if (device_type_priorities.find(physicalDeviceProperties.deviceType) != + device_type_priorities.end()) { + priority = device_type_priorities[physicalDeviceProperties.deviceType]; } - } - for (uint32_t i = 0; i < physical_devices.size(); i++) { - const auto physicalDeviceProperties = physical_devices[i].getProperties(); - if (physicalDeviceProperties.deviceType == search_for_device_type) { + if (priority > prev_priority) { gpu_number = i; - break; + prev_priority = priority; } } } @@ -1877,7 +1882,6 @@ void Demo::create_surface() { } void Demo::init_vk_swapchain() { - create_surface(); // Iterate over each queue to learn whether it supports presenting: std::vector supportsPresent; for (uint32_t i = 0; i < static_cast(queue_props.size()); i++) { @@ -3744,6 +3748,8 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine, demo.connection = hInstance; demo.name = "Vulkan Cube"; demo.create_window(); + demo.create_surface(); + demo.select_physical_device(); demo.init_vk_swapchain(); demo.prepare(); @@ -3825,6 +3831,10 @@ int main(int argc, char **argv) { #endif } + demo.create_surface(); + + demo.select_physical_device(); + demo.init_vk_swapchain(); demo.prepare(); @@ -3879,6 +3889,8 @@ int main(int argc, char **argv) { // Global function invoked from NS or UI views and controllers to create demo static void demo_main(Demo &demo, void *caMetalLayer, int argc, const char *argv[]) { demo.init(argc, (char **)argv); + demo.create_surface(); + demo.select_physical_device(); demo.caMetalLayer = caMetalLayer; demo.init_vk_swapchain(); demo.prepare(); From 500bb826b027793919aca9773d217cced31cc2f4 Mon Sep 17 00:00:00 2001 From: Charles Giessen Date: Wed, 27 Nov 2024 17:53:28 -0600 Subject: [PATCH 4/4] cube: Check return value of vkGetPhysicalDeviceSurfaceSupportKHR --- cube/cube.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cube/cube.c b/cube/cube.c index f1123ac25..d2b9bac43 100644 --- a/cube/cube.c +++ b/cube/cube.c @@ -4145,7 +4145,7 @@ static void demo_init_vk(struct demo *demo) { volkLoadInstance(demo->inst); } -static void demo_select_physical_device(struct demo* demo) { +static void demo_select_physical_device(struct demo *demo) { VkResult err; /* Make initial call to query gpu_count, then second call for gpu info */ uint32_t gpu_count = 0; @@ -4192,8 +4192,8 @@ static void demo_select_physical_device(struct demo* demo) { // Continue next gpu if this gpu does not support the surface. VkBool32 supported = VK_FALSE; - vkGetPhysicalDeviceSurfaceSupportKHR(physical_devices[i], 0, demo->surface, &supported); - if (!supported) continue; + VkResult result = vkGetPhysicalDeviceSurfaceSupportKHR(physical_devices[i], 0, demo->surface, &supported); + if (result != VK_SUCCESS || !supported) continue; int priority = 0; switch (physicalDeviceProperties.deviceType) {