summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2014-10-08 04:12:49 -0700
committerEric Anholt <eric@anholt.net>2014-10-27 13:16:23 -0700
commit34a98c8103a6f725283d0d1ee4084bf387b93019 (patch)
treea42e8cd34c1673439c0ea40f1fb599727a3de178 /hw
parent470d97e1d176981dbd8087c621e54caab0d6c73c (diff)
dri2: Automatically fill in the driver name if the DDX doesn't provide it.
This will be used by the modesetting driver to support DRI2 across all hardware that can support glamor, and could potentially be used by other drivers that have to support DRI2 on sets of hardware with multiple Mesa drivers. This logic is the same as what's present in the Mesa driver loader, except for the lack of nouveau_vieux support (which requires a predicate on the device). v2: Fix duplicated assignment of info->driverName. Signed-off-by: Eric Anholt <eric@anholt.net> Reviewed-by: Adam Jackson <ajax@redhat.com>
Diffstat (limited to 'hw')
-rw-r--r--hw/xfree86/dri2/dri2.c62
1 files changed, 61 insertions, 1 deletions
diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index 6459f11b1..c8fcd6220 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -1410,6 +1410,59 @@ get_prime_id(void)
return -1;
}
+#include "pci_ids/pci_id_driver_map.h"
+
+static char *
+dri2_probe_driver_name(ScreenPtr pScreen, DRI2InfoPtr info)
+{
+ ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
+ EntityInfoPtr pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
+ struct pci_device *pdev = NULL;
+ int i, j;
+
+ if (pEnt)
+ pdev = xf86GetPciInfoForEntity(pEnt->index);
+
+ /* For non-PCI devices, just assume that the 3D driver is named
+ * the same as the kernel driver. This is currently true for vc4
+ * and msm (freedreno).
+ */
+ if (!pdev) {
+ drmVersionPtr version = drmGetVersion(info->fd);
+ char *kernel_driver;
+
+ if (!version) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[DRI2] Couldn't drmGetVersion() on non-PCI device, "
+ "no driver name found.\n");
+ return NULL;
+ }
+
+ kernel_driver = strndup(version->name, version->name_len);
+ drmFreeVersion(version);
+ return kernel_driver;
+ }
+
+ for (i = 0; driver_map[i].driver; i++) {
+ if (pdev->vendor_id != driver_map[i].vendor_id)
+ continue;
+
+ if (driver_map[i].num_chips_ids == -1)
+ return strdup(driver_map[i].driver);
+
+ for (j = 0; j < driver_map[i].num_chips_ids; j++) {
+ if (driver_map[i].chip_ids[j] == pdev->device_id)
+ return strdup(driver_map[i].driver);
+ }
+ }
+
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[DRI2] No driver mapping found for PCI device "
+ "0x%04x / 0x%04x\n",
+ pdev->vendor_id, pdev->device_id);
+ return NULL;
+}
+
Bool
DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
{
@@ -1524,7 +1577,14 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
ds->driverNames = malloc(sizeof(*ds->driverNames));
if (!ds->driverNames)
goto err_out;
- ds->driverNames[0] = info->driverName;
+
+ if (info->driverName) {
+ ds->driverNames[0] = info->driverName;
+ } else {
+ ds->driverNames[0] = dri2_probe_driver_name(pScreen, info);
+ if (!ds->driverNames[0])
+ return FALSE;
+ }
}
else {
ds->numDrivers = info->numDrivers;