anv: do not open random render node(s)

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, explicitly require/check for libdrm
v3: Return VK_ERROR_INCOMPATIBLE_DRIVER for no devices (Ilia)
v4: Rebase

Cc: Jason Ekstrand <jason.ekstrand@intel.com>
Signed-off-by: Emil Velikov <emil.velikov@collabora.com>
Reviewed-by: Eric Engestrom <eric.engestrom@imgtec.com> (v1)
Tested-by: Mike Lothian <mike@fireburn.co.uk>
This commit is contained in:
Emil Velikov
2016-12-01 21:21:10 +00:00
committed by Emil Velikov
parent 743315f269
commit b1fb6e8d8c
2 changed files with 39 additions and 17 deletions

View File

@@ -27,6 +27,7 @@
#include <sys/mman.h>
#include <unistd.h>
#include <fcntl.h>
#include <xf86drm.h>
#include "anv_private.h"
#include "util/strtod.h"
@@ -384,6 +385,40 @@ void anv_DestroyInstance(
vk_free(&instance->alloc, instance);
}
static VkResult
anv_enumerate_devices(struct anv_instance *instance)
{
/* 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 == 0x8086) {
result = anv_physical_device_init(&instance->physicalDevice,
instance,
devices[i]->nodes[DRM_NODE_RENDER]);
if (result != VK_ERROR_INCOMPATIBLE_DRIVER)
break;
}
}
if (result == VK_SUCCESS)
instance->physicalDeviceCount = 1;
return result;
}
VkResult anv_EnumeratePhysicalDevices(
VkInstance _instance,
uint32_t* pPhysicalDeviceCount,
@@ -394,22 +429,10 @@ VkResult anv_EnumeratePhysicalDevices(
VkResult result;
if (instance->physicalDeviceCount < 0) {
char path[20];
for (unsigned i = 0; i < 8; i++) {
snprintf(path, sizeof(path), "/dev/dri/renderD%d", 128 + i);
result = anv_physical_device_init(&instance->physicalDevice,
instance, path);
if (result != VK_ERROR_INCOMPATIBLE_DRIVER)
break;
}
if (result == VK_ERROR_INCOMPATIBLE_DRIVER) {
instance->physicalDeviceCount = 0;
} else if (result == VK_SUCCESS) {
instance->physicalDeviceCount = 1;
} else {
result = anv_enumerate_devices(instance);
if (result != VK_SUCCESS &&
result != VK_ERROR_INCOMPATIBLE_DRIVER)
return result;
}
}
if (instance->physicalDeviceCount > 0) {