radv: do not open random render node(s)
authorEmil Velikov <emil.velikov@collabora.com>
Thu, 1 Dec 2016 20:58:20 +0000 (20:58 +0000)
committerEmil Velikov <emil.l.velikov@gmail.com>
Wed, 15 Mar 2017 11:38:02 +0000 (11:38 +0000)
drmGetDevices2() provides us with enough flexibility to build heuristics
upon. Opening a random node on the other hand will wake up the device,
regardless if it's the one we're interested or not.

v2: Rebase.
v3: Return VK_ERROR_INCOMPATIBLE_DRIVER for no devices (Ilia)

Cc: Michel Dänzer <michel.daenzer@amd.com>
Cc: Dave Airlie <airlied@redhat.com>
Signed-off-by: Emil Velikov <emil.velikov@collabora.com>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl> (v1)
Reviewed-by: Eric Engestrom <eric.engestrom@imgtec.com> (v1)
Tested-by: Mike Lothian <mike@fireburn.co.uk>
src/amd/vulkan/radv_device.c

index d1fd58d77b9081bfbb9e5f8173229b99ce316b73..bc136e4489b133378e4f13dc72f63fcca4698e8b 100644 (file)
@@ -379,28 +379,52 @@ void radv_DestroyInstance(
        vk_free(&instance->alloc, instance);
 }
 
-VkResult radv_EnumeratePhysicalDevices(
-       VkInstance                                  _instance,
-       uint32_t*                                   pPhysicalDeviceCount,
-       VkPhysicalDevice*                           pPhysicalDevices)
+static VkResult
+radv_enumerate_devices(struct radv_instance *instance)
 {
-       RADV_FROM_HANDLE(radv_instance, instance, _instance);
-       VkResult result;
+       /* TODO: Check for more devices ? */
+       drmDevicePtr devices[8];
+       VkResult result = VK_ERROR_INCOMPATIBLE_DRIVER;
+       int max_devices;
+
+       instance->physicalDeviceCount = 0;
+
+       max_devices = drmGetDevices2(0, devices, sizeof(devices));
+       if (max_devices < 1)
+               return VK_ERROR_INCOMPATIBLE_DRIVER;
+
+       for (unsigned i = 0; i < (unsigned)max_devices; i++) {
+               if (devices[i]->available_nodes & 1 << DRM_NODE_RENDER &&
+                   devices[i]->bustype == DRM_BUS_PCI &&
+                   devices[i]->deviceinfo.pci->vendor_id == 0x1002) {
 
-       if (instance->physicalDeviceCount < 0) {
-               char path[20];
-               instance->physicalDeviceCount = 0;
-               for (unsigned i = 0; i < RADV_MAX_DRM_DEVICES; i++) {
-                       snprintf(path, sizeof(path), "/dev/dri/renderD%d", 128 + i);
                        result = radv_physical_device_init(instance->physicalDevices +
                                                           instance->physicalDeviceCount,
-                                                          instance, path);
+                                                          instance,
+                                                          devices[i]->nodes[DRM_NODE_RENDER]);
                        if (result == VK_SUCCESS)
                                ++instance->physicalDeviceCount;
                        else if (result != VK_ERROR_INCOMPATIBLE_DRIVER)
                                return result;
                }
        }
+       return result;
+}
+
+VkResult radv_EnumeratePhysicalDevices(
+       VkInstance                                  _instance,
+       uint32_t*                                   pPhysicalDeviceCount,
+       VkPhysicalDevice*                           pPhysicalDevices)
+{
+       RADV_FROM_HANDLE(radv_instance, instance, _instance);
+       VkResult result;
+
+       if (instance->physicalDeviceCount < 0) {
+               result = radv_enumerate_devices(instance);
+               if (result != VK_SUCCESS &&
+                   result != VK_ERROR_INCOMPATIBLE_DRIVER)
+                       return result;
+       }
 
        if (!pPhysicalDevices) {
                *pPhysicalDeviceCount = instance->physicalDeviceCount;