Module Name: xsrc Committed By: mrg Date: Sun Nov 1 09:57:41 UTC 2020
Modified Files: xsrc/external/mit/libdrm/dist: xf86atomic.h xf86drm.c xf86drm.h xf86drmMode.c xf86drmMode.h xsrc/external/mit/libdrm/dist/include/drm: drm.h xsrc/external/mit/libdrm/dist/intel: intel_bufmgr_gem.c xsrc/external/mit/libdrm/dist/tests/modetest: modetest.c Added Files: xsrc/external/mit/libdrm/dist: Android.mk xsrc/external/mit/libdrm/dist/freedreno: Android.mk xsrc/external/mit/libdrm/dist/intel: Android.mk xsrc/external/mit/libdrm/dist/libkms: Android.mk xsrc/external/mit/libdrm/dist/nouveau: Android.mk xsrc/external/mit/libdrm/dist/radeon: Android.mk xsrc/external/mit/libdrm/dist/tests/modetest: Android.mk Removed Files: xsrc/external/mit/libdrm/dist: Makefile.am Makefile.in aclocal.m4 config.h.in configure configure.ac xsrc/external/mit/libdrm/dist/amdgpu: Makefile.am Makefile.in amdgpu-symbol-check xsrc/external/mit/libdrm/dist/build-aux: compile config.guess config.sub depcomp install-sh ltmain.sh missing test-driver xsrc/external/mit/libdrm/dist/data: Makefile.am Makefile.in xsrc/external/mit/libdrm/dist/etnaviv: Makefile.am Makefile.in etnaviv-symbol-check xsrc/external/mit/libdrm/dist/exynos: Makefile.am Makefile.in exynos-symbol-check xsrc/external/mit/libdrm/dist/freedreno: Makefile.am Makefile.in freedreno-symbol-check xsrc/external/mit/libdrm/dist/intel: Makefile.am Makefile.in intel-symbol-check xsrc/external/mit/libdrm/dist/intel/tests: gen4-3d.batch.sh gen5-3d.batch.sh gen6-3d.batch.sh gen7-2d-copy.batch.sh gen7-3d.batch.sh gm45-3d.batch.sh xsrc/external/mit/libdrm/dist/libkms: Makefile.am Makefile.in kms-symbol-check xsrc/external/mit/libdrm/dist/m4: libtool.m4 ltoptions.m4 ltsugar.m4 ltversion.m4 lt~obsolete.m4 xsrc/external/mit/libdrm/dist/man: Makefile.am Makefile.in xsrc/external/mit/libdrm/dist/nouveau: Makefile.am Makefile.in nouveau-symbol-check xsrc/external/mit/libdrm/dist/omap: Makefile.am Makefile.in omap-symbol-check xsrc/external/mit/libdrm/dist/radeon: Makefile.am Makefile.in radeon-symbol-check xsrc/external/mit/libdrm/dist/tegra: Makefile.am Makefile.in tegra-symbol-check xsrc/external/mit/libdrm/dist/tests: Makefile.am Makefile.in random.c xsrc/external/mit/libdrm/dist/tests/amdgpu: Makefile.am Makefile.in xsrc/external/mit/libdrm/dist/tests/etnaviv: Makefile.am Makefile.in xsrc/external/mit/libdrm/dist/tests/exynos: Makefile.am Makefile.in xsrc/external/mit/libdrm/dist/tests/kms: Makefile.am Makefile.in xsrc/external/mit/libdrm/dist/tests/kmstest: Makefile.am Makefile.in xsrc/external/mit/libdrm/dist/tests/modeprint: Makefile.am Makefile.in xsrc/external/mit/libdrm/dist/tests/modetest: Makefile.am Makefile.in xsrc/external/mit/libdrm/dist/tests/nouveau: Makefile.am Makefile.in xsrc/external/mit/libdrm/dist/tests/proptest: Makefile.am Makefile.in xsrc/external/mit/libdrm/dist/tests/radeon: Makefile.am Makefile.in xsrc/external/mit/libdrm/dist/tests/tegra: Makefile.am Makefile.in xsrc/external/mit/libdrm/dist/tests/util: Makefile.am Makefile.in xsrc/external/mit/libdrm/dist/tests/vbltest: Makefile.am Makefile.in xsrc/external/mit/libdrm/dist/vc4: Makefile.am Makefile.in Log Message: merge libdrm 2.4.102. To generate a diff of this commit: cvs rdiff -u -r0 -r1.3 xsrc/external/mit/libdrm/dist/Android.mk cvs rdiff -u -r1.1.1.12 -r0 xsrc/external/mit/libdrm/dist/Makefile.am cvs rdiff -u -r1.1.1.15 -r0 xsrc/external/mit/libdrm/dist/Makefile.in cvs rdiff -u -r1.1.1.16 -r0 xsrc/external/mit/libdrm/dist/aclocal.m4 cvs rdiff -u -r1.1.1.10 -r0 xsrc/external/mit/libdrm/dist/config.h.in cvs rdiff -u -r1.1.1.19 -r0 xsrc/external/mit/libdrm/dist/configure \ xsrc/external/mit/libdrm/dist/configure.ac cvs rdiff -u -r1.13 -r1.14 xsrc/external/mit/libdrm/dist/xf86atomic.h cvs rdiff -u -r1.25 -r1.26 xsrc/external/mit/libdrm/dist/xf86drm.c cvs rdiff -u -r1.11 -r1.12 xsrc/external/mit/libdrm/dist/xf86drm.h cvs rdiff -u -r1.15 -r1.16 xsrc/external/mit/libdrm/dist/xf86drmMode.c cvs rdiff -u -r1.9 -r1.10 xsrc/external/mit/libdrm/dist/xf86drmMode.h cvs rdiff -u -r1.1.1.4 -r0 xsrc/external/mit/libdrm/dist/amdgpu/Makefile.am cvs rdiff -u -r1.1.1.6 -r0 xsrc/external/mit/libdrm/dist/amdgpu/Makefile.in cvs rdiff -u -r1.1.1.8 -r0 \ xsrc/external/mit/libdrm/dist/amdgpu/amdgpu-symbol-check cvs rdiff -u -r1.1.1.5 -r0 xsrc/external/mit/libdrm/dist/build-aux/compile \ xsrc/external/mit/libdrm/dist/build-aux/depcomp \ xsrc/external/mit/libdrm/dist/build-aux/ltmain.sh cvs rdiff -u -r1.1.1.10 -r0 \ xsrc/external/mit/libdrm/dist/build-aux/config.guess \ xsrc/external/mit/libdrm/dist/build-aux/config.sub cvs rdiff -u -r1.1.1.4 -r0 xsrc/external/mit/libdrm/dist/build-aux/install-sh cvs rdiff -u -r1.1.1.6 -r0 xsrc/external/mit/libdrm/dist/build-aux/missing \ xsrc/external/mit/libdrm/dist/build-aux/test-driver cvs rdiff -u -r1.1.1.2 -r0 xsrc/external/mit/libdrm/dist/data/Makefile.am cvs rdiff -u -r1.1.1.3 -r0 xsrc/external/mit/libdrm/dist/data/Makefile.in cvs rdiff -u -r1.1.1.2 -r0 xsrc/external/mit/libdrm/dist/etnaviv/Makefile.am cvs rdiff -u -r1.1.1.5 -r0 xsrc/external/mit/libdrm/dist/etnaviv/Makefile.in cvs rdiff -u -r1.1.1.6 -r0 \ xsrc/external/mit/libdrm/dist/etnaviv/etnaviv-symbol-check cvs rdiff -u -r1.1.1.4 -r0 xsrc/external/mit/libdrm/dist/exynos/Makefile.am cvs rdiff -u -r1.1.1.10 -r0 xsrc/external/mit/libdrm/dist/exynos/Makefile.in cvs rdiff -u -r1.1.1.5 -r0 \ xsrc/external/mit/libdrm/dist/exynos/exynos-symbol-check cvs rdiff -u -r0 -r1.3 xsrc/external/mit/libdrm/dist/freedreno/Android.mk cvs rdiff -u -r1.1.1.7 -r0 \ xsrc/external/mit/libdrm/dist/freedreno/Makefile.am cvs rdiff -u -r1.1.1.10 -r0 \ xsrc/external/mit/libdrm/dist/freedreno/Makefile.in cvs rdiff -u -r1.1.1.6 -r0 \ xsrc/external/mit/libdrm/dist/freedreno/freedreno-symbol-check cvs rdiff -u -r1.12 -r1.13 xsrc/external/mit/libdrm/dist/include/drm/drm.h cvs rdiff -u -r0 -r1.3 xsrc/external/mit/libdrm/dist/intel/Android.mk cvs rdiff -u -r1.1.1.6 -r0 xsrc/external/mit/libdrm/dist/intel/Makefile.am \ xsrc/external/mit/libdrm/dist/intel/intel-symbol-check cvs rdiff -u -r1.1.1.14 -r0 xsrc/external/mit/libdrm/dist/intel/Makefile.in cvs rdiff -u -r1.18 -r1.19 \ xsrc/external/mit/libdrm/dist/intel/intel_bufmgr_gem.c cvs rdiff -u -r1.1.1.1 -r0 \ xsrc/external/mit/libdrm/dist/intel/tests/gen4-3d.batch.sh \ xsrc/external/mit/libdrm/dist/intel/tests/gen5-3d.batch.sh \ xsrc/external/mit/libdrm/dist/intel/tests/gen6-3d.batch.sh \ xsrc/external/mit/libdrm/dist/intel/tests/gen7-2d-copy.batch.sh \ xsrc/external/mit/libdrm/dist/intel/tests/gen7-3d.batch.sh \ xsrc/external/mit/libdrm/dist/intel/tests/gm45-3d.batch.sh cvs rdiff -u -r0 -r1.3 xsrc/external/mit/libdrm/dist/libkms/Android.mk cvs rdiff -u -r1.1.1.8 -r0 xsrc/external/mit/libdrm/dist/libkms/Makefile.am cvs rdiff -u -r1.1.1.14 -r0 xsrc/external/mit/libdrm/dist/libkms/Makefile.in cvs rdiff -u -r1.1.1.4 -r0 \ xsrc/external/mit/libdrm/dist/libkms/kms-symbol-check cvs rdiff -u -r1.1.1.7 -r0 xsrc/external/mit/libdrm/dist/m4/libtool.m4 cvs rdiff -u -r1.1.1.3 -r0 xsrc/external/mit/libdrm/dist/m4/ltoptions.m4 \ xsrc/external/mit/libdrm/dist/m4/ltsugar.m4 \ xsrc/external/mit/libdrm/dist/m4/ltversion.m4 \ xsrc/external/mit/libdrm/dist/m4/lt~obsolete.m4 cvs rdiff -u -r1.1.1.3 -r0 xsrc/external/mit/libdrm/dist/man/Makefile.am cvs rdiff -u -r1.1.1.9 -r0 xsrc/external/mit/libdrm/dist/man/Makefile.in cvs rdiff -u -r0 -r1.3 xsrc/external/mit/libdrm/dist/nouveau/Android.mk cvs rdiff -u -r1.1.1.7 -r0 xsrc/external/mit/libdrm/dist/nouveau/Makefile.am cvs rdiff -u -r1.1.1.14 -r0 xsrc/external/mit/libdrm/dist/nouveau/Makefile.in cvs rdiff -u -r1.1.1.5 -r0 \ xsrc/external/mit/libdrm/dist/nouveau/nouveau-symbol-check cvs rdiff -u -r1.1.1.4 -r0 xsrc/external/mit/libdrm/dist/omap/Makefile.am \ xsrc/external/mit/libdrm/dist/omap/omap-symbol-check cvs rdiff -u -r1.1.1.10 -r0 xsrc/external/mit/libdrm/dist/omap/Makefile.in cvs rdiff -u -r0 -r1.3 xsrc/external/mit/libdrm/dist/radeon/Android.mk cvs rdiff -u -r1.1.1.7 -r0 xsrc/external/mit/libdrm/dist/radeon/Makefile.am cvs rdiff -u -r1.1.1.14 -r0 xsrc/external/mit/libdrm/dist/radeon/Makefile.in cvs rdiff -u -r1.1.1.4 -r0 \ xsrc/external/mit/libdrm/dist/radeon/radeon-symbol-check cvs rdiff -u -r1.1.1.3 -r0 xsrc/external/mit/libdrm/dist/tegra/Makefile.am cvs rdiff -u -r1.1.1.8 -r0 xsrc/external/mit/libdrm/dist/tegra/Makefile.in cvs rdiff -u -r1.1.1.5 -r0 \ xsrc/external/mit/libdrm/dist/tegra/tegra-symbol-check cvs rdiff -u -r1.1.1.9 -r0 xsrc/external/mit/libdrm/dist/tests/Makefile.am cvs rdiff -u -r1.1.1.15 -r0 xsrc/external/mit/libdrm/dist/tests/Makefile.in cvs rdiff -u -r1.1.1.1 -r0 xsrc/external/mit/libdrm/dist/tests/random.c cvs rdiff -u -r1.1.1.5 -r0 \ xsrc/external/mit/libdrm/dist/tests/amdgpu/Makefile.am cvs rdiff -u -r1.1.1.7 -r0 \ xsrc/external/mit/libdrm/dist/tests/amdgpu/Makefile.in cvs rdiff -u -r1.1.1.3 -r0 \ xsrc/external/mit/libdrm/dist/tests/etnaviv/Makefile.am cvs rdiff -u -r1.1.1.5 -r0 \ xsrc/external/mit/libdrm/dist/tests/etnaviv/Makefile.in cvs rdiff -u -r1.1.1.6 -r0 \ xsrc/external/mit/libdrm/dist/tests/exynos/Makefile.am cvs rdiff -u -r1.1.1.10 -r0 \ xsrc/external/mit/libdrm/dist/tests/exynos/Makefile.in cvs rdiff -u -r1.1.1.2 -r0 \ xsrc/external/mit/libdrm/dist/tests/kms/Makefile.am cvs rdiff -u -r1.1.1.6 -r0 \ xsrc/external/mit/libdrm/dist/tests/kms/Makefile.in cvs rdiff -u -r1.1.1.5 -r0 \ xsrc/external/mit/libdrm/dist/tests/kmstest/Makefile.am cvs rdiff -u -r1.1.1.14 -r0 \ xsrc/external/mit/libdrm/dist/tests/kmstest/Makefile.in cvs rdiff -u -r1.1.1.6 -r0 \ xsrc/external/mit/libdrm/dist/tests/modeprint/Makefile.am cvs rdiff -u -r1.1.1.15 -r0 \ xsrc/external/mit/libdrm/dist/tests/modeprint/Makefile.in cvs rdiff -u -r0 -r1.3 \ xsrc/external/mit/libdrm/dist/tests/modetest/Android.mk cvs rdiff -u -r1.1.1.9 -r0 \ xsrc/external/mit/libdrm/dist/tests/modetest/Makefile.am cvs rdiff -u -r1.1.1.16 -r0 \ xsrc/external/mit/libdrm/dist/tests/modetest/Makefile.in cvs rdiff -u -r1.13 -r1.14 \ xsrc/external/mit/libdrm/dist/tests/modetest/modetest.c cvs rdiff -u -r1.1.1.3 -r0 \ xsrc/external/mit/libdrm/dist/tests/nouveau/Makefile.am cvs rdiff -u -r1.1.1.7 -r0 \ xsrc/external/mit/libdrm/dist/tests/nouveau/Makefile.in cvs rdiff -u -r1.1.1.4 -r0 \ xsrc/external/mit/libdrm/dist/tests/proptest/Makefile.am cvs rdiff -u -r1.1.1.8 -r0 \ xsrc/external/mit/libdrm/dist/tests/proptest/Makefile.in cvs rdiff -u -r1.1.1.4 -r0 \ xsrc/external/mit/libdrm/dist/tests/radeon/Makefile.am cvs rdiff -u -r1.1.1.10 -r0 \ xsrc/external/mit/libdrm/dist/tests/radeon/Makefile.in cvs rdiff -u -r1.1.1.3 -r0 \ xsrc/external/mit/libdrm/dist/tests/tegra/Makefile.am cvs rdiff -u -r1.1.1.8 -r0 \ xsrc/external/mit/libdrm/dist/tests/tegra/Makefile.in cvs rdiff -u -r1.1.1.1 -r0 \ xsrc/external/mit/libdrm/dist/tests/util/Makefile.am cvs rdiff -u -r1.1.1.5 -r0 \ xsrc/external/mit/libdrm/dist/tests/util/Makefile.in cvs rdiff -u -r1.1.1.5 -r0 \ xsrc/external/mit/libdrm/dist/tests/vbltest/Makefile.am cvs rdiff -u -r1.1.1.13 -r0 \ xsrc/external/mit/libdrm/dist/tests/vbltest/Makefile.in cvs rdiff -u -r1.1.1.2 -r0 xsrc/external/mit/libdrm/dist/vc4/Makefile.am cvs rdiff -u -r1.1.1.6 -r0 xsrc/external/mit/libdrm/dist/vc4/Makefile.in Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: xsrc/external/mit/libdrm/dist/xf86atomic.h diff -u xsrc/external/mit/libdrm/dist/xf86atomic.h:1.13 xsrc/external/mit/libdrm/dist/xf86atomic.h:1.14 --- xsrc/external/mit/libdrm/dist/xf86atomic.h:1.13 Mon Jul 15 05:42:34 2019 +++ xsrc/external/mit/libdrm/dist/xf86atomic.h Sun Nov 1 09:57:37 2020 @@ -54,6 +54,7 @@ typedef struct { #endif #if HAVE_LIB_ATOMIC_OPS +#define AO_REQUIRE_CAS #include <atomic_ops.h> #define HAS_ATOMIC_OPS 1 Index: xsrc/external/mit/libdrm/dist/xf86drm.c diff -u xsrc/external/mit/libdrm/dist/xf86drm.c:1.25 xsrc/external/mit/libdrm/dist/xf86drm.c:1.26 --- xsrc/external/mit/libdrm/dist/xf86drm.c:1.25 Sun Feb 23 09:59:00 2020 +++ xsrc/external/mit/libdrm/dist/xf86drm.c Sun Nov 1 09:57:37 2020 @@ -57,8 +57,16 @@ #ifdef MAJOR_IN_SYSMACROS #include <sys/sysmacros.h> #endif +#if HAVE_SYS_SYSCTL_H +#include <sys/sysctl.h> +#endif #include <math.h> +#if defined(__FreeBSD__) +#include <sys/param.h> +#include <sys/pciio.h> +#endif + #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) /* Not all systems have MAP_FAILED defined */ @@ -71,7 +79,7 @@ #include "util_math.h" -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) +#ifdef __DragonFly__ #define DRM_MAJOR 145 #endif @@ -117,6 +125,9 @@ struct drm_pciinfo { static drmServerInfoPtr drm_server_info; +static bool drmNodeIsDRM(int maj, int min); +static char *drmGetMinorNameForFD(int fd, int type); + drm_public void drmSetServerInfo(drmServerInfoPtr info) { drm_server_info = info; @@ -515,8 +526,28 @@ static int drmGetMinorBase(int type) }; } -static int drmGetMinorType(int minor) +static int drmGetMinorType(int major, int minor) { +#ifdef __FreeBSD__ + char name[SPECNAMELEN]; + int id; + + if (!devname_r(makedev(major, minor), S_IFCHR, name, sizeof(name))) + return -1; + + if (sscanf(name, "drm/%d", &id) != 1) { + // If not in /dev/drm/ we have the type in the name + if (sscanf(name, "dri/card%d\n", &id) >= 1) + return DRM_NODE_PRIMARY; + else if (sscanf(name, "dri/control%d\n", &id) >= 1) + return DRM_NODE_CONTROL; + else if (sscanf(name, "dri/renderD%d\n", &id) >= 1) + return DRM_NODE_RENDER; + return -1; + } + + minor = id; +#endif int type = minor >> 6; if (minor < 0) @@ -2748,6 +2779,19 @@ drm_public int drmIsMaster(int fd) drm_public char *drmGetDeviceNameFromFd(int fd) { +#ifdef __FreeBSD__ + struct stat sbuf; + int maj, min; + int nodetype; + + if (fstat(fd, &sbuf)) + return NULL; + + maj = major(sbuf.st_rdev); + min = minor(sbuf.st_rdev); + nodetype = drmGetMinorType(maj, min); + return drmGetMinorNameForFD(fd, nodetype); +#else char name[128]; struct stat sbuf; dev_t d; @@ -2770,6 +2814,7 @@ drm_public char *drmGetDeviceNameFromFd( return NULL; return strdup(name); +#endif } static bool drmNodeIsDRM(int maj, int min) @@ -2781,6 +2826,16 @@ static bool drmNodeIsDRM(int maj, int mi snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device/drm", maj, min); return stat(path, &sbuf) == 0; +#elif __FreeBSD__ + char name[SPECNAMELEN]; + + if (!devname_r(makedev(maj, min), S_IFCHR, name, sizeof(name))) + return 0; + /* Handle drm/ and dri/ as both are present in different FreeBSD version + * FreeBSD on amd64/i386/powerpc external kernel modules create node in + * in /dev/drm/ and links in /dev/dri while a WIP in kernel driver creates + * only device nodes in /dev/dri/ */ + return (!strncmp(name, "drm/", 4) || !strncmp(name, "dri/", 4)); #else return maj == DRM_MAJOR; #endif @@ -2802,7 +2857,7 @@ drm_public int drmGetNodeTypeFromFd(int return -1; } - type = drmGetMinorType(min); + type = drmGetMinorType(maj, min); if (type == -1) errno = ENODEV; return type; @@ -2884,6 +2939,49 @@ static char *drmGetMinorNameForFD(int fd closedir(sysdir); return NULL; +#elif __FreeBSD__ + struct stat sbuf; + char dname[SPECNAMELEN]; + const char *mname; + char name[SPECNAMELEN]; + int id, maj, min, nodetype, i; + + if (fstat(fd, &sbuf)) + return NULL; + + maj = major(sbuf.st_rdev); + min = minor(sbuf.st_rdev); + + if (!drmNodeIsDRM(maj, min) || !S_ISCHR(sbuf.st_mode)) + return NULL; + + if (!devname_r(sbuf.st_rdev, S_IFCHR, dname, sizeof(dname))) + return NULL; + + /* Handle both /dev/drm and /dev/dri + * FreeBSD on amd64/i386/powerpc external kernel modules create node in + * in /dev/drm/ and links in /dev/dri while a WIP in kernel driver creates + * only device nodes in /dev/dri/ */ + + /* Get the node type represented by fd so we can deduce the target name */ + nodetype = drmGetMinorType(maj, min); + if (nodetype == -1) + return (NULL); + mname = drmGetMinorName(type); + + for (i = 0; i < SPECNAMELEN; i++) { + if (isalpha(dname[i]) == 0 && dname[i] != '/') + break; + } + if (dname[i] == '\0') + return (NULL); + + id = (int)strtol(&dname[i], NULL, 10); + id -= drmGetMinorBase(nodetype); + snprintf(name, sizeof(name), DRM_DIR_NAME "/%s%d", mname, + id + drmGetMinorBase(type)); + + return strdup(name); #else struct stat sbuf; char buf[PATH_MAX + 1]; @@ -2968,10 +3066,10 @@ sysfs_uevent_get(const char *path, const /* Little white lie to avoid major rework of the existing code */ #define DRM_BUS_VIRTIO 0x10 -static int drmParseSubsystemType(int maj, int min) -{ #ifdef __linux__ - char path[PATH_MAX + 1]; +static int get_subsystem_type(const char *device_path) +{ + char path[PATH_MAX + 1] = ""; char link[PATH_MAX + 1] = ""; char *name; struct { @@ -2986,8 +3084,8 @@ static int drmParseSubsystemType(int maj { "/virtio", DRM_BUS_VIRTIO }, }; - snprintf(path, PATH_MAX, "/sys/dev/char/%d:%d/device/subsystem", - maj, min); + strncpy(path, device_path, PATH_MAX); + strncat(path, "/subsystem", PATH_MAX); if (readlink(path, link, PATH_MAX) < 0) return -errno; @@ -3002,6 +3100,29 @@ static int drmParseSubsystemType(int maj } return -EINVAL; +} +#endif + +static int drmParseSubsystemType(int maj, int min) +{ +#ifdef __linux__ + char path[PATH_MAX + 1] = ""; + char real_path[PATH_MAX + 1] = ""; + int subsystem_type; + + snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device", maj, min); + + subsystem_type = get_subsystem_type(path); + /* Try to get the parent (underlying) device type */ + if (subsystem_type == DRM_BUS_VIRTIO) { + /* Assume virtio-pci on error */ + if (!realpath(path, real_path)) + return DRM_BUS_VIRTIO; + strncat(path, "/..", PATH_MAX); + subsystem_type = get_subsystem_type(path); + if (subsystem_type < 0) + return DRM_BUS_VIRTIO; + } #elif defined(__NetBSD__) int type, fd; drmSetVersion sv; @@ -3069,6 +3190,7 @@ static int drmParseSubsystemType(int maj #endif } +#ifdef __linux__ static void get_pci_path(int maj, int min, char *pci_path) { @@ -3084,6 +3206,67 @@ get_pci_path(int maj, int min, char *pci if (term && strncmp(term, "/virtio", 7) == 0) *term = 0; } +#endif + +#ifdef __FreeBSD__ +static int get_sysctl_pci_bus_info(int maj, int min, drmPciBusInfoPtr info) +{ + char dname[SPECNAMELEN]; + char sysctl_name[16]; + char sysctl_val[256]; + size_t sysctl_len; + int id, type, nelem; + unsigned int rdev, majmin, domain, bus, dev, func; + + rdev = makedev(maj, min); + if (!devname_r(rdev, S_IFCHR, dname, sizeof(dname))) + return -EINVAL; + + if (sscanf(dname, "drm/%d\n", &id) != 1) + return -EINVAL; + type = drmGetMinorType(maj, min); + if (type == -1) + return -EINVAL; + + /* BUG: This above section is iffy, since it mandates that a driver will + * create both card and render node. + * If it does not, the next DRM device will create card#X and + * renderD#(128+X)-1. + * This is a possibility in FreeBSD but for now there is no good way for + * obtaining the info. + */ + switch (type) { + case DRM_NODE_PRIMARY: + break; + case DRM_NODE_CONTROL: + id -= 64; + break; + case DRM_NODE_RENDER: + id -= 128; + break; + } + if (id < 0) + return -EINVAL; + + if (snprintf(sysctl_name, sizeof(sysctl_name), "hw.dri.%d.busid", id) <= 0) + return -EINVAL; + sysctl_len = sizeof(sysctl_val); + if (sysctlbyname(sysctl_name, sysctl_val, &sysctl_len, NULL, 0)) + return -EINVAL; + + #define bus_fmt "pci:%04x:%02x:%02x.%u" + + nelem = sscanf(sysctl_val, bus_fmt, &domain, &bus, &dev, &func); + if (nelem != 4) + return -EINVAL; + info->domain = domain; + info->bus = bus; + info->dev = dev; + info->func = func; + + return 0; +} +#endif static int drmParsePciBusInfo(int maj, int min, drmPciBusInfoPtr info) { @@ -3181,7 +3364,7 @@ static int drmParsePciBusInfo(int maj, i struct drm_pciinfo pinfo; int fd, type; - type = drmGetMinorType(min); + type = drmGetMinorType(maj, min); if (type == -1) return -ENODEV; @@ -3201,6 +3384,8 @@ static int drmParsePciBusInfo(int maj, i info->func = pinfo.func; return 0; +#elif __FreeBSD__ + return get_sysctl_pci_bus_info(maj, min, info); #else #warning "Missing implementation of drmParsePciBusInfo" return -EINVAL; @@ -3389,7 +3574,7 @@ out: struct drm_pciinfo pinfo; int fd, type; - type = drmGetMinorType(min); + type = drmGetMinorType(maj, min); if (type == -1) return -ENODEV; @@ -3410,6 +3595,48 @@ out: device->subdevice_id = pinfo.subdevice_id; return 0; +#elif __FreeBSD__ + drmPciBusInfo info; + struct pci_conf_io pc; + struct pci_match_conf patterns[1]; + struct pci_conf results[1]; + int fd, error; + + if (get_sysctl_pci_bus_info(maj, min, &info) != 0) + return -EINVAL; + + fd = open("/dev/pci", O_RDONLY, 0); + if (fd < 0) + return -errno; + + bzero(&patterns, sizeof(patterns)); + patterns[0].pc_sel.pc_domain = info.domain; + patterns[0].pc_sel.pc_bus = info.bus; + patterns[0].pc_sel.pc_dev = info.dev; + patterns[0].pc_sel.pc_func = info.func; + patterns[0].flags = PCI_GETCONF_MATCH_DOMAIN | PCI_GETCONF_MATCH_BUS + | PCI_GETCONF_MATCH_DEV | PCI_GETCONF_MATCH_FUNC; + bzero(&pc, sizeof(struct pci_conf_io)); + pc.num_patterns = 1; + pc.pat_buf_len = sizeof(patterns); + pc.patterns = patterns; + pc.match_buf_len = sizeof(results); + pc.matches = results; + + if (ioctl(fd, PCIOCGETCONF, &pc) || pc.status == PCI_GETCONF_ERROR) { + error = errno; + close(fd); + return -error; + } + close(fd); + + device->vendor_id = results[0].pc_vendor; + device->device_id = results[0].pc_device; + device->subvendor_id = results[0].pc_subvendor; + device->subdevice_id = results[0].pc_subdevice; + device->revision_id = results[0].pc_revid; + + return 0; #else #warning "Missing implementation of drmParsePciDeviceInfo" return -EINVAL; @@ -3559,6 +3786,46 @@ free_device: return ret; } +#ifdef __linux__ +static int drm_usb_dev_path(int maj, int min, char *path, size_t len) +{ + char *value, *tmp_path, *slash; + + snprintf(path, len, "/sys/dev/char/%d:%d/device", maj, min); + + value = sysfs_uevent_get(path, "DEVTYPE"); + if (!value) + return -ENOENT; + + if (strcmp(value, "usb_device") == 0) + return 0; + if (strcmp(value, "usb_interface") != 0) + return -ENOTSUP; + + /* The parent of a usb_interface is a usb_device */ + + tmp_path = realpath(path, NULL); + if (!tmp_path) + return -errno; + + slash = strrchr(tmp_path, '/'); + if (!slash) { + free(tmp_path); + return -EINVAL; + } + + *slash = '\0'; + + if (snprintf(path, len, "%s", tmp_path) >= (int)len) { + free(tmp_path); + return -EINVAL; + } + + free(tmp_path); + return 0; +} +#endif + static int drmParseUsbBusInfo(int maj, int min, drmUsbBusInfoPtr info) { #ifdef __linux__ @@ -3566,7 +3833,9 @@ static int drmParseUsbBusInfo(int maj, i unsigned int bus, dev; int ret; - snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device", maj, min); + ret = drm_usb_dev_path(maj, min, path, sizeof(path)); + if (ret < 0) + return ret; value = sysfs_uevent_get(path, "BUSNUM"); if (!value) @@ -3605,7 +3874,9 @@ static int drmParseUsbDeviceInfo(int maj unsigned int vendor, product; int ret; - snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device", maj, min); + ret = drm_usb_dev_path(maj, min, path, sizeof(path)); + if (ret < 0) + return ret; value = sysfs_uevent_get(path, "PRODUCT"); if (!value) @@ -3979,7 +4250,7 @@ drm_public int drmGetDevice2(int fd, uin if (!drmNodeIsDRM(maj, min) || !S_ISCHR(sbuf.st_mode)) return -EINVAL; - node_type = drmGetMinorType(min); + node_type = drmGetMinorType(maj, min); if (node_type == -1) return -ENODEV; @@ -4202,6 +4473,8 @@ drm_public char *drmGetDeviceNameFromFd2 free(value); return strdup(path); +#elif __FreeBSD__ + return drmGetDeviceNameFromFd(fd); #else struct stat sbuf; char node[PATH_MAX + 1]; @@ -4218,7 +4491,7 @@ drm_public char *drmGetDeviceNameFromFd2 if (!drmNodeIsDRM(maj, min) || !S_ISCHR(sbuf.st_mode)) return NULL; - node_type = drmGetMinorType(min); + node_type = drmGetMinorType(maj, min); if (node_type == -1) return NULL; @@ -4424,6 +4697,21 @@ drm_public int drmSyncobjQuery(int fd, u return 0; } +drm_public int drmSyncobjQuery2(int fd, uint32_t *handles, uint64_t *points, + uint32_t handle_count, uint32_t flags) +{ + struct drm_syncobj_timeline_array args; + + memclear(args); + args.handles = (uintptr_t)handles; + args.points = (uintptr_t)points; + args.count_handles = handle_count; + args.flags = flags; + + return drmIoctl(fd, DRM_IOCTL_SYNCOBJ_QUERY, &args); +} + + drm_public int drmSyncobjTransfer(int fd, uint32_t dst_handle, uint64_t dst_point, uint32_t src_handle, uint64_t src_point, Index: xsrc/external/mit/libdrm/dist/xf86drm.h diff -u xsrc/external/mit/libdrm/dist/xf86drm.h:1.11 xsrc/external/mit/libdrm/dist/xf86drm.h:1.12 --- xsrc/external/mit/libdrm/dist/xf86drm.h:1.11 Sun Feb 23 09:59:00 2020 +++ xsrc/external/mit/libdrm/dist/xf86drm.h Sun Nov 1 09:57:37 2020 @@ -490,6 +490,29 @@ do { register unsigned int __old __asm(" : "cr0", "memory"); \ } while (0) +# elif defined (__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \ + || defined (__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) \ + || defined (__ARM_ARCH_6K__) || defined(__ARM_ARCH_6T2__) \ + || defined (__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \ + || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \ + || defined(__ARM_ARCH_7EM__) + /* excluding ARMv4/ARMv5 and lower (lacking ldrex/strex support) */ + #undef DRM_DEV_MODE + #define DRM_DEV_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) + + #define DRM_CAS(lock,old,new,__ret) \ + do { \ + __asm__ __volatile__ ( \ + "1: ldrex %0, [%1]\n" \ + " teq %0, %2\n" \ + " ite eq\n" \ + " strexeq %0, %3, [%1]\n" \ + " movne %0, #1\n" \ + : "=&r" (__ret) \ + : "r" (lock), "r" (old), "r" (new) \ + : "cc","memory"); \ + } while (0) + #endif /* architecture */ #endif /* __GNUC__ >= 2 */ @@ -905,6 +928,8 @@ extern int drmSyncobjTimelineWait(int fd uint32_t *first_signaled); extern int drmSyncobjQuery(int fd, uint32_t *handles, uint64_t *points, uint32_t handle_count); +extern int drmSyncobjQuery2(int fd, uint32_t *handles, uint64_t *points, + uint32_t handle_count, uint32_t flags); extern int drmSyncobjTransfer(int fd, uint32_t dst_handle, uint64_t dst_point, uint32_t src_handle, uint64_t src_point, Index: xsrc/external/mit/libdrm/dist/xf86drmMode.c diff -u xsrc/external/mit/libdrm/dist/xf86drmMode.c:1.15 xsrc/external/mit/libdrm/dist/xf86drmMode.c:1.16 --- xsrc/external/mit/libdrm/dist/xf86drmMode.c:1.15 Mon Jul 15 05:42:34 2019 +++ xsrc/external/mit/libdrm/dist/xf86drmMode.c Sun Nov 1 09:57:37 2020 @@ -42,7 +42,7 @@ #include <stdint.h> #include <stdlib.h> #include <sys/ioctl.h> -#ifdef HAVE_SYS_SYSCTL_H +#if HAVE_SYS_SYSCTL_H #include <sys/sysctl.h> #endif #include <stdio.h> @@ -683,6 +683,7 @@ drm_public void drmModeFreeProperty(drmM drmFree(ptr->values); drmFree(ptr->enums); + drmFree(ptr->blob_ids); drmFree(ptr); } @@ -800,21 +801,13 @@ drm_public int drmCheckModesettingSuppor if (found) return 0; #elif defined (__FreeBSD__) || defined (__FreeBSD_kernel__) - char kbusid[1024], sbusid[1024]; + char sbusid[1024]; char oid[128]; - int domain, bus, dev, func; int i, modesetting, ret; size_t len; - ret = sscanf(busid, "pci:%04x:%02x:%02x.%d", &domain, &bus, &dev, - &func); - if (ret != 4) - return -EINVAL; - snprintf(kbusid, sizeof(kbusid), "pci:%04x:%02x:%02x.%d", domain, bus, - dev, func); - /* How many GPUs do we expect in the machine ? */ - for (i = 0; i < 16; i++) { + for (i = 0; i < 10; i++) { snprintf(oid, sizeof(oid), "hw.dri.%d.busid", i); len = sizeof(sbusid); ret = sysctlbyname(oid, sbusid, &len, NULL, 0); @@ -823,7 +816,7 @@ drm_public int drmCheckModesettingSuppor continue; return -EINVAL; } - if (strcmp(sbusid, kbusid) != 0) + if (strcmp(sbusid, busid) != 0) continue; snprintf(oid, sizeof(oid), "hw.dri.%d.modesetting", i); len = sizeof(modesetting); @@ -1594,3 +1587,38 @@ drmModeRevokeLease(int fd, uint32_t less return 0; return -errno; } + +drm_public drmModeFB2Ptr +drmModeGetFB2(int fd, uint32_t fb_id) +{ + struct drm_mode_fb_cmd2 get = { + .fb_id = fb_id, + }; + drmModeFB2Ptr ret; + int err; + + err = DRM_IOCTL(fd, DRM_IOCTL_MODE_GETFB2, &get); + if (err != 0) + return NULL; + + ret = drmMalloc(sizeof(drmModeFB2)); + if (!ret) + return NULL; + + ret->fb_id = fb_id; + ret->width = get.width; + ret->height = get.height; + ret->pixel_format = get.pixel_format; + ret->flags = get.flags; + ret->modifier = get.modifier[0]; + memcpy(ret->handles, get.handles, sizeof(uint32_t) * 4); + memcpy(ret->pitches, get.pitches, sizeof(uint32_t) * 4); + memcpy(ret->offsets, get.offsets, sizeof(uint32_t) * 4); + + return ret; +} + +drm_public void drmModeFreeFB2(drmModeFB2Ptr ptr) +{ + drmFree(ptr); +} Index: xsrc/external/mit/libdrm/dist/xf86drmMode.h diff -u xsrc/external/mit/libdrm/dist/xf86drmMode.h:1.9 xsrc/external/mit/libdrm/dist/xf86drmMode.h:1.10 --- xsrc/external/mit/libdrm/dist/xf86drmMode.h:1.9 Mon Jul 15 05:42:34 2019 +++ xsrc/external/mit/libdrm/dist/xf86drmMode.h Sun Nov 1 09:57:37 2020 @@ -41,6 +41,8 @@ extern "C" { #endif #include <drm.h> +#include <stddef.h> +#include <stdint.h> /* * This is the interface for modesetting for drm. @@ -160,6 +162,7 @@ extern "C" { #define DRM_MODE_CONNECTOR_VIRTUAL 15 #define DRM_MODE_CONNECTOR_DSI 16 #define DRM_MODE_CONNECTOR_DPI 17 +#define DRM_MODE_CONNECTOR_WRITEBACK 18 #define DRM_MODE_PROP_PENDING (1<<0) #define DRM_MODE_PROP_RANGE (1<<1) @@ -223,6 +226,19 @@ typedef struct _drmModeFB { uint32_t handle; } drmModeFB, *drmModeFBPtr; +typedef struct _drmModeFB2 { + uint32_t fb_id; + uint32_t width, height; + uint32_t pixel_format; /* fourcc code from drm_fourcc.h */ + uint64_t modifier; /* applies to all buffers */ + uint32_t flags; + + /* per-plane GEM handle; may be duplicate entries for multiple planes */ + uint32_t handles[4]; + uint32_t pitches[4]; /* bytes */ + uint32_t offsets[4]; /* bytes */ +} drmModeFB2, *drmModeFB2Ptr; + typedef struct drm_clip_rect drmModeClip, *drmModeClipPtr; typedef struct _drmModePropertyBlob { @@ -341,6 +357,7 @@ typedef struct _drmModePlaneRes { extern void drmModeFreeModeInfo( drmModeModeInfoPtr ptr ); extern void drmModeFreeResources( drmModeResPtr ptr ); extern void drmModeFreeFB( drmModeFBPtr ptr ); +extern void drmModeFreeFB2( drmModeFB2Ptr ptr ); extern void drmModeFreeCrtc( drmModeCrtcPtr ptr ); extern void drmModeFreeConnector( drmModeConnectorPtr ptr ); extern void drmModeFreeEncoder( drmModeEncoderPtr ptr ); @@ -360,6 +377,7 @@ extern drmModeResPtr drmModeGetResources * Retrieve information about framebuffer bufferId */ extern drmModeFBPtr drmModeGetFB(int fd, uint32_t bufferId); +extern drmModeFB2Ptr drmModeGetFB2(int fd, uint32_t bufferId); /** * Creates a new framebuffer with an buffer object as its scanout buffer. Index: xsrc/external/mit/libdrm/dist/include/drm/drm.h diff -u xsrc/external/mit/libdrm/dist/include/drm/drm.h:1.12 xsrc/external/mit/libdrm/dist/include/drm/drm.h:1.13 --- xsrc/external/mit/libdrm/dist/include/drm/drm.h:1.12 Mon Jul 15 05:42:34 2019 +++ xsrc/external/mit/libdrm/dist/include/drm/drm.h Sun Nov 1 09:57:38 2020 @@ -775,11 +775,12 @@ struct drm_syncobj_array { __u32 pad; }; +#define DRM_SYNCOBJ_QUERY_FLAGS_LAST_SUBMITTED (1 << 0) /* last available point on timeline syncobj */ struct drm_syncobj_timeline_array { __u64 handles; __u64 points; __u32 count_handles; - __u32 pad; + __u32 flags; }; @@ -944,6 +945,8 @@ extern "C" { #define DRM_IOCTL_SYNCOBJ_TRANSFER DRM_IOWR(0xCC, struct drm_syncobj_transfer) #define DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL DRM_IOWR(0xCD, struct drm_syncobj_timeline_array) +#define DRM_IOCTL_MODE_GETFB2 DRM_IOWR(0xCE, struct drm_mode_fb_cmd2) + /** * Device specific ioctls should only be in their respective headers * The device specific ioctl range is from 0x40 to 0x9f. Index: xsrc/external/mit/libdrm/dist/intel/intel_bufmgr_gem.c diff -u xsrc/external/mit/libdrm/dist/intel/intel_bufmgr_gem.c:1.18 xsrc/external/mit/libdrm/dist/intel/intel_bufmgr_gem.c:1.19 --- xsrc/external/mit/libdrm/dist/intel/intel_bufmgr_gem.c:1.18 Wed Aug 7 13:02:16 2019 +++ xsrc/external/mit/libdrm/dist/intel/intel_bufmgr_gem.c Sun Nov 1 09:57:38 2020 @@ -1069,6 +1069,28 @@ check_bo_alloc_userptr(drm_intel_bufmgr tiling_mode, stride, size, flags); } +static int get_tiling_mode(drm_intel_bufmgr_gem *bufmgr_gem, + uint32_t gem_handle, + uint32_t *tiling_mode, + uint32_t *swizzle_mode) +{ + struct drm_i915_gem_get_tiling get_tiling = { + .handle = gem_handle, + }; + int ret; + + ret = drmIoctl(bufmgr_gem->fd, + DRM_IOCTL_I915_GEM_GET_TILING, + &get_tiling); + if (ret != 0 && errno != EOPNOTSUPP) + return ret; + + *tiling_mode = get_tiling.tiling_mode; + *swizzle_mode = get_tiling.swizzle_mode; + + return 0; +} + /** * Returns a drm_intel_bo wrapping the given buffer object handle. * @@ -1084,7 +1106,6 @@ drm_intel_bo_gem_create_from_name(drm_in drm_intel_bo_gem *bo_gem; int ret; struct drm_gem_open open_arg; - struct drm_i915_gem_get_tiling get_tiling; /* At the moment most applications only have a few named bo. * For instance, in a DRI client only the render buffers passed @@ -1146,16 +1167,11 @@ drm_intel_bo_gem_create_from_name(drm_in HASH_ADD(name_hh, bufmgr_gem->name_table, global_name, sizeof(bo_gem->global_name), bo_gem); - memclear(get_tiling); - get_tiling.handle = bo_gem->gem_handle; - ret = drmIoctl(bufmgr_gem->fd, - DRM_IOCTL_I915_GEM_GET_TILING, - &get_tiling); + ret = get_tiling_mode(bufmgr_gem, bo_gem->gem_handle, + &bo_gem->tiling_mode, &bo_gem->swizzle_mode); if (ret != 0) goto err_unref; - bo_gem->tiling_mode = get_tiling.tiling_mode; - bo_gem->swizzle_mode = get_tiling.swizzle_mode; /* XXX stride is unknown */ drm_intel_bo_gem_set_in_aperture_size(bufmgr_gem, bo_gem, 0); DBG("bo_create_from_handle: %d (%s)\n", handle, bo_gem->name); @@ -2634,7 +2650,6 @@ drm_intel_bo_gem_create_from_prime(drm_i int ret; uint32_t handle; drm_intel_bo_gem *bo_gem; - struct drm_i915_gem_get_tiling get_tiling; pthread_mutex_lock(&bufmgr_gem->lock); ret = drmPrimeFDToHandle(bufmgr_gem->fd, prime_fd, &handle); @@ -2688,15 +2703,11 @@ drm_intel_bo_gem_create_from_prime(drm_i bo_gem->has_error = false; bo_gem->reusable = false; - memclear(get_tiling); - get_tiling.handle = bo_gem->gem_handle; - if (drmIoctl(bufmgr_gem->fd, - DRM_IOCTL_I915_GEM_GET_TILING, - &get_tiling)) + ret = get_tiling_mode(bufmgr_gem, handle, + &bo_gem->tiling_mode, &bo_gem->swizzle_mode); + if (ret) goto err; - bo_gem->tiling_mode = get_tiling.tiling_mode; - bo_gem->swizzle_mode = get_tiling.swizzle_mode; /* XXX stride is unknown */ drm_intel_bo_gem_set_in_aperture_size(bufmgr_gem, bo_gem, 0); @@ -2717,7 +2728,7 @@ drm_intel_bo_gem_export_to_prime(drm_int drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo; if (drmPrimeHandleToFD(bufmgr_gem->fd, bo_gem->gem_handle, - DRM_CLOEXEC, prime_fd) != 0) + DRM_CLOEXEC | DRM_RDWR, prime_fd) != 0) return -errno; bo_gem->reusable = false; Index: xsrc/external/mit/libdrm/dist/tests/modetest/modetest.c diff -u xsrc/external/mit/libdrm/dist/tests/modetest/modetest.c:1.13 xsrc/external/mit/libdrm/dist/tests/modetest/modetest.c:1.14 --- xsrc/external/mit/libdrm/dist/tests/modetest/modetest.c:1.13 Mon Jul 15 05:42:34 2019 +++ xsrc/external/mit/libdrm/dist/tests/modetest/modetest.c Sun Nov 1 09:57:40 2020 @@ -51,9 +51,10 @@ #include <errno.h> #include <poll.h> #include <sys/time.h> -#ifdef HAVE_SYS_SELECT_H +#if HAVE_SYS_SELECT_H #include <sys/select.h> #endif +#include <math.h> #include "xf86drm.h" #include "xf86drmMode.h" @@ -99,14 +100,16 @@ struct plane { }; struct resources { - drmModeRes *res; - drmModePlaneRes *plane_res; - struct crtc *crtcs; + int count_crtcs; struct encoder *encoders; + int count_encoders; struct connector *connectors; + int count_connectors; struct fb *fbs; + int count_fbs; struct plane *planes; + uint32_t count_planes; }; struct device { @@ -132,6 +135,12 @@ static inline int64_t U642I64(uint64_t v return (int64_t)*((int64_t *)&val); } +static float mode_vrefresh(drmModeModeInfo *mode) +{ + return mode->clock * 1000.00 + / (mode->htotal * mode->vtotal); +} + #define bit_name_fn(res) \ const char * res##_str(int type) { \ unsigned int i; \ @@ -192,7 +201,7 @@ static void dump_encoders(struct device printf("Encoders:\n"); printf("id\tcrtc\ttype\tpossible crtcs\tpossible clones\t\n"); - for (i = 0; i < dev->resources->res->count_encoders; i++) { + for (i = 0; i < dev->resources->count_encoders; i++) { encoder = dev->resources->encoders[i].encoder; if (!encoder) continue; @@ -207,11 +216,12 @@ static void dump_encoders(struct device printf("\n"); } -static void dump_mode(drmModeModeInfo *mode) +static void dump_mode(drmModeModeInfo *mode, int index) { - printf(" %s %d %d %d %d %d %d %d %d %d %d", + printf(" #%i %s %.2f %d %d %d %d %d %d %d %d %d", + index, mode->name, - mode->vrefresh, + mode_vrefresh(mode), mode->hdisplay, mode->hsync_start, mode->hsync_end, @@ -426,7 +436,7 @@ static void dump_connectors(struct devic printf("Connectors:\n"); printf("id\tencoder\tstatus\t\tname\t\tsize (mm)\tmodes\tencoders\n"); - for (i = 0; i < dev->resources->res->count_connectors; i++) { + for (i = 0; i < dev->resources->count_connectors; i++) { struct connector *_connector = &dev->resources->connectors[i]; drmModeConnector *connector = _connector->connector; if (!connector) @@ -446,10 +456,10 @@ static void dump_connectors(struct devic if (connector->count_modes) { printf(" modes:\n"); - printf("\tname refresh (Hz) hdisp hss hse htot vdisp " + printf("\tindex name refresh (Hz) hdisp hss hse htot vdisp " "vss vse vtot)\n"); for (j = 0; j < connector->count_modes; j++) - dump_mode(&connector->modes[j]); + dump_mode(&connector->modes[j], j); } if (_connector->props) { @@ -470,7 +480,7 @@ static void dump_crtcs(struct device *de printf("CRTCs:\n"); printf("id\tfb\tpos\tsize\n"); - for (i = 0; i < dev->resources->res->count_crtcs; i++) { + for (i = 0; i < dev->resources->count_crtcs; i++) { struct crtc *_crtc = &dev->resources->crtcs[i]; drmModeCrtc *crtc = _crtc->crtc; if (!crtc) @@ -481,7 +491,7 @@ static void dump_crtcs(struct device *de crtc->buffer_id, crtc->x, crtc->y, crtc->width, crtc->height); - dump_mode(&crtc->mode); + dump_mode(&crtc->mode, 0); if (_crtc->props) { printf(" props:\n"); @@ -503,7 +513,7 @@ static void dump_framebuffers(struct dev printf("Frame buffers:\n"); printf("id\tsize\tpitch\n"); - for (i = 0; i < dev->resources->res->count_fbs; i++) { + for (i = 0; i < dev->resources->count_fbs; i++) { fb = dev->resources->fbs[i].fb; if (!fb) continue; @@ -523,10 +533,7 @@ static void dump_planes(struct device *d printf("Planes:\n"); printf("id\tcrtc\tfb\tCRTC x,y\tx,y\tgamma size\tpossible crtcs\n"); - if (!dev->resources->plane_res) - return; - - for (i = 0; i < dev->resources->plane_res->count_planes; i++) { + for (i = 0; i < dev->resources->count_planes; i++) { struct plane *plane = &dev->resources->planes[i]; drmModePlane *ovr = plane->plane; if (!ovr) @@ -567,11 +574,11 @@ static void free_resources(struct resour if (!res) return; -#define free_resource(_res, __res, type, Type) \ +#define free_resource(_res, type, Type) \ do { \ if (!(_res)->type##s) \ break; \ - for (i = 0; i < (int)(_res)->__res->count_##type##s; ++i) { \ + for (i = 0; i < (int)(_res)->count_##type##s; ++i) { \ if (!(_res)->type##s[i].type) \ break; \ drmModeFree##Type((_res)->type##s[i].type); \ @@ -579,42 +586,38 @@ static void free_resources(struct resour free((_res)->type##s); \ } while (0) -#define free_properties(_res, __res, type) \ +#define free_properties(_res, type) \ do { \ - for (i = 0; i < (int)(_res)->__res->count_##type##s; ++i) { \ - drmModeFreeObjectProperties(res->type##s[i].props); \ + for (i = 0; i < (int)(_res)->count_##type##s; ++i) { \ + unsigned int j; \ + for (j = 0; j < res->type##s[i].props->count_props; ++j)\ + drmModeFreeProperty(res->type##s[i].props_info[j]);\ free(res->type##s[i].props_info); \ + drmModeFreeObjectProperties(res->type##s[i].props); \ } \ } while (0) - if (res->res) { - free_properties(res, res, crtc); - - free_resource(res, res, crtc, Crtc); - free_resource(res, res, encoder, Encoder); + free_properties(res, plane); + free_resource(res, plane, Plane); - for (i = 0; i < res->res->count_connectors; i++) - free(res->connectors[i].name); + free_properties(res, connector); + free_properties(res, crtc); - free_resource(res, res, connector, Connector); - free_resource(res, res, fb, FB); + for (i = 0; i < res->count_connectors; i++) + free(res->connectors[i].name); - drmModeFreeResources(res->res); - } - - if (res->plane_res) { - free_properties(res, plane_res, plane); - - free_resource(res, plane_res, plane, Plane); - - drmModeFreePlaneResources(res->plane_res); - } + free_resource(res, fb, FB); + free_resource(res, connector, Connector); + free_resource(res, encoder, Encoder); + free_resource(res, crtc, Crtc); free(res); } static struct resources *get_resources(struct device *dev) { + drmModeRes *_res; + drmModePlaneRes *plane_res; struct resources *res; int i; @@ -624,40 +627,51 @@ static struct resources *get_resources(s drmSetClientCap(dev->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1); - res->res = drmModeGetResources(dev->fd); - if (!res->res) { + _res = drmModeGetResources(dev->fd); + if (!_res) { fprintf(stderr, "drmModeGetResources failed: %s\n", strerror(errno)); - goto error; + free(res); + return NULL; } - res->crtcs = calloc(res->res->count_crtcs, sizeof(*res->crtcs)); - res->encoders = calloc(res->res->count_encoders, sizeof(*res->encoders)); - res->connectors = calloc(res->res->count_connectors, sizeof(*res->connectors)); - res->fbs = calloc(res->res->count_fbs, sizeof(*res->fbs)); + res->count_crtcs = _res->count_crtcs; + res->count_encoders = _res->count_encoders; + res->count_connectors = _res->count_connectors; + res->count_fbs = _res->count_fbs; + + res->crtcs = calloc(res->count_crtcs, sizeof(*res->crtcs)); + res->encoders = calloc(res->count_encoders, sizeof(*res->encoders)); + res->connectors = calloc(res->count_connectors, sizeof(*res->connectors)); + res->fbs = calloc(res->count_fbs, sizeof(*res->fbs)); - if (!res->crtcs || !res->encoders || !res->connectors || !res->fbs) + if (!res->crtcs || !res->encoders || !res->connectors || !res->fbs) { + drmModeFreeResources(_res); goto error; + } #define get_resource(_res, __res, type, Type) \ do { \ - for (i = 0; i < (int)(_res)->__res->count_##type##s; ++i) { \ - (_res)->type##s[i].type = \ - drmModeGet##Type(dev->fd, (_res)->__res->type##s[i]); \ - if (!(_res)->type##s[i].type) \ + for (i = 0; i < (int)(_res)->count_##type##s; ++i) { \ + uint32_t type##id = (__res)->type##s[i]; \ + (_res)->type##s[i].type = \ + drmModeGet##Type(dev->fd, type##id); \ + if (!(_res)->type##s[i].type) \ fprintf(stderr, "could not get %s %i: %s\n", \ - #type, (_res)->__res->type##s[i], \ + #type, type##id, \ strerror(errno)); \ } \ } while (0) - get_resource(res, res, crtc, Crtc); - get_resource(res, res, encoder, Encoder); - get_resource(res, res, connector, Connector); - get_resource(res, res, fb, FB); + get_resource(res, _res, crtc, Crtc); + get_resource(res, _res, encoder, Encoder); + get_resource(res, _res, connector, Connector); + get_resource(res, _res, fb, FB); + + drmModeFreeResources(_res); /* Set the name of all connectors based on the type name and the per-type ID. */ - for (i = 0; i < res->res->count_connectors; i++) { + for (i = 0; i < res->count_connectors; i++) { struct connector *connector = &res->connectors[i]; drmModeConnector *conn = connector->connector; int num; @@ -669,9 +683,9 @@ static struct resources *get_resources(s goto error; } -#define get_properties(_res, __res, type, Type) \ +#define get_properties(_res, type, Type) \ do { \ - for (i = 0; i < (int)(_res)->__res->count_##type##s; ++i) { \ + for (i = 0; i < (int)(_res)->count_##type##s; ++i) { \ struct type *obj = &res->type##s[i]; \ unsigned int j; \ obj->props = \ @@ -694,25 +708,30 @@ static struct resources *get_resources(s } \ } while (0) - get_properties(res, res, crtc, CRTC); - get_properties(res, res, connector, CONNECTOR); + get_properties(res, crtc, CRTC); + get_properties(res, connector, CONNECTOR); - for (i = 0; i < res->res->count_crtcs; ++i) + for (i = 0; i < res->count_crtcs; ++i) res->crtcs[i].mode = &res->crtcs[i].crtc->mode; - res->plane_res = drmModeGetPlaneResources(dev->fd); - if (!res->plane_res) { + plane_res = drmModeGetPlaneResources(dev->fd); + if (!plane_res) { fprintf(stderr, "drmModeGetPlaneResources failed: %s\n", strerror(errno)); return res; } - res->planes = calloc(res->plane_res->count_planes, sizeof(*res->planes)); - if (!res->planes) + res->count_planes = plane_res->count_planes; + + res->planes = calloc(res->count_planes, sizeof(*res->planes)); + if (!res->planes) { + drmModeFreePlaneResources(plane_res); goto error; + } get_resource(res, plane_res, plane, Plane); - get_properties(res, plane_res, plane, PLANE); + drmModeFreePlaneResources(plane_res); + get_properties(res, plane, PLANE); return res; @@ -721,17 +740,31 @@ error: return NULL; } -static int get_crtc_index(struct device *dev, uint32_t id) +static struct crtc *get_crtc_by_id(struct device *dev, uint32_t id) { int i; - for (i = 0; i < dev->resources->res->count_crtcs; ++i) { + for (i = 0; i < dev->resources->count_crtcs; ++i) { drmModeCrtc *crtc = dev->resources->crtcs[i].crtc; if (crtc && crtc->crtc_id == id) - return i; + return &dev->resources->crtcs[i]; } - return -1; + return NULL; +} + +static uint32_t get_crtc_mask(struct device *dev, struct crtc *crtc) +{ + unsigned int i; + + for (i = 0; i < (unsigned int)dev->resources->count_crtcs; i++) { + if (crtc->crtc->crtc_id == dev->resources->crtcs[i].crtc->crtc_id) + return 1 << i; + } + /* Unreachable: crtc->crtc is one of resources->crtcs[] */ + /* Don't return zero or static analysers will complain */ + abort(); + return 0; } static drmModeConnector *get_connector_by_name(struct device *dev, const char *name) @@ -739,7 +772,7 @@ static drmModeConnector *get_connector_b struct connector *connector; int i; - for (i = 0; i < dev->resources->res->count_connectors; i++) { + for (i = 0; i < dev->resources->count_connectors; i++) { connector = &dev->resources->connectors[i]; if (strcmp(connector->name, name) == 0) @@ -754,7 +787,7 @@ static drmModeConnector *get_connector_b drmModeConnector *connector; int i; - for (i = 0; i < dev->resources->res->count_connectors; i++) { + for (i = 0; i < dev->resources->count_connectors; i++) { connector = dev->resources->connectors[i].connector; if (connector && connector->connector_id == id) return connector; @@ -768,7 +801,7 @@ static drmModeEncoder *get_encoder_by_id drmModeEncoder *encoder; int i; - for (i = 0; i < dev->resources->res->count_encoders; i++) { + for (i = 0; i < dev->resources->count_encoders; i++) { encoder = dev->resources->encoders[i].encoder; if (encoder && encoder->encoder_id == id) return encoder; @@ -795,7 +828,7 @@ struct pipe_arg { uint32_t crtc_id; char mode_str[64]; char format_str[5]; - unsigned int vrefresh; + float vrefresh; unsigned int fourcc; drmModeModeInfo *mode; struct crtc *crtc; @@ -822,7 +855,7 @@ struct plane_arg { static drmModeModeInfo * connector_find_mode(struct device *dev, uint32_t con_id, const char *mode_str, - const unsigned int vrefresh) + const float vrefresh) { drmModeConnector *connector; drmModeModeInfo *mode; @@ -832,16 +865,27 @@ connector_find_mode(struct device *dev, if (!connector || !connector->count_modes) return NULL; + /* Pick by Index */ + if (mode_str[0] == '#') { + int index = atoi(mode_str + 1); + + if (index >= connector->count_modes || index < 0) + return NULL; + return &connector->modes[index]; + } + + /* Pick by Name */ for (i = 0; i < connector->count_modes; i++) { mode = &connector->modes[i]; if (!strcmp(mode->name, mode_str)) { - /* If the vertical refresh frequency is not specified then return the - * first mode that match with the name. Else, return the mode that match - * the name and the specified vertical refresh frequency. + /* If the vertical refresh frequency is not specified + * then return the first mode that match with the name. + * Else, return the mode that match the name and + * the specified vertical refresh frequency. */ if (vrefresh == 0) return mode; - else if (mode->vrefresh == vrefresh) + else if (fabs(mode_vrefresh(mode) - vrefresh) < 0.005) return mode; } } @@ -861,7 +905,7 @@ static struct crtc *pipe_find_crtc(struc uint32_t crtcs_for_connector = 0; drmModeConnector *connector; drmModeEncoder *encoder; - int idx; + struct crtc *crtc; connector = get_connector_by_id(dev, pipe->con_ids[i]); if (!connector) @@ -873,10 +917,10 @@ static struct crtc *pipe_find_crtc(struc continue; crtcs_for_connector |= encoder->possible_crtcs; - - idx = get_crtc_index(dev, encoder->crtc_id); - if (idx >= 0) - active_crtcs |= 1 << idx; + crtc = get_crtc_by_id(dev, encoder->crtc_id); + if (!crtc) + continue; + active_crtcs |= get_crtc_mask(dev, crtc); } possible_crtcs &= crtcs_for_connector; @@ -907,7 +951,13 @@ static int pipe_find_crtc_and_mode(struc mode = connector_find_mode(dev, pipe->con_ids[i], pipe->mode_str, pipe->vrefresh); if (mode == NULL) { - fprintf(stderr, + if (pipe->vrefresh) + fprintf(stderr, + "failed to find mode " + "\"%s-%.2fHz\" for connector %s\n", + pipe->mode_str, pipe->vrefresh, pipe->cons[i]); + else + fprintf(stderr, "failed to find mode \"%s\" for connector %s\n", pipe->mode_str, pipe->cons[i]); return -EINVAL; @@ -918,16 +968,10 @@ static int pipe_find_crtc_and_mode(struc * locate a CRTC that can be attached to all the connectors. */ if (pipe->crtc_id != (uint32_t)-1) { - for (i = 0; i < dev->resources->res->count_crtcs; i++) { - struct crtc *crtc = &dev->resources->crtcs[i]; - - if (pipe->crtc_id == crtc->crtc->crtc_id) { - pipe->crtc = crtc; - break; - } - } + pipe->crtc = get_crtc_by_id(dev, pipe->crtc_id); } else { pipe->crtc = pipe_find_crtc(dev, pipe); + pipe->crtc_id = pipe->crtc->crtc->crtc_id; } if (!pipe->crtc) { @@ -965,9 +1009,9 @@ static bool set_property(struct device * p->obj_type = 0; p->prop_id = 0; -#define find_object(_res, __res, type, Type) \ +#define find_object(_res, type, Type) \ do { \ - for (i = 0; i < (int)(_res)->__res->count_##type##s; ++i) { \ + for (i = 0; i < (int)(_res)->count_##type##s; ++i) { \ struct type *obj = &(_res)->type##s[i]; \ if (obj->type->type##_id != p->obj_id) \ continue; \ @@ -978,11 +1022,11 @@ static bool set_property(struct device * } \ } while(0) \ - find_object(dev->resources, res, crtc, CRTC); + find_object(dev->resources, crtc, CRTC); if (p->obj_type == 0) - find_object(dev->resources, res, connector, CONNECTOR); + find_object(dev->resources, connector, CONNECTOR); if (p->obj_type == 0) - find_object(dev->resources, plane_res, plane, PLANE); + find_object(dev->resources, plane, PLANE); if (p->obj_type == 0) { fprintf(stderr, "Object %i not found, can't set property\n", p->obj_id); @@ -1041,7 +1085,7 @@ page_flip_handler(int fd, unsigned int f else new_fb_id = pipe->fb_id[0]; - drmModePageFlip(fd, pipe->crtc->crtc->crtc_id, new_fb_id, + drmModePageFlip(fd, pipe->crtc_id, new_fb_id, DRM_MODE_PAGE_FLIP_EVENT, pipe); pipe->current_fb_id = new_fb_id; pipe->swap_count++; @@ -1128,26 +1172,41 @@ static void set_gamma(struct device *dev } } +static int +bo_fb_create(int fd, unsigned int fourcc, const uint32_t w, const uint32_t h, + enum util_fill_pattern pat, struct bo **out_bo, unsigned int *out_fb_id) +{ + uint32_t handles[4] = {0}, pitches[4] = {0}, offsets[4] = {0}; + struct bo *bo; + unsigned int fb_id; + + bo = bo_create(fd, fourcc, w, h, handles, pitches, offsets, pat); + + if (bo == NULL) + return -1; + + if (drmModeAddFB2(fd, w, h, fourcc, handles, pitches, offsets, &fb_id, 0)) { + fprintf(stderr, "failed to add fb (%ux%u): %s\n", w, h, strerror(errno)); + bo_destroy(bo); + return -1; + } + *out_bo = bo; + *out_fb_id = fb_id; + return 0; +} + static int atomic_set_plane(struct device *dev, struct plane_arg *p, int pattern, bool update) { - uint32_t handles[4] = {0}, pitches[4] = {0}, offsets[4] = {0}; struct bo *plane_bo; int crtc_x, crtc_y, crtc_w, crtc_h; struct crtc *crtc = NULL; - unsigned int i; unsigned int old_fb_id; /* Find an unused plane which can be connected to our CRTC. Find the * CRTC index first, then iterate over available planes. */ - for (i = 0; i < (unsigned int)dev->resources->res->count_crtcs; i++) { - if (p->crtc_id == dev->resources->res->crtcs[i]) { - crtc = &dev->resources->crtcs[i]; - break; - } - } - + crtc = get_crtc_by_id(dev, p->crtc_id); if (!crtc) { fprintf(stderr, "CRTC %u not found\n", p->crtc_id); return -1; @@ -1161,17 +1220,9 @@ static int atomic_set_plane(struct devic p->old_bo = p->bo; if (!plane_bo) { - plane_bo = bo_create(dev->fd, p->fourcc, p->w, p->h, - handles, pitches, offsets, pattern); - - if (plane_bo == NULL) + if (bo_fb_create(dev->fd, p->fourcc, p->w, p->h, + pattern, &plane_bo, &p->fb_id)) return -1; - - if (drmModeAddFB2(dev->fd, p->w, p->h, p->fourcc, - handles, pitches, offsets, &p->fb_id, 0)) { - fprintf(stderr, "failed to add fb: %s\n", strerror(errno)); - return -1; - } } p->bo = plane_bo; @@ -1207,34 +1258,23 @@ static int atomic_set_plane(struct devic static int set_plane(struct device *dev, struct plane_arg *p) { drmModePlane *ovr; - uint32_t handles[4] = {0}, pitches[4] = {0}, offsets[4] = {0}; uint32_t plane_id; - struct bo *plane_bo; - uint32_t plane_flags = 0; int crtc_x, crtc_y, crtc_w, crtc_h; struct crtc *crtc = NULL; - unsigned int pipe; - unsigned int i; + unsigned int i, crtc_mask; /* Find an unused plane which can be connected to our CRTC. Find the * CRTC index first, then iterate over available planes. */ - for (i = 0; i < (unsigned int)dev->resources->res->count_crtcs; i++) { - if (p->crtc_id == dev->resources->res->crtcs[i]) { - crtc = &dev->resources->crtcs[i]; - pipe = i; - break; - } - } - + crtc = get_crtc_by_id(dev, p->crtc_id); if (!crtc) { fprintf(stderr, "CRTC %u not found\n", p->crtc_id); return -1; } - + crtc_mask = get_crtc_mask(dev, crtc); plane_id = p->plane_id; - for (i = 0; i < dev->resources->plane_res->count_planes; i++) { + for (i = 0; i < dev->resources->count_planes; i++) { ovr = dev->resources->planes[i].plane; if (!ovr) continue; @@ -1245,35 +1285,26 @@ static int set_plane(struct device *dev, if (!format_support(ovr, p->fourcc)) continue; - if ((ovr->possible_crtcs & (1 << pipe)) && + if ((ovr->possible_crtcs & crtc_mask) && (ovr->crtc_id == 0 || ovr->crtc_id == p->crtc_id)) { plane_id = ovr->plane_id; break; } } - if (i == dev->resources->plane_res->count_planes) { + if (i == dev->resources->count_planes) { fprintf(stderr, "no unused plane available for CRTC %u\n", - crtc->crtc->crtc_id); + p->crtc_id); return -1; } fprintf(stderr, "testing %dx%d@%s overlay plane %u\n", p->w, p->h, p->format_str, plane_id); - plane_bo = bo_create(dev->fd, p->fourcc, p->w, p->h, handles, - pitches, offsets, secondary_fill); - if (plane_bo == NULL) - return -1; - - p->bo = plane_bo; - /* just use single plane format for now.. */ - if (drmModeAddFB2(dev->fd, p->w, p->h, p->fourcc, - handles, pitches, offsets, &p->fb_id, plane_flags)) { - fprintf(stderr, "failed to add fb: %s\n", strerror(errno)); + if (bo_fb_create(dev->fd, p->fourcc, p->w, p->h, + secondary_fill, &p->bo, &p->fb_id)) return -1; - } crtc_w = p->w * p->scale; crtc_h = p->h * p->scale; @@ -1287,15 +1318,15 @@ static int set_plane(struct device *dev, } /* note src coords (last 4 args) are in Q16 format */ - if (drmModeSetPlane(dev->fd, plane_id, crtc->crtc->crtc_id, p->fb_id, - plane_flags, crtc_x, crtc_y, crtc_w, crtc_h, + if (drmModeSetPlane(dev->fd, plane_id, p->crtc_id, p->fb_id, + 0, crtc_x, crtc_y, crtc_w, crtc_h, 0, 0, p->w << 16, p->h << 16)) { fprintf(stderr, "failed to enable plane: %s\n", strerror(errno)); return -1; } - ovr->crtc_id = crtc->crtc->crtc_id; + ovr->crtc_id = p->crtc_id; return 0; } @@ -1317,6 +1348,41 @@ static void atomic_set_planes(struct dev } } +static void +atomic_test_page_flip(struct device *dev, struct pipe_arg *pipe_args, + struct plane_arg *plane_args, unsigned int plane_count) +{ + int ret; + + gettimeofday(&pipe_args->start, NULL); + pipe_args->swap_count = 0; + + while (true) { + drmModeAtomicFree(dev->req); + dev->req = drmModeAtomicAlloc(); + atomic_set_planes(dev, plane_args, plane_count, true); + + ret = drmModeAtomicCommit(dev->fd, dev->req, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL); + if (ret) { + fprintf(stderr, "Atomic Commit failed [2]\n"); + return; + } + + pipe_args->swap_count++; + if (pipe_args->swap_count == 60) { + struct timeval end; + double t; + + gettimeofday(&end, NULL); + t = end.tv_sec + end.tv_usec * 1e-6 - + (pipe_args->start.tv_sec + pipe_args->start.tv_usec * 1e-6); + fprintf(stderr, "freq: %.02fHz\n", pipe_args->swap_count / t); + pipe_args->swap_count = 0; + pipe_args->start = end; + } + } +} + static void atomic_clear_planes(struct device *dev, struct plane_arg *p, unsigned int count) { unsigned int i; @@ -1372,131 +1438,269 @@ static void clear_planes(struct device * } } -static void atomic_set_mode(struct device *dev, struct pipe_arg *pipes, unsigned int count) +static int pipe_resolve_connectors(struct device *dev, struct pipe_arg *pipe) { + drmModeConnector *connector; unsigned int i; - unsigned int j; - int ret; + uint32_t id; + char *endp; - for (i = 0; i < count; i++) { - struct pipe_arg *pipe = &pipes[i]; + for (i = 0; i < pipe->num_cons; i++) { + id = strtoul(pipe->cons[i], &endp, 10); + if (endp == pipe->cons[i]) { + connector = get_connector_by_name(dev, pipe->cons[i]); + if (!connector) { + fprintf(stderr, "no connector named '%s'\n", + pipe->cons[i]); + return -ENODEV; + } - ret = pipe_find_crtc_and_mode(dev, pipe); - if (ret < 0) + id = connector->connector_id; + } + + pipe->con_ids[i] = id; + } + + return 0; +} + +static int pipe_attempt_connector(struct device *dev, drmModeConnector *con, + struct pipe_arg *pipe) +{ + char *con_str; + int i; + + con_str = calloc(8, sizeof(char)); + if (!con_str) + return -1; + + sprintf(con_str, "%d", con->connector_id); + strcpy(pipe->format_str, "XR24"); + pipe->fourcc = util_format_fourcc(pipe->format_str); + pipe->num_cons = 1; + pipe->con_ids = calloc(1, sizeof(*pipe->con_ids)); + pipe->cons = calloc(1, sizeof(*pipe->cons)); + + if (!pipe->con_ids || !pipe->cons) + goto free_con_str; + + pipe->con_ids[0] = con->connector_id; + pipe->cons[0] = (const char*)con_str; + + pipe->crtc = pipe_find_crtc(dev, pipe); + if (!pipe->crtc) + goto free_all; + + pipe->crtc_id = pipe->crtc->crtc->crtc_id; + + /* Return the first mode if no preferred. */ + pipe->mode = &con->modes[0]; + + for (i = 0; i < con->count_modes; i++) { + drmModeModeInfo *current_mode = &con->modes[i]; + + if (current_mode->type & DRM_MODE_TYPE_PREFERRED) { + pipe->mode = current_mode; + break; + } + } + + sprintf(pipe->mode_str, "%dx%d", pipe->mode->hdisplay, pipe->mode->vdisplay); + + return 0; + +free_all: + free(pipe->cons); + free(pipe->con_ids); +free_con_str: + free(con_str); + return -1; +} + +static int pipe_find_preferred(struct device *dev, struct pipe_arg **out_pipes) +{ + struct pipe_arg *pipes; + struct resources *res = dev->resources; + drmModeConnector *con = NULL; + int i, connected = 0, attempted = 0; + + for (i = 0; i < res->count_connectors; i++) { + con = res->connectors[i].connector; + if (!con || con->connection != DRM_MODE_CONNECTED) continue; + connected++; + } + if (!connected) { + printf("no connected connector!\n"); + return 0; } - for (i = 0; i < count; i++) { - struct pipe_arg *pipe = &pipes[i]; - uint32_t blob_id; + pipes = calloc(connected, sizeof(struct pipe_arg)); + if (!pipes) + return 0; - if (pipe->mode == NULL) + for (i = 0; i < res->count_connectors && attempted < connected; i++) { + con = res->connectors[i].connector; + if (!con || con->connection != DRM_MODE_CONNECTED) continue; - printf("setting mode %s-%dHz on connectors ", - pipe->mode_str, pipe->mode->vrefresh); - for (j = 0; j < pipe->num_cons; ++j) { - printf("%s, ", pipe->cons[j]); - add_property(dev, pipe->con_ids[j], "CRTC_ID", pipe->crtc->crtc->crtc_id); + if (pipe_attempt_connector(dev, con, &pipes[attempted]) < 0) { + printf("failed fetching preferred mode for connector\n"); + continue; } - printf("crtc %d\n", pipe->crtc->crtc->crtc_id); - - drmModeCreatePropertyBlob(dev->fd, pipe->mode, sizeof(*pipe->mode), &blob_id); - add_property(dev, pipe->crtc->crtc->crtc_id, "MODE_ID", blob_id); - add_property(dev, pipe->crtc->crtc->crtc_id, "ACTIVE", 1); + attempted++; } + + *out_pipes = pipes; + return attempted; } -static void atomic_clear_mode(struct device *dev, struct pipe_arg *pipes, unsigned int count) +static struct plane *get_primary_plane_by_crtc(struct device *dev, struct crtc *crtc) { unsigned int i; - unsigned int j; - - for (i = 0; i < count; i++) { - struct pipe_arg *pipe = &pipes[i]; - if (pipe->mode == NULL) + for (i = 0; i < dev->resources->count_planes; i++) { + struct plane *plane = &dev->resources->planes[i]; + drmModePlane *ovr = plane->plane; + if (!ovr) continue; - for (j = 0; j < pipe->num_cons; ++j) - add_property(dev, pipe->con_ids[j], "CRTC_ID",0); + // XXX: add is_primary_plane and (?) format checks - add_property(dev, pipe->crtc->crtc->crtc_id, "MODE_ID", 0); - add_property(dev, pipe->crtc->crtc->crtc_id, "ACTIVE", 0); + if (ovr->possible_crtcs & get_crtc_mask(dev, crtc)) + return plane; } + return NULL; } static void set_mode(struct device *dev, struct pipe_arg *pipes, unsigned int count) { - uint32_t handles[4] = {0}, pitches[4] = {0}, offsets[4] = {0}; - unsigned int fb_id; - struct bo *bo; - unsigned int i; - unsigned int j; - int ret, x; - - dev->mode.width = 0; - dev->mode.height = 0; - dev->mode.fb_id = 0; + unsigned int i, j; + int ret, x = 0; + int preferred = count == 0; for (i = 0; i < count; i++) { struct pipe_arg *pipe = &pipes[i]; + ret = pipe_resolve_connectors(dev, pipe); + if (ret < 0) + return; + ret = pipe_find_crtc_and_mode(dev, pipe); if (ret < 0) continue; + } + if (preferred) { + struct pipe_arg *pipe_args; - dev->mode.width += pipe->mode->hdisplay; - if (dev->mode.height < pipe->mode->vdisplay) - dev->mode.height = pipe->mode->vdisplay; + count = pipe_find_preferred(dev, &pipe_args); + if (!count) { + fprintf(stderr, "can't find any preferred connector/mode.\n"); + return; + } + pipes = pipe_args; } - bo = bo_create(dev->fd, pipes[0].fourcc, dev->mode.width, - dev->mode.height, handles, pitches, offsets, - primary_fill); - if (bo == NULL) - return; + if (!dev->use_atomic) { + for (i = 0; i < count; i++) { + struct pipe_arg *pipe = &pipes[i]; - dev->mode.bo = bo; + if (pipe->mode == NULL) + continue; - ret = drmModeAddFB2(dev->fd, dev->mode.width, dev->mode.height, - pipes[0].fourcc, handles, pitches, offsets, &fb_id, 0); - if (ret) { - fprintf(stderr, "failed to add fb (%ux%u): %s\n", - dev->mode.width, dev->mode.height, strerror(errno)); - return; - } + if (!preferred) { + dev->mode.width += pipe->mode->hdisplay; + if (dev->mode.height < pipe->mode->vdisplay) + dev->mode.height = pipe->mode->vdisplay; + } else { + /* XXX: Use a clone mode, more like atomic. We could do per + * connector bo/fb, so we don't have the stretched image. + */ + if (dev->mode.width < pipe->mode->hdisplay) + dev->mode.width = pipe->mode->hdisplay; + if (dev->mode.height < pipe->mode->vdisplay) + dev->mode.height = pipe->mode->vdisplay; + } + } - dev->mode.fb_id = fb_id; + if (bo_fb_create(dev->fd, pipes[0].fourcc, dev->mode.width, dev->mode.height, + primary_fill, &dev->mode.bo, &dev->mode.fb_id)) + return; + } - x = 0; for (i = 0; i < count; i++) { struct pipe_arg *pipe = &pipes[i]; + uint32_t blob_id; if (pipe->mode == NULL) continue; - printf("setting mode %s-%dHz@%s on connectors ", - pipe->mode_str, pipe->mode->vrefresh, pipe->format_str); - for (j = 0; j < pipe->num_cons; ++j) + printf("setting mode %s-%.2fHz on connectors ", + pipe->mode->name, mode_vrefresh(pipe->mode)); + for (j = 0; j < pipe->num_cons; ++j) { printf("%s, ", pipe->cons[j]); - printf("crtc %d\n", pipe->crtc->crtc->crtc_id); + if (dev->use_atomic) + add_property(dev, pipe->con_ids[j], "CRTC_ID", pipe->crtc_id); + } + printf("crtc %d\n", pipe->crtc_id); - ret = drmModeSetCrtc(dev->fd, pipe->crtc->crtc->crtc_id, fb_id, - x, 0, pipe->con_ids, pipe->num_cons, - pipe->mode); + if (!dev->use_atomic) { + ret = drmModeSetCrtc(dev->fd, pipe->crtc_id, dev->mode.fb_id, + x, 0, pipe->con_ids, pipe->num_cons, + pipe->mode); - /* XXX: Actually check if this is needed */ - drmModeDirtyFB(dev->fd, fb_id, NULL, 0); + /* XXX: Actually check if this is needed */ + drmModeDirtyFB(dev->fd, dev->mode.fb_id, NULL, 0); - x += pipe->mode->hdisplay; + if (!preferred) + x += pipe->mode->hdisplay; - if (ret) { - fprintf(stderr, "failed to set mode: %s\n", strerror(errno)); - return; + if (ret) { + fprintf(stderr, "failed to set mode: %s\n", strerror(errno)); + return; + } + + set_gamma(dev, pipe->crtc_id, pipe->fourcc); + } else { + drmModeCreatePropertyBlob(dev->fd, pipe->mode, sizeof(*pipe->mode), &blob_id); + add_property(dev, pipe->crtc_id, "MODE_ID", blob_id); + add_property(dev, pipe->crtc_id, "ACTIVE", 1); + + /* By default atomic modeset does not set a primary plane, shrug */ + if (preferred) { + struct plane *plane = get_primary_plane_by_crtc(dev, pipe->crtc); + struct plane_arg plane_args = { + .plane_id = plane->plane->plane_id, + .crtc_id = pipe->crtc_id, + .w = pipe->mode->hdisplay, + .h = pipe->mode->vdisplay, + .scale = 1.0, + .format_str = "XR24", + .fourcc = util_format_fourcc(pipe->format_str), + }; + + atomic_set_planes(dev, &plane_args, 1, false); + } } + } +} + +static void atomic_clear_mode(struct device *dev, struct pipe_arg *pipes, unsigned int count) +{ + unsigned int i; + unsigned int j; + + for (i = 0; i < count; i++) { + struct pipe_arg *pipe = &pipes[i]; - set_gamma(dev, pipe->crtc->crtc->crtc_id, pipe->fourcc); + if (pipe->mode == NULL) + continue; + + for (j = 0; j < pipe->num_cons; ++j) + add_property(dev, pipe->con_ids[j], "CRTC_ID",0); + + add_property(dev, pipe->crtc_id, "MODE_ID", 0); + add_property(dev, pipe->crtc_id, "ACTIVE", 0); } } @@ -1542,7 +1746,7 @@ static void set_cursors(struct device *d for (i = 0; i < count; i++) { struct pipe_arg *pipe = &pipes[i]; ret = cursor_init(dev->fd, handles[0], - pipe->crtc->crtc->crtc_id, + pipe->crtc_id, pipe->mode->hdisplay, pipe->mode->vdisplay, cw, ch); if (ret) { @@ -1565,34 +1769,23 @@ static void clear_cursors(struct device static void test_page_flip(struct device *dev, struct pipe_arg *pipes, unsigned int count) { - uint32_t handles[4] = {0}, pitches[4] = {0}, offsets[4] = {0}; unsigned int other_fb_id; struct bo *other_bo; drmEventContext evctx; unsigned int i; int ret; - other_bo = bo_create(dev->fd, pipes[0].fourcc, dev->mode.width, - dev->mode.height, handles, pitches, offsets, - UTIL_PATTERN_PLAIN); - if (other_bo == NULL) + if (bo_fb_create(dev->fd, pipes[0].fourcc, dev->mode.width, dev->mode.height, + UTIL_PATTERN_PLAIN, &other_bo, &other_fb_id)) return; - ret = drmModeAddFB2(dev->fd, dev->mode.width, dev->mode.height, - pipes[0].fourcc, handles, pitches, offsets, - &other_fb_id, 0); - if (ret) { - fprintf(stderr, "failed to add fb: %s\n", strerror(errno)); - goto err; - } - for (i = 0; i < count; i++) { struct pipe_arg *pipe = &pipes[i]; if (pipe->mode == NULL) continue; - ret = drmModePageFlip(dev->fd, pipe->crtc->crtc->crtc_id, + ret = drmModePageFlip(dev->fd, pipe->crtc_id, other_fb_id, DRM_MODE_PAGE_FLIP_EVENT, pipe); if (ret) { @@ -1650,7 +1843,6 @@ static void test_page_flip(struct device err_rmfb: drmModeRmFB(dev->fd, other_fb_id); -err: bo_destroy(other_bo); } @@ -1695,6 +1887,8 @@ static int parse_connector(struct pipe_a return -1; /* Parse the remaining parameters. */ + if (!endp) + return -1; if (*endp == '@') { arg = endp + 1; pipe->crtc_id = strtoul(arg, &endp, 10); @@ -1713,7 +1907,7 @@ static int parse_connector(struct pipe_a pipe->mode_str[len] = '\0'; if (*p == '-') { - pipe->vrefresh = strtoul(p + 1, &endp, 10); + pipe->vrefresh = strtof(p + 1, &endp); p = endp; } @@ -1811,7 +2005,7 @@ static void parse_fill_patterns(char *ar static void usage(char *name) { - fprintf(stderr, "usage: %s [-acDdefMPpsCvw]\n", name); + fprintf(stderr, "usage: %s [-acDdefMPpsCvrw]\n", name); fprintf(stderr, "\n Query options:\n\n"); fprintf(stderr, "\t-c\tlist connectors\n"); @@ -1821,9 +2015,10 @@ static void usage(char *name) fprintf(stderr, "\n Test options:\n\n"); fprintf(stderr, "\t-P <plane_id>@<crtc_id>:<w>x<h>[+<x>+<y>][*<scale>][@<format>]\tset a plane\n"); - fprintf(stderr, "\t-s <connector_id>[,<connector_id>][@<crtc_id>]:<mode>[-<vrefresh>][@<format>]\tset a mode\n"); + fprintf(stderr, "\t-s <connector_id>[,<connector_id>][@<crtc_id>]:[#<mode index>]<mode>[-<vrefresh>][@<format>]\tset a mode\n"); fprintf(stderr, "\t-C\ttest hw cursor\n"); fprintf(stderr, "\t-v\ttest vsynced page flipping\n"); + fprintf(stderr, "\t-r\tset the preferred mode for all connectors\n"); fprintf(stderr, "\t-w <obj_id>:<prop_name>:<value>\tset property\n"); fprintf(stderr, "\t-a \tuse atomic API\n"); fprintf(stderr, "\t-F pattern1,pattern2\tspecify fill patterns\n"); @@ -1837,60 +2032,7 @@ static void usage(char *name) exit(0); } -static int page_flipping_supported(void) -{ - /*FIXME: generic ioctl needed? */ - return 1; -#if 0 - int ret, value; - struct drm_i915_getparam gp; - - gp.param = I915_PARAM_HAS_PAGEFLIPPING; - gp.value = &value; - - ret = drmCommandWriteRead(fd, DRM_I915_GETPARAM, &gp, sizeof(gp)); - if (ret) { - fprintf(stderr, "drm_i915_getparam: %m\n"); - return 0; - } - - return *gp.value; -#endif -} - -static int cursor_supported(void) -{ - /*FIXME: generic ioctl needed? */ - return 1; -} - -static int pipe_resolve_connectors(struct device *dev, struct pipe_arg *pipe) -{ - drmModeConnector *connector; - unsigned int i; - uint32_t id; - char *endp; - - for (i = 0; i < pipe->num_cons; i++) { - id = strtoul(pipe->cons[i], &endp, 10); - if (endp == pipe->cons[i]) { - connector = get_connector_by_name(dev, pipe->cons[i]); - if (!connector) { - fprintf(stderr, "no connector named '%s'\n", - pipe->cons[i]); - return -ENODEV; - } - - id = connector->connector_id; - } - - pipe->con_ids[i] = id; - } - - return 0; -} - -static char optstr[] = "acdD:efF:M:P:ps:Cvw:"; +static char optstr[] = "acdD:efF:M:P:ps:Cvrw:"; int main(int argc, char **argv) { @@ -1901,6 +2043,7 @@ int main(int argc, char **argv) int drop_master = 0; int test_vsync = 0; int test_cursor = 0; + int set_preferred = 0; int use_atomic = 0; char *device = NULL; char *module = NULL; @@ -1922,12 +2065,15 @@ int main(int argc, char **argv) switch (c) { case 'a': use_atomic = 1; + /* Preserve the default behaviour of dumping all information. */ + args--; break; case 'c': connectors = 1; break; case 'D': device = optarg; + /* Preserve the default behaviour of dumping all information. */ args--; break; case 'd': @@ -1985,6 +2131,9 @@ int main(int argc, char **argv) case 'v': test_vsync = 1; break; + case 'r': + set_preferred = 1; + break; case 'w': prop_args = realloc(prop_args, (prop_count + 1) * sizeof *prop_args); @@ -2005,51 +2154,45 @@ int main(int argc, char **argv) } } - if (!args || (args == 1 && use_atomic)) + /* Dump all the details when no* arguments are provided. */ + if (!args) encoders = connectors = crtcs = planes = framebuffers = 1; - dev.fd = util_open(device, module); - if (dev.fd < 0) - return -1; - - ret = drmSetClientCap(dev.fd, DRM_CLIENT_CAP_ATOMIC, 1); - if (ret && use_atomic) { - fprintf(stderr, "no atomic modesetting support: %s\n", strerror(errno)); - drmClose(dev.fd); + if (test_vsync && !count) { + fprintf(stderr, "page flipping requires at least one -s option.\n"); return -1; } - - dev.use_atomic = use_atomic; - - if (test_vsync && !page_flipping_supported()) { - fprintf(stderr, "page flipping not supported by drm.\n"); + if (set_preferred && count) { + fprintf(stderr, "cannot use -r (preferred) when -s (mode) is set\n"); return -1; } - if (test_vsync && !count) { - fprintf(stderr, "page flipping requires at least one -s option.\n"); + if (set_preferred && plane_count) { + fprintf(stderr, "cannot use -r (preferred) when -P (plane) is set\n"); return -1; } - if (test_cursor && !cursor_supported()) { - fprintf(stderr, "hw cursor not supported by drm.\n"); + dev.fd = util_open(device, module); + if (dev.fd < 0) return -1; + + if (use_atomic) { + ret = drmSetClientCap(dev.fd, DRM_CLIENT_CAP_ATOMIC, 1); + if (ret) { + fprintf(stderr, "no atomic modesetting support: %s\n", strerror(errno)); + drmClose(dev.fd); + return -1; + } } + dev.use_atomic = use_atomic; + dev.resources = get_resources(&dev); if (!dev.resources) { drmClose(dev.fd); return 1; } - for (i = 0; i < count; i++) { - if (pipe_resolve_connectors(&dev, &pipe_args[i]) < 0) { - free_resources(dev.resources); - drmClose(dev.fd); - return 1; - } - } - #define dump_resource(dev, res) if (res) dump_##res(dev) dump_resource(&dev, encoders); @@ -2064,7 +2207,7 @@ int main(int argc, char **argv) if (dev.use_atomic) { dev.req = drmModeAtomicAlloc(); - if (count && plane_count) { + if (set_preferred || (count && plane_count)) { uint64_t cap = 0; ret = drmGetCap(dev.fd, DRM_CAP_DUMB_BUFFER, &cap); @@ -2073,8 +2216,11 @@ int main(int argc, char **argv) return 1; } - atomic_set_mode(&dev, pipe_args, count); - atomic_set_planes(&dev, plane_args, plane_count, false); + if (set_preferred || count) + set_mode(&dev, pipe_args, count); + + if (plane_count) + atomic_set_planes(&dev, plane_args, plane_count, false); ret = drmModeAtomicCommit(dev.fd, dev.req, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL); if (ret) { @@ -2082,33 +2228,8 @@ int main(int argc, char **argv) return 1; } - gettimeofday(&pipe_args->start, NULL); - pipe_args->swap_count = 0; - - while (test_vsync) { - drmModeAtomicFree(dev.req); - dev.req = drmModeAtomicAlloc(); - atomic_set_planes(&dev, plane_args, plane_count, true); - - ret = drmModeAtomicCommit(dev.fd, dev.req, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL); - if (ret) { - fprintf(stderr, "Atomic Commit failed [2]\n"); - return 1; - } - - pipe_args->swap_count++; - if (pipe_args->swap_count == 60) { - struct timeval end; - double t; - - gettimeofday(&end, NULL); - t = end.tv_sec + end.tv_usec * 1e-6 - - (pipe_args->start.tv_sec + pipe_args->start.tv_usec * 1e-6); - fprintf(stderr, "freq: %.02fHz\n", pipe_args->swap_count / t); - pipe_args->swap_count = 0; - pipe_args->start = end; - } - } + if (test_vsync) + atomic_test_page_flip(&dev, pipe_args, plane_args, plane_count); if (drop_master) drmDropMaster(dev.fd); @@ -2118,20 +2239,24 @@ int main(int argc, char **argv) drmModeAtomicFree(dev.req); dev.req = drmModeAtomicAlloc(); - atomic_clear_mode(&dev, pipe_args, count); - atomic_clear_planes(&dev, plane_args, plane_count); + /* XXX: properly teardown the preferred mode/plane state */ + if (plane_count) + atomic_clear_planes(&dev, plane_args, plane_count); + + if (count) + atomic_clear_mode(&dev, pipe_args, count); + ret = drmModeAtomicCommit(dev.fd, dev.req, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL); - if (ret) { + if (ret) fprintf(stderr, "Atomic Commit failed\n"); - return 1; - } - atomic_clear_FB(&dev, plane_args, plane_count); + if (plane_count) + atomic_clear_FB(&dev, plane_args, plane_count); } drmModeAtomicFree(dev.req); } else { - if (count || plane_count) { + if (set_preferred || count || plane_count) { uint64_t cap = 0; ret = drmGetCap(dev.fd, DRM_CAP_DUMB_BUFFER, &cap); @@ -2140,7 +2265,7 @@ int main(int argc, char **argv) return 1; } - if (count) + if (set_preferred || count) set_mode(&dev, pipe_args, count); if (plane_count) @@ -2163,12 +2288,13 @@ int main(int argc, char **argv) if (plane_count) clear_planes(&dev, plane_args, plane_count); - if (count) + if (set_preferred || count) clear_mode(&dev); } } free_resources(dev.resources); + drmClose(dev.fd); return 0; } Added files: Index: xsrc/external/mit/libdrm/dist/Android.mk diff -u /dev/null xsrc/external/mit/libdrm/dist/Android.mk:1.3 --- /dev/null Sun Nov 1 09:57:41 2020 +++ xsrc/external/mit/libdrm/dist/Android.mk Sun Nov 1 09:57:37 2020 @@ -0,0 +1,74 @@ +# +# Copyright © 2011-2012 Intel Corporation +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice (including the next +# paragraph) shall be included in all copies or substantial portions of the +# Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. +# + +LIBDRM_ANDROID_MAJOR_VERSION := $(word 1, $(subst ., , $(PLATFORM_VERSION))) +ifneq ($(filter 2 4, $(LIBDRM_ANDROID_MAJOR_VERSION)),) +$(error "Android 4.4 and earlier not supported") +endif + +LIBDRM_COMMON_MK := $(call my-dir)/Android.common.mk + +LOCAL_PATH := $(call my-dir) +LIBDRM_TOP := $(LOCAL_PATH) + +include $(CLEAR_VARS) + +# Import variables LIBDRM_{,H,INCLUDE_H,INCLUDE_ANDROID_H,INCLUDE_VMWGFX_H}_FILES +include $(LOCAL_PATH)/Makefile.sources + +#static library for the device (recovery) +include $(CLEAR_VARS) +LOCAL_MODULE := libdrm + +LOCAL_SRC_FILES := $(LIBDRM_FILES) +LOCAL_EXPORT_C_INCLUDE_DIRS := \ + $(LOCAL_PATH) \ + $(LOCAL_PATH)/include/drm \ + $(LOCAL_PATH)/android + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/include/drm + +include $(LIBDRM_COMMON_MK) +include $(BUILD_STATIC_LIBRARY) + +# Shared library for the device +include $(CLEAR_VARS) +LOCAL_MODULE := libdrm + +LOCAL_SRC_FILES := $(LIBDRM_FILES) +LOCAL_EXPORT_C_INCLUDE_DIRS := \ + $(LOCAL_PATH) \ + $(LOCAL_PATH)/include/drm \ + $(LOCAL_PATH)/android + +LOCAL_SHARED_LIBRARIES := \ + libcutils + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/include/drm + +include $(LIBDRM_COMMON_MK) +include $(BUILD_SHARED_LIBRARY) + +include $(call all-makefiles-under,$(LOCAL_PATH)) Index: xsrc/external/mit/libdrm/dist/freedreno/Android.mk diff -u /dev/null xsrc/external/mit/libdrm/dist/freedreno/Android.mk:1.3 --- /dev/null Sun Nov 1 09:57:41 2020 +++ xsrc/external/mit/libdrm/dist/freedreno/Android.mk Sun Nov 1 09:57:38 2020 @@ -0,0 +1,14 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +# Import variables LIBDRM_FREEDRENO_FILES, LIBDRM_FREEDRENO_H_FILES +include $(LOCAL_PATH)/Makefile.sources + +LOCAL_MODULE := libdrm_freedreno + +LOCAL_SHARED_LIBRARIES := libdrm + +LOCAL_SRC_FILES := $(LIBDRM_FREEDRENO_FILES) + +include $(LIBDRM_COMMON_MK) +include $(BUILD_SHARED_LIBRARY) Index: xsrc/external/mit/libdrm/dist/intel/Android.mk diff -u /dev/null xsrc/external/mit/libdrm/dist/intel/Android.mk:1.3 --- /dev/null Sun Nov 1 09:57:41 2020 +++ xsrc/external/mit/libdrm/dist/intel/Android.mk Sun Nov 1 09:57:38 2020 @@ -0,0 +1,38 @@ +# +# Copyright © 2011 Intel Corporation +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice (including the next +# paragraph) shall be included in all copies or substantial portions of the +# Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. +# + +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +# Import variables LIBDRM_INTEL_FILES, LIBDRM_INTEL_H_FILES +include $(LOCAL_PATH)/Makefile.sources + +LOCAL_MODULE := libdrm_intel + +LOCAL_SRC_FILES := $(LIBDRM_INTEL_FILES) + +LOCAL_SHARED_LIBRARIES := \ + libdrm + +include $(LIBDRM_COMMON_MK) +include $(BUILD_SHARED_LIBRARY) Index: xsrc/external/mit/libdrm/dist/libkms/Android.mk diff -u /dev/null xsrc/external/mit/libdrm/dist/libkms/Android.mk:1.3 --- /dev/null Sun Nov 1 09:57:41 2020 +++ xsrc/external/mit/libdrm/dist/libkms/Android.mk Sun Nov 1 09:57:38 2020 @@ -0,0 +1,51 @@ +DRM_GPU_DRIVERS := $(strip $(filter-out swrast, $(BOARD_GPU_DRIVERS))) + +intel_drivers := i915 i965 i915g iris +radeon_drivers := r300g r600g radeonsi +nouveau_drivers := nouveau +virgl_drivers := virgl +vmwgfx_drivers := vmwgfx + +valid_drivers := \ + $(intel_drivers) \ + $(radeon_drivers) \ + $(nouveau_drivers) \ + $(virgl_drivers) \ + $(vmwgfx_drivers) + +# warn about invalid drivers +invalid_drivers := $(filter-out $(valid_drivers), $(DRM_GPU_DRIVERS)) +ifneq ($(invalid_drivers),) +$(warning invalid GPU drivers: $(invalid_drivers)) +# tidy up +DRM_GPU_DRIVERS := $(filter-out $(invalid_drivers), $(DRM_GPU_DRIVERS)) +endif + +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) +include $(LOCAL_PATH)/Makefile.sources + +LOCAL_SRC_FILES := $(LIBKMS_FILES) + +ifneq ($(filter $(vmwgfx_drivers), $(DRM_GPU_DRIVERS)),) +LOCAL_SRC_FILES += $(LIBKMS_VMWGFX_FILES) +endif + +ifneq ($(filter $(intel_drivers), $(DRM_GPU_DRIVERS)),) +LOCAL_SRC_FILES += $(LIBKMS_INTEL_FILES) +endif + +ifneq ($(filter $(nouveau_drivers), $(DRM_GPU_DRIVERS)),) +LOCAL_SRC_FILES += $(LIBKMS_NOUVEAU_FILES) +endif + +ifneq ($(filter $(radeon_drivers), $(DRM_GPU_DRIVERS)),) +LOCAL_SRC_FILES += $(LIBKMS_RADEON_FILES) +endif + +LOCAL_MODULE := libkms +LOCAL_SHARED_LIBRARIES := libdrm + +include $(LIBDRM_COMMON_MK) +include $(BUILD_SHARED_LIBRARY) Index: xsrc/external/mit/libdrm/dist/nouveau/Android.mk diff -u /dev/null xsrc/external/mit/libdrm/dist/nouveau/Android.mk:1.3 --- /dev/null Sun Nov 1 09:57:41 2020 +++ xsrc/external/mit/libdrm/dist/nouveau/Android.mk Sun Nov 1 09:57:39 2020 @@ -0,0 +1,14 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +# Import variables LIBDRM_NOUVEAU_FILES, LIBDRM_NOUVEAU_H_FILES +include $(LOCAL_PATH)/Makefile.sources + +LOCAL_MODULE := libdrm_nouveau + +LOCAL_SHARED_LIBRARIES := libdrm + +LOCAL_SRC_FILES := $(LIBDRM_NOUVEAU_FILES) + +include $(LIBDRM_COMMON_MK) +include $(BUILD_SHARED_LIBRARY) Index: xsrc/external/mit/libdrm/dist/radeon/Android.mk diff -u /dev/null xsrc/external/mit/libdrm/dist/radeon/Android.mk:1.3 --- /dev/null Sun Nov 1 09:57:41 2020 +++ xsrc/external/mit/libdrm/dist/radeon/Android.mk Sun Nov 1 09:57:39 2020 @@ -0,0 +1,14 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +# Import variables LIBDRM_RADEON_FILES, LIBDRM_RADEON_H_FILES +include $(LOCAL_PATH)/Makefile.sources + +LOCAL_MODULE := libdrm_radeon + +LOCAL_SHARED_LIBRARIES := libdrm + +LOCAL_SRC_FILES := $(LIBDRM_RADEON_FILES) + +include $(LIBDRM_COMMON_MK) +include $(BUILD_SHARED_LIBRARY) Index: xsrc/external/mit/libdrm/dist/tests/modetest/Android.mk diff -u /dev/null xsrc/external/mit/libdrm/dist/tests/modetest/Android.mk:1.3 --- /dev/null Sun Nov 1 09:57:41 2020 +++ xsrc/external/mit/libdrm/dist/tests/modetest/Android.mk Sun Nov 1 09:57:40 2020 @@ -0,0 +1,14 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) +include $(LOCAL_PATH)/Makefile.sources + +LOCAL_SRC_FILES := $(MODETEST_FILES) + +LOCAL_MODULE := modetest + +LOCAL_SHARED_LIBRARIES := libdrm +LOCAL_STATIC_LIBRARIES := libdrm_util + +include $(LIBDRM_COMMON_MK) +include $(BUILD_EXECUTABLE)