summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarijn Suijten <marijn.suijten@somainline.org>2024-05-08 01:13:34 +0200
committerMarijn Suijten <marijn.suijten@somainline.org>2024-09-03 13:30:41 +0200
commit887fec2c288f291454a0f165a5e66c740524a764 (patch)
treee137c5717017c6b25cda7720f28d1debdf25af74
parent25dec5b91fe4d2638787d033a0b22b6c1dc145e0 (diff)
tests/util: Call `drmGetDevices2()` instead of `drmOpen()`ing all modules
Whenever `util_open()` is called to open a device for the first matching module, it will skip devices for the `nvidia_drm` kernel module which is not in the list. We could add this module for now, but keeping this list of DRM modules up to date is cumbersome. At the same time walking a list of modules and calling `drmOpen()` for each of them is incredibly expensive (when the user doesn't explicitly specify one with `-M`), as each each call opens every DRM node just to see if they are associated to the requested module. And for no good reason: all we want is the first `DRM_NODE_PRIMARY` (which is what `drmOpen()` also returns) to use by default. For example on the `"msm"` driver, which used to be the 9th in the modules list, all nodes are opened for the 9th time before e.g. `modetest` returns a useful result, which takes ages unless the user painstakingly provides the module for the currently known device on the cmdline. This is very simply solved by calling `drmGetDevices(2)()`, which iterates through all DRM nodes only once and allows us to immediately find + `open()` the first device that has a PRIMARY node. A random search for the error shows that this was also attempted in (a fork of?) kmscube: https://git.ti.com/cgit/glsdk/kmscube/commit/?id=456cabc661caac5c60729751d45efd668faa8e97 Finally we add a `drmIsKMS()` check to make sure we only include primary nodes that actually support rendering, and also print the values from `drmGetVersion()` on success to make it easier to identify the device. In the future we could extrapolate this feature by letting query commands like `modetest -c` list connectors for every device/module, not just the first PRIMARY node that we found.
-rw-r--r--tests/util/kms.c75
1 files changed, 35 insertions, 40 deletions
diff --git a/tests/util/kms.c b/tests/util/kms.c
index 8bbc2275..5c66da3f 100644
--- a/tests/util/kms.c
+++ b/tests/util/kms.c
@@ -42,6 +42,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
#include "xf86drm.h"
#include "xf86drmMode.h"
@@ -96,59 +98,42 @@ const char *util_lookup_connector_status_name(unsigned int status)
ARRAY_SIZE(connector_status_names));
}
-static const char * const modules[] = {
- "i915",
- "amdgpu",
- "radeon",
- "nouveau",
- "vmwgfx",
- "omapdrm",
- "exynos",
- "tilcdc",
- "msm",
- "sti",
- "tegra",
- "imx-drm",
- "rockchip",
- "atmel-hlcdc",
- "fsl-dcu-drm",
- "vc4",
- "virtio_gpu",
- "mediatek",
- "meson",
- "pl111",
- "stm",
- "sun4i-drm",
- "armada-drm",
- "komeda",
- "imx-dcss",
- "mxsfb-drm",
- "simpledrm",
- "imx-lcdif",
- "vkms",
- "tidss",
-};
-
int util_open(const char *device, const char *module)
{
- int fd;
+ int fd = -1;
+ drmVersionPtr version;
- if (module) {
+ if (module || device) {
fd = drmOpen(module, device);
if (fd < 0) {
- fprintf(stderr, "failed to open device '%s': %s\n",
- module, strerror(errno));
+ fprintf(stderr, "failed to open device '%s' with busid '%s': %s\n",
+ module, device, strerror(errno));
return -errno;
}
} else {
unsigned int i;
+ drmDevicePtr devices[64];
+ int num_devices = drmGetDevices2(0, devices, ARRAY_SIZE(devices));
+ if (num_devices < 0) {
+ fprintf(stderr, "drmGetDevices2() failed with %s\n", strerror(num_devices));
+ return num_devices;
+ }
- for (i = 0; i < ARRAY_SIZE(modules); i++) {
- printf("trying to open device '%s'...", modules[i]);
+ for (i = 0; i < num_devices; i++) {
+ drmDevicePtr device = devices[i];
+ // Select only primary nodes
+ if ((device->available_nodes & 1 << DRM_NODE_PRIMARY) == 0)
+ continue;
+
+ printf("trying to open device '%s'... ", device->nodes[DRM_NODE_PRIMARY]);
+ fd = open(device->nodes[DRM_NODE_PRIMARY], O_RDWR | O_CLOEXEC);
- fd = drmOpen(modules[i], device);
if (fd < 0) {
printf("failed\n");
+ } else if (!drmIsKMS(fd)) {
+ printf("is not a KMS device\n");
+ close(fd);
+ fd = -1;
} else {
printf("done\n");
break;
@@ -161,5 +146,15 @@ int util_open(const char *device, const char *module)
}
}
+ version = drmGetVersion(fd);
+ printf("opened device `%s` on driver `%s` (version %d.%d.%d at %s)\n",
+ version->desc,
+ version->name,
+ version->version_major,
+ version->version_minor,
+ version->version_patchlevel,
+ version->date);
+ drmFreeVersion(version);
+
return fd;
}