diff options
author | Matthias Clasen <mclasen@redhat.com> | 2018-01-09 20:33:04 -0500 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2018-01-09 20:33:04 -0500 |
commit | ccdeaab1f97f5d73fad951a56bd0d6ccfa94f2a2 (patch) | |
tree | 84401cae960a65a59a753bdfdc473a38e8b3e02c /gdk/gdkvulkancontext.c | |
parent | 0fe6d76ab6a5e0da97bc08922f05814a25d4315e (diff) | |
download | gtk+-ccdeaab1f97f5d73fad951a56bd0d6ccfa94f2a2.tar.gz |
vulkan: Add a way to specify a device
We should be smarter in picking a good device eventually,
but for now, we just allow to explicitly choose one. To
see a list of all devices, use GDK_VULKAN_DEVICE=list
To specify which device to use, use GDK_VULKAN_DEVICE=<number>
Diffstat (limited to 'gdk/gdkvulkancontext.c')
-rw-r--r-- | gdk/gdkvulkancontext.c | 107 |
1 files changed, 87 insertions, 20 deletions
diff --git a/gdk/gdkvulkancontext.c b/gdk/gdkvulkancontext.c index 0e3d4f99cb..9841c6ce91 100644 --- a/gdk/gdkvulkancontext.c +++ b/gdk/gdkvulkancontext.c @@ -712,7 +712,10 @@ static gboolean gdk_display_create_vulkan_device (GdkDisplay *display, GError **error) { - uint32_t i, j; + uint32_t i, j, k; + const char *override; + gboolean list_devices; + int first, last; uint32_t n_devices = 0; GDK_VK_CHECK(vkEnumeratePhysicalDevices, display->vk_instance, &n_devices, NULL); @@ -729,25 +732,90 @@ gdk_display_create_vulkan_device (GdkDisplay *display, devices = g_newa (VkPhysicalDevice, n_devices); GDK_VK_CHECK(vkEnumeratePhysicalDevices, display->vk_instance, &n_devices, devices); - for (i = 0; i < n_devices; i++) + first = 0; + last = n_devices; + + override = g_getenv ("GDK_VULKAN_DEVICE"); + list_devices = FALSE; + if (override) + { + if (g_strcmp0 (override, "list") == 0) + list_devices = TRUE; + else + { + gint64 device_idx; + GError *error = NULL; + + if (!g_ascii_string_to_signed (override, 10, 0, G_MAXINT, &device_idx, &error)) + { + g_warning ("Failed to parse %s: %s", "GDK_VULKAN_DEVICE", error->message); + g_error_free (error); + device_idx = -1; + } + + if (device_idx < 0 || device_idx >= n_devices) + g_warning ("%s value out of range, ignoring", "GDK_VULKAN_DEVICE"); + else + { + first = device_idx; + last = first + 1; + } + } + } + + if (list_devices || GDK_DEBUG_CHECK (VULKAN)) { - VkPhysicalDeviceProperties props; - - vkGetPhysicalDeviceProperties (devices[i], &props); - - GDK_NOTE (VULKAN, g_print ("Vulkan Device %u:\n", i)); - GDK_NOTE (VULKAN, g_print (" %s (%u)\n", props.deviceName, props.deviceType)); - GDK_NOTE (VULKAN, g_print (" vendor ID: 0x%Xu\n", props.vendorID)); - GDK_NOTE (VULKAN, g_print (" device ID: 0x%Xu\n", props.deviceID)); - GDK_NOTE (VULKAN, g_print (" API version %u.%u.%u\n", - VK_VERSION_MAJOR (props.apiVersion), - VK_VERSION_MINOR (props.apiVersion), - VK_VERSION_PATCH (props.apiVersion))); - GDK_NOTE (VULKAN, g_print (" driver version %u.%u.%u\n", - VK_VERSION_MAJOR (props.driverVersion), - VK_VERSION_MINOR (props.driverVersion), - VK_VERSION_PATCH (props.driverVersion))); + for (i = 0; i < n_devices; i++) + { + VkPhysicalDeviceProperties props; + VkQueueFamilyProperties *queue_props; + uint32_t n_queue_props; + const char *device_type[] = { + "Other", "Integrated GPU", "Discrete GPU", "Virtual GPU", "CPU" + }; + struct { + int bit; + const char *name; + } queue_caps[] = { + { VK_QUEUE_GRAPHICS_BIT, "graphics" }, + { VK_QUEUE_COMPUTE_BIT, "compute" }, + { VK_QUEUE_TRANSFER_BIT, "transfer" }, + { VK_QUEUE_SPARSE_BINDING_BIT, "sparse binding" } + }; + + vkGetPhysicalDeviceProperties (devices[i], &props); + vkGetPhysicalDeviceQueueFamilyProperties (devices[i], &n_queue_props, NULL); + queue_props = g_newa (VkQueueFamilyProperties, n_queue_props); + vkGetPhysicalDeviceQueueFamilyProperties (devices[i], &n_queue_props, queue_props); + + g_print ("Vulkan Device %u:\n", i); + g_print (" %s (%s)\n", props.deviceName, device_type[props.deviceType]); + g_print (" Vendor ID: 0x%Xu\n", props.vendorID); + g_print (" Device ID: 0x%Xu\n", props.deviceID); + g_print (" API version %u.%u.%u\n", + VK_VERSION_MAJOR (props.apiVersion), + VK_VERSION_MINOR (props.apiVersion), + VK_VERSION_PATCH (props.apiVersion)); + for (j = 0; j < n_queue_props; j++) + { + const char *sep = ""; + + g_print (" Queue %d: ", j); + for (k = 0; k < G_N_ELEMENTS (queue_caps); k++) + { + if (queue_props[j].queueFlags & queue_caps[k].bit) + { + g_print ("%s%s", sep, queue_caps[k].name); + sep = "/"; + } + } + g_print ("\n"); + } + } + } + for (i = first; i < last; i++) + { uint32_t n_queue_props; vkGetPhysicalDeviceQueueFamilyProperties (devices[i], &n_queue_props, NULL); VkQueueFamilyProperties *queue_props = g_newa (VkQueueFamilyProperties, n_queue_props); @@ -755,10 +823,9 @@ gdk_display_create_vulkan_device (GdkDisplay *display, for (j = 0; j < n_queue_props; j++) { - GDK_NOTE (VULKAN, g_print (" queue %u/%u: %s\n", j, n_queue_props, queue_props[j].queueFlags & VK_QUEUE_GRAPHICS_BIT ? "graphics" : "no graphics")); if (queue_props[j].queueFlags & VK_QUEUE_GRAPHICS_BIT) { - GDK_NOTE (VULKAN, g_print (" => trying this queue\n")); + GDK_NOTE (VULKAN, g_print ("Using Vulkan device %u, queue %u\n", i, j)); if (GDK_VK_CHECK (vkCreateDevice, devices[i], &(VkDeviceCreateInfo) { VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, |