aboutsummaryrefslogtreecommitdiff
path: root/cube/cube.c
diff options
context:
space:
mode:
authorWitold Baryluk <witold.baryluk@gmail.com>2021-01-07 19:03:02 +0000
committerTony Barbour <tony@lunarg.com>2021-01-12 15:51:58 -0700
commita3b988fa55885a3da83e33724e7beaaaeeee297c (patch)
treed20f59ce4c4fad5f72ab79e2bdb4640920c4d17f /cube/cube.c
parentbe70e017bff5d1a1889cde1c09522b6ab24e5764 (diff)
downloadusermoji-a3b988fa55885a3da83e33724e7beaaaeeee297c.tar.xz
vkcube: Improve GPU auto-selection
Instead of selecting GPU 0, prefer dGPU, iGPU, vGPU, CPU, OTHER. In that order. If user selects specific gpu_number (including 0), use only that and don't fallback to anything else, even when incorrect.
Diffstat (limited to 'cube/cube.c')
-rw-r--r--cube/cube.c76
1 files changed, 58 insertions, 18 deletions
diff --git a/cube/cube.c b/cube/cube.c
index 9516fca1..800a0694 100644
--- a/cube/cube.c
+++ b/cube/cube.c
@@ -343,7 +343,7 @@ struct demo {
bool use_staging_buffer;
bool separate_present_queue;
bool is_minimized;
- uint32_t gpu_number;
+ int32_t gpu_number;
bool VK_KHR_incremental_present_enabled;
@@ -3248,8 +3248,6 @@ static void demo_init_vk(struct demo *demo) {
inst_info.pNext = &dbg_messenger_create_info;
}
- uint32_t gpu_count;
-
err = vkCreateInstance(&inst_info, NULL, &demo->inst);
if (err == VK_ERROR_INCOMPATIBLE_DRIVER) {
ERR_EXIT(
@@ -3269,22 +3267,12 @@ static void demo_init_vk(struct demo *demo) {
"vkCreateInstance Failure");
}
- /* Make initial call to query gpu_count, then second call for gpu info*/
+ /* 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);
assert(!err);
- if (gpu_count > 0) {
- VkPhysicalDevice *physical_devices = malloc(sizeof(VkPhysicalDevice) * gpu_count);
- err = vkEnumeratePhysicalDevices(demo->inst, &gpu_count, physical_devices);
- assert(!err);
- if (demo->gpu_number > gpu_count - 1) {
- fprintf(stderr, "Gpu %u specified is not present, gpu count = %u\n", demo->gpu_number, gpu_count);
- fprintf(stderr, "Continuing with gpu 0\n");
- demo->gpu_number = 0;
- }
- demo->gpu = physical_devices[demo->gpu_number];
- free(physical_devices);
- } else {
+ if (gpu_count <= 0) {
ERR_EXIT(
"vkEnumeratePhysicalDevices reported zero accessible devices.\n\n"
"Do you have a compatible Vulkan installable client driver (ICD) installed?\n"
@@ -3292,6 +3280,57 @@ static void demo_init_vk(struct demo *demo) {
"vkEnumeratePhysicalDevices Failure");
}
+ VkPhysicalDevice *physical_devices = malloc(sizeof(VkPhysicalDevice) * gpu_count);
+ err = vkEnumeratePhysicalDevices(demo->inst, &gpu_count, physical_devices);
+ assert(!err);
+ if (demo->gpu_number >= 0 && !((uint32_t)demo->gpu_number < gpu_count)) {
+ fprintf(stderr, "GPU %d specified is not present, GPU count = %u\n", demo->gpu_number, gpu_count);
+ ERR_EXIT("Specified GPU number is not present", "User Error");
+ }
+
+ /* 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;
+ 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]++;
+ }
+
+ 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;
+ }
+
+ for (uint32_t i = 0; i < gpu_count; i++) {
+ vkGetPhysicalDeviceProperties(physical_devices[i], &physicalDeviceProperties);
+ if (physicalDeviceProperties.deviceType == search_for_device_type) {
+ demo->gpu_number = i;
+ break;
+ }
+ }
+ }
+ assert(demo->gpu_number >= 0);
+ demo->gpu = physical_devices[demo->gpu_number];
+ {
+ VkPhysicalDeviceProperties physicalDeviceProperties;
+ vkGetPhysicalDeviceProperties(demo->gpu, &physicalDeviceProperties);
+ fprintf(stderr, "Selected GPU %d: %s, type: %u\n", demo->gpu_number, physicalDeviceProperties.deviceName,
+ physicalDeviceProperties.deviceType);
+ }
+ free(physical_devices);
+
/* Look for device extensions */
uint32_t device_extension_count = 0;
VkBool32 swapchainExtFound = 0;
@@ -3816,8 +3855,8 @@ static void demo_init(struct demo *demo, int argc, char **argv) {
memset(demo, 0, sizeof(*demo));
demo->presentMode = VK_PRESENT_MODE_FIFO_KHR;
demo->frameCount = INT32_MAX;
- /* For cube demo we just grab the first physical device by default */
- demo->gpu_number = 0;
+ /* Autodetect suitable / best GPU by default */
+ demo->gpu_number = -1;
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "--use_staging") == 0) {
@@ -3865,6 +3904,7 @@ static void demo_init(struct demo *demo, int argc, char **argv) {
}
if ((strcmp(argv[i], "--gpu_number") == 0) && (i < argc - 1)) {
demo->gpu_number = atoi(argv[i + 1]);
+ assert(demo->gpu_number >= 0);
i++;
continue;
}