summaryrefslogtreecommitdiff
path: root/gdk/gdkvulkancontext.c
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2018-01-09 20:33:04 -0500
committerMatthias Clasen <mclasen@redhat.com>2018-01-09 20:33:04 -0500
commitccdeaab1f97f5d73fad951a56bd0d6ccfa94f2a2 (patch)
tree84401cae960a65a59a753bdfdc473a38e8b3e02c /gdk/gdkvulkancontext.c
parent0fe6d76ab6a5e0da97bc08922f05814a25d4315e (diff)
downloadgtk+-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.c107
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,