int main(void) { drmDevicePtr *devices; drmDevicePtr device; int fd, ret, max_devices; max_devices = drmGetDevices(NULL, 0); if (max_devices <= 0) { printf("drmGetDevices() has returned %d\n", max_devices); return -1; } devices = calloc(max_devices, sizeof(drmDevicePtr)); if (devices == NULL) { printf("Failed to allocate memory for the drmDevicePtr array\n"); return -1; } ret = drmGetDevices(devices, max_devices); if (ret < 0) { printf("drmGetDevices() returned an error %d\n", ret); free(devices); return -1; } for (int i = 0; i < ret; i++) { print_device_info(devices[i], i); for (int j = 0; j < DRM_NODE_MAX; j++) { if (devices[i]->available_nodes & 1 << j) { printf("Opening device %d node %s\n", i, devices[i]->nodes[j]); fd = open(devices[i]->nodes[j], O_RDONLY | O_CLOEXEC, 0); if (fd < 0) { printf("Failed - %s (%d)\n", strerror(errno), errno); continue; } if (drmGetDevice(fd, &device) == 0) { print_device_info(device, i); drmFreeDevice(&device); } close(fd); } } } drmFreeDevices(devices, ret); free(devices); return 0; }
int loader_get_user_preferred_fd(int default_fd, int *different_device) { /* Arbitrary "maximum" value of drm devices. */ #define MAX_DRM_DEVICES 32 const char *dri_prime = getenv("DRI_PRIME"); char *default_tag, *prime = NULL; drmDevicePtr devices[MAX_DRM_DEVICES]; int i, num_devices, fd; bool found = false; if (dri_prime) prime = strdup(dri_prime); #ifdef USE_DRICONF else prime = loader_get_dri_config_device_id(); #endif if (prime == NULL) { *different_device = 0; return default_fd; } default_tag = drm_get_id_path_tag_for_fd(default_fd); if (default_tag == NULL) goto err; num_devices = drmGetDevices(devices, MAX_DRM_DEVICES); if (num_devices < 0) goto err; /* two format are supported: * "1": choose any other card than the card used by default. * id_path_tag: (for example "pci-0000_02_00_0") choose the card * with this id_path_tag. */ if (!strcmp(prime,"1")) { /* Hmm... detection for 2-7 seems to be broken. Oh well ... * Pick the first render device that is not our own. */ for (i = 0; i < num_devices; i++) { if (devices[i]->available_nodes & 1 << DRM_NODE_RENDER && !drm_device_matches_tag(devices[i], default_tag)) { found = true; break; } } } else { for (i = 0; i < num_devices; i++) { if (devices[i]->available_nodes & 1 << DRM_NODE_RENDER && drm_device_matches_tag(devices[i], prime)) { found = true; break; } } } if (!found) { drmFreeDevices(devices, num_devices); goto err; } fd = loader_open_device(devices[i]->nodes[DRM_NODE_RENDER]); drmFreeDevices(devices, num_devices); if (fd < 0) goto err; close(default_fd); *different_device = !!strcmp(default_tag, prime); free(default_tag); free(prime); return fd; err: *different_device = 0; free(default_tag); free(prime); return default_fd; }