summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2021-02-11 10:34:52 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2021-02-11 10:34:52 +0000
commitbe78449b8f432727284419721a0ab771c692d829 (patch)
treeff8416d35b0f758e18a88d5d0595d4ea565384f9
parentffee5617b8194d3eb43883b13f044d9e7632d928 (diff)
add Makefiles to replace upstream use of meson
-rw-r--r--lib/libdrm/Makefile6
-rw-r--r--lib/libdrm/mk/Makefile12
-rw-r--r--lib/libdrm/mk/Makefile.inc14
-rw-r--r--lib/libdrm/mk/config.mk57
-rw-r--r--lib/libdrm/mk/include/Makefile70
-rw-r--r--lib/libdrm/mk/libdrm/Makefile19
-rw-r--r--lib/libdrm/mk/libdrm/shlib_version2
-rw-r--r--lib/libdrm/mk/libdrm_amdgpu/Makefile32
-rw-r--r--lib/libdrm/mk/libdrm_amdgpu/shlib_version2
-rw-r--r--lib/libdrm/mk/libdrm_intel/Makefile28
-rw-r--r--lib/libdrm/mk/libdrm_intel/shlib_version2
-rw-r--r--lib/libdrm/mk/libdrm_radeon/Makefile26
-rw-r--r--lib/libdrm/mk/libdrm_radeon/shlib_version2
-rw-r--r--lib/libdrm/mk/man/Makefile21
-rw-r--r--lib/libdrm/mk/man/drm-kms.7240
-rw-r--r--lib/libdrm/mk/man/drm-memory.7369
-rw-r--r--lib/libdrm/mk/man/drm.7100
-rw-r--r--lib/libdrm/mk/man/drmAvailable.354
-rw-r--r--lib/libdrm/mk/man/drmHandleEvent.381
-rw-r--r--lib/libdrm/mk/man/drmModeGetResources.3111
-rw-r--r--lib/libdrm/mk/pkgconfig/Makefile31
-rw-r--r--lib/libdrm/mk/pkgconfig/gen_libdrm.sh66
-rw-r--r--lib/libdrm/mk/pkgconfig/gen_libdrm_amdgpu.sh67
-rw-r--r--lib/libdrm/mk/pkgconfig/gen_libdrm_intel.sh67
-rw-r--r--lib/libdrm/mk/pkgconfig/gen_libdrm_radeon.sh67
25 files changed, 1546 insertions, 0 deletions
diff --git a/lib/libdrm/Makefile b/lib/libdrm/Makefile
new file mode 100644
index 000000000..d87d556b1
--- /dev/null
+++ b/lib/libdrm/Makefile
@@ -0,0 +1,6 @@
+# $OpenBSD: Makefile,v 1.13 2021/02/11 10:34:51 jsg Exp $
+
+SUBDIR= mk
+
+.include <bsd.subdir.mk>
+.include <bsd.xorg.mk>
diff --git a/lib/libdrm/mk/Makefile b/lib/libdrm/mk/Makefile
new file mode 100644
index 000000000..680f1e9c7
--- /dev/null
+++ b/lib/libdrm/mk/Makefile
@@ -0,0 +1,12 @@
+# $OpenBSD: Makefile,v 1.1 2021/02/11 10:34:51 jsg Exp $
+
+.include "config.mk"
+
+SUBDIR= include man pkgconfig \
+ libdrm libdrm_amdgpu libdrm_radeon
+
+.if ${WITH_INTEL} == "yes" || make(obj)
+SUBDIR+= libdrm_intel
+.endif
+
+.include <bsd.subdir.mk>
diff --git a/lib/libdrm/mk/Makefile.inc b/lib/libdrm/mk/Makefile.inc
new file mode 100644
index 000000000..2c5b1d45e
--- /dev/null
+++ b/lib/libdrm/mk/Makefile.inc
@@ -0,0 +1,14 @@
+# $OpenBSD: Makefile.inc,v 1.1 2021/02/11 10:34:51 jsg Exp $
+
+# bsd.lib.mk and bsd.xorg.mk both include Makefile.inc
+.if !defined(DRM_MK_INC)
+
+DRM_SRC?= ${.CURDIR}/../..
+
+CPPFLAGS+= -I${DRM_SRC} \
+ -I${DRM_SRC}/include/drm
+
+.include "config.mk"
+
+.endif
+DRM_MK_INC=Done
diff --git a/lib/libdrm/mk/config.mk b/lib/libdrm/mk/config.mk
new file mode 100644
index 000000000..62af7c642
--- /dev/null
+++ b/lib/libdrm/mk/config.mk
@@ -0,0 +1,57 @@
+.include <bsd.xconf.mk>
+.include <bsd.own.mk>
+
+CFLAGS+= \
+ -std=gnu99 \
+ -fvisibility=hidden \
+ -Wall \
+ -Wdeclaration-after-statement \
+ -Werror=implicit-function-declaration \
+ -Werror=undef \
+ -Wextra \
+ -Winit-self \
+ -Winline \
+ -Winvalid-pch \
+ -Wmissing-declarations \
+ -Wmissing-format-attribute \
+ -Wmissing-prototypes \
+ -Wnested-externs \
+ -Wno-attributes \
+ -Wno-long-long \
+ -Wno-missing-field-initializers \
+ -Wno-unused-parameter \
+ -Wold-style-definition \
+ -Wpacked \
+ -Wpointer-arith \
+ -Wshadow \
+ -Wsign-compare \
+ -Wstrict-aliasing=2 \
+ -Wstrict-prototypes \
+ -Wswitch-enum \
+ -Wwrite-strings
+
+CPPFLAGS+= \
+ -DHAVE_ALLOCA_H=0 \
+ -DHAVE_CAIRO=0 \
+ -DHAVE_EXYNOS=0 \
+ -DHAVE_FREEDRENO_KGSL=0 \
+ -DHAVE_LIBDRM_ATOMIC_PRIMITIVES=1 \
+ -DHAVE_LIB_ATOMIC_OPS=0 \
+ -DHAVE_NOUVEAU=0 \
+ -DHAVE_OPEN_MEMSTREAM=1 \
+ -DHAVE_RADEON=1 \
+ -DHAVE_SYS_SELECT_H=1 \
+ -DHAVE_SYS_SYSCTL_H=1 \
+ -DHAVE_VALGRIND=0 \
+ -DHAVE_VC4=0 \
+ -DHAVE_VISIBILITY=1 \
+ -DHAVE_VMWGFX=0 \
+ -DUDEV=0
+
+.if ${MACHINE} == "amd64" || ${MACHINE} == "i386"
+WITH_INTEL=yes
+CPPFLAGS+= -DHAVE_INTEL=1
+.else
+WITH_INTEL=no
+CPPFLAGS+= -DHAVE_INTEL=0
+.endif
diff --git a/lib/libdrm/mk/include/Makefile b/lib/libdrm/mk/include/Makefile
new file mode 100644
index 000000000..c1dd8ca98
--- /dev/null
+++ b/lib/libdrm/mk/include/Makefile
@@ -0,0 +1,70 @@
+# $OpenBSD: Makefile,v 1.1 2021/02/11 10:34:51 jsg Exp $
+
+.include "../Makefile.inc"
+
+BASE_FILES= libsync.h \
+ xf86drm.h \
+ xf86drmMode.h
+DRM_FILES= amdgpu_drm.h \
+ drm.h \
+ drm_fourcc.h \
+ drm_mode.h \
+ drm_sarea.h \
+ i915_drm.h \
+ mach64_drm.h \
+ mga_drm.h \
+ msm_drm.h \
+ nouveau_drm.h \
+ qxl_drm.h \
+ r128_drm.h \
+ radeon_drm.h \
+ savage_drm.h \
+ sis_drm.h \
+ tegra_drm.h \
+ vc4_drm.h \
+ via_drm.h \
+ virtgpu_drm.h \
+ vmwgfx_drm.h
+RADEON_FILES= r600_pci_ids.h \
+ radeon_bo.h \
+ radeon_bo_gem.h \
+ radeon_bo_int.h \
+ radeon_cs.h \
+ radeon_cs_gem.h \
+ radeon_cs_int.h \
+ radeon_surface.h
+INTEL_FILES= intel_aub.h \
+ intel_bufmgr.h \
+ intel_debug.h
+AMDGPU_FILES= amdgpu.h
+
+includes:
+ cd ${DRM_SRC} && for i in ${BASE_FILES}; do \
+ cmp -s $$i ${DESTDIR}${X11BASE}/include/$$i || \
+ ${INSTALL} ${INSTALL_COPY} -m 444 $$i ${DESTDIR}${X11BASE}/include/$$i; \
+ done
+ cd ${DRM_SRC}/include/drm && for i in ${DRM_FILES}; do \
+ cmp -s $$i ${DESTDIR}${X11BASE}/include/libdrm/$$i || \
+ ${INSTALL} ${INSTALL_COPY} -m 444 $$i ${DESTDIR}${X11BASE}/include/libdrm/$$i; \
+ done
+ cd ${DRM_SRC}/radeon && for i in ${RADEON_FILES}; do \
+ cmp -s $$i ${DESTDIR}${X11BASE}/include/libdrm/$$i || \
+ ${INSTALL} ${INSTALL_COPY} -m 444 $$i ${DESTDIR}${X11BASE}/include/libdrm/$$i; \
+ done
+ cd ${DRM_SRC}/amdgpu && for i in ${AMDGPU_FILES}; do \
+ cmp -s $$i ${DESTDIR}${X11BASE}/include/libdrm/$$i || \
+ ${INSTALL} ${INSTALL_COPY} -m 444 $$i ${DESTDIR}${X11BASE}/include/libdrm/$$i; \
+ done
+.if ${WITH_INTEL} == "yes"
+ cd ${DRM_SRC}/intel && for i in ${INTEL_FILES}; do \
+ cmp -s $$i ${DESTDIR}${X11BASE}/include/libdrm/$$i || \
+ ${INSTALL} ${INSTALL_COPY} -m 444 $$i ${DESTDIR}${X11BASE}/include/libdrm/$$i; \
+ done
+.endif
+
+beforeinstall: includes
+
+obj: _xenocara_obj
+
+.include <bsd.prog.mk>
+.include <bsd.xorg.mk>
diff --git a/lib/libdrm/mk/libdrm/Makefile b/lib/libdrm/mk/libdrm/Makefile
new file mode 100644
index 000000000..95ea49b9b
--- /dev/null
+++ b/lib/libdrm/mk/libdrm/Makefile
@@ -0,0 +1,19 @@
+# $OpenBSD: Makefile,v 1.1 2021/02/11 10:34:51 jsg Exp $
+
+LIB= drm
+
+SRCS= xf86drm.c \
+ xf86drmHash.c \
+ xf86drmMode.c \
+ xf86drmRandom.c \
+ xf86drmSL.c
+
+obj: _xenocara_obj
+
+beforeinstall:
+ rm -f ${DESTDIR}${LIBDIR}/lib${LIB}.la
+
+.include <bsd.lib.mk>
+.include <bsd.xorg.mk>
+
+.PATH: ${DRM_SRC}
diff --git a/lib/libdrm/mk/libdrm/shlib_version b/lib/libdrm/mk/libdrm/shlib_version
new file mode 100644
index 000000000..977728b3c
--- /dev/null
+++ b/lib/libdrm/mk/libdrm/shlib_version
@@ -0,0 +1,2 @@
+major=7
+minor=9
diff --git a/lib/libdrm/mk/libdrm_amdgpu/Makefile b/lib/libdrm/mk/libdrm_amdgpu/Makefile
new file mode 100644
index 000000000..5842a68a6
--- /dev/null
+++ b/lib/libdrm/mk/libdrm_amdgpu/Makefile
@@ -0,0 +1,32 @@
+# $OpenBSD: Makefile,v 1.1 2021/02/11 10:34:51 jsg Exp $
+
+LIB= drm_amdgpu
+
+SRCS= amdgpu_asic_id.c \
+ amdgpu_bo.c \
+ amdgpu_cs.c \
+ amdgpu_device.c \
+ amdgpu_gpu_info.c \
+ amdgpu_vamgr.c \
+ amdgpu_vm.c \
+ handle_table.c
+
+.include "../Makefile.inc"
+
+CPPFLAGS+= -I${DRM_SRC}/amdgpu \
+ -DAMDGPU_ASIC_ID_TABLE=\"${DRM_SRC}/data/amdgpu.ids\"
+
+LDADD+= -L${.CURDIR}/../libdrm/${__objdir} -ldrm
+
+obj: _xenocara_obj
+
+beforeinstall:
+ rm -f ${DESTDIR}${LIBDIR}/lib${LIB}.la
+ ${INSTALL} ${INSTALL_COPY} -o ${SHAREOWN} -g ${SHAREGRP} \
+ -m ${SHAREMODE} ${DRM_SRC}/data/amdgpu.ids \
+ ${DESTDIR}/${X11BASE}/share/libdrm/amdgpu.ids
+
+.include <bsd.lib.mk>
+.include <bsd.xorg.mk>
+
+.PATH: ${DRM_SRC}/amdgpu
diff --git a/lib/libdrm/mk/libdrm_amdgpu/shlib_version b/lib/libdrm/mk/libdrm_amdgpu/shlib_version
new file mode 100644
index 000000000..ba14f87a7
--- /dev/null
+++ b/lib/libdrm/mk/libdrm_amdgpu/shlib_version
@@ -0,0 +1,2 @@
+major=1
+minor=10
diff --git a/lib/libdrm/mk/libdrm_intel/Makefile b/lib/libdrm/mk/libdrm_intel/Makefile
new file mode 100644
index 000000000..84681aa59
--- /dev/null
+++ b/lib/libdrm/mk/libdrm_intel/Makefile
@@ -0,0 +1,28 @@
+# $OpenBSD: Makefile,v 1.1 2021/02/11 10:34:51 jsg Exp $
+
+LIB= drm_intel
+
+SRCS= intel_bufmgr.c \
+ intel_bufmgr_fake.c \
+ intel_bufmgr_gem.c \
+ intel_chipset.c \
+ intel_decode.c \
+ mm.c
+
+.include "../Makefile.inc"
+
+CPPFLAGS+= -I${DRM_SRC}/intel \
+ -I${X11BASE}/include
+
+LDADD+= -L${.CURDIR}/../libdrm/${__objdir} -ldrm \
+ -L${X11BASE}/lib -lpciaccess
+
+obj: _xenocara_obj
+
+beforeinstall:
+ rm -f ${DESTDIR}${LIBDIR}/lib${LIB}.la
+
+.include <bsd.lib.mk>
+.include <bsd.xorg.mk>
+
+.PATH: ${DRM_SRC}/intel
diff --git a/lib/libdrm/mk/libdrm_intel/shlib_version b/lib/libdrm/mk/libdrm_intel/shlib_version
new file mode 100644
index 000000000..11ab6a71a
--- /dev/null
+++ b/lib/libdrm/mk/libdrm_intel/shlib_version
@@ -0,0 +1,2 @@
+major=5
+minor=4
diff --git a/lib/libdrm/mk/libdrm_radeon/Makefile b/lib/libdrm/mk/libdrm_radeon/Makefile
new file mode 100644
index 000000000..cee956d49
--- /dev/null
+++ b/lib/libdrm/mk/libdrm_radeon/Makefile
@@ -0,0 +1,26 @@
+# $OpenBSD: Makefile,v 1.1 2021/02/11 10:34:51 jsg Exp $
+
+LIB= drm_radeon
+
+SRCS= radeon_bo.c \
+ radeon_bo_gem.c \
+ radeon_cs.c \
+ radeon_cs_gem.c \
+ radeon_cs_space.c \
+ radeon_surface.c
+
+.include "../Makefile.inc"
+
+CPPFLAGS+= -I${DRM_SRC}/radeon
+
+LDADD+= -L${.CURDIR}/../libdrm/${__objdir} -ldrm
+
+obj: _xenocara_obj
+
+beforeinstall:
+ rm -f ${DESTDIR}${LIBDIR}/lib${LIB}.la
+
+.include <bsd.lib.mk>
+.include <bsd.xorg.mk>
+
+.PATH: ${DRM_SRC}/radeon
diff --git a/lib/libdrm/mk/libdrm_radeon/shlib_version b/lib/libdrm/mk/libdrm_radeon/shlib_version
new file mode 100644
index 000000000..d9961ea9f
--- /dev/null
+++ b/lib/libdrm/mk/libdrm_radeon/shlib_version
@@ -0,0 +1,2 @@
+major=4
+minor=0
diff --git a/lib/libdrm/mk/man/Makefile b/lib/libdrm/mk/man/Makefile
new file mode 100644
index 000000000..686af489b
--- /dev/null
+++ b/lib/libdrm/mk/man/Makefile
@@ -0,0 +1,21 @@
+MDOCS= drmAvailable 3 drmHandleEvent 3 drmModeGetResources 3 \
+ drm 7 drm-kms 7 drm-memory 7
+
+beforeinstall:
+.for n s in ${MDOCS}
+ ${INSTALL} ${INSTALL_COPY} -o ${MANOWN} -g ${MANGRP} -m ${MANMODE} \
+ ${.CURDIR}/${n}.${s} ${DESTDIR}${MANDIR}${s}
+.endfor
+
+# maintainer target, not used duing build or install
+mdoc:
+.for n s in ${MDOCS}
+ rst2man-3 ${DRM_SRC}/man/${n}.${s}.rst> ${.CURDIR}/${n}.${s}
+.endfor
+
+obj: _xenocara_obj
+
+.include <bsd.prog.mk>
+.include <bsd.xorg.mk>
+
+.PHONY: mdoc
diff --git a/lib/libdrm/mk/man/drm-kms.7 b/lib/libdrm/mk/man/drm-kms.7
new file mode 100644
index 000000000..da6222da8
--- /dev/null
+++ b/lib/libdrm/mk/man/drm-kms.7
@@ -0,0 +1,240 @@
+.\" Man page generated from reStructuredText.
+.
+.TH DRM-KMS 7 "September 2012" "" "Direct Rendering Manager"
+.SH NAME
+drm-kms \- Kernel Mode-Setting
+.
+.nr rst2man-indent-level 0
+.
+.de1 rstReportMargin
+\\$1 \\n[an-margin]
+level \\n[rst2man-indent-level]
+level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
+-
+\\n[rst2man-indent0]
+\\n[rst2man-indent1]
+\\n[rst2man-indent2]
+..
+.de1 INDENT
+.\" .rstReportMargin pre:
+. RS \\$1
+. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
+. nr rst2man-indent-level +1
+.\" .rstReportMargin post:
+..
+.de UNINDENT
+. RE
+.\" indent \\n[an-margin]
+.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.nr rst2man-indent-level -1
+.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
+..
+.SH SYNOPSIS
+.sp
+\fB#include <xf86drm.h>\fP
+.sp
+\fB#include <xf86drmMode.h>\fP
+.SH DESCRIPTION
+.sp
+Each DRM device provides access to manage which monitors and displays are
+currently used and what frames to be displayed. This task is called \fIKernel
+Mode\-Setting\fP (KMS). Historically, this was done in user\-space and called
+\fIUser\-space Mode\-Setting\fP (UMS). Almost all open\-source drivers now provide the
+KMS kernel API to do this in the kernel, however, many non\-open\-source binary
+drivers from different vendors still do not support this. You can use
+\fBdrmModeSettingSupported\fP(3) to check whether your driver supports this. To
+understand how KMS works, we need to introduce 5 objects: \fICRTCs\fP, \fIPlanes\fP,
+\fIEncoders\fP, \fIConnectors\fP and \fIFramebuffers\fP\&.
+.INDENT 0.0
+.TP
+.B CRTCs
+A \fICRTC\fP short for \fICRT Controller\fP is an abstraction representing a part of
+the chip that contains a pointer to a scanout buffer. Therefore, the number
+of CRTCs available determines how many independent scanout buffers can be
+active at any given time. The CRTC structure contains several fields to
+support this: a pointer to some video memory (abstracted as a frame\-buffer
+object), a list of driven connectors, a display mode and an (x, y) offset
+into the video memory to support panning or configurations where one piece
+of video memory spans multiple CRTCs. A CRTC is the central point where
+configuration of displays happens. You select which objects to use, which
+modes and which parameters and then configure each CRTC via
+\fBdrmModeCrtcSet\fP(3) to drive the display devices.
+.TP
+.B Planes
+A \fIplane\fP respresents an image source that can be blended with or overlayed
+on top of a CRTC during the scanout process. Planes are associated with a
+frame\-buffer to crop a portion of the image memory (source) and optionally
+scale it to a destination size. The result is then blended with or overlayed
+on top of a CRTC. Planes are not provided by all hardware and the number of
+available planes is limited. If planes are not available or if not enough
+planes are available, the user should fall back to normal software blending
+(via GPU or CPU).
+.TP
+.B Encoders
+An \fIencoder\fP takes pixel data from a CRTC and converts it to a format
+suitable for any attached connectors. On some devices, it may be possible to
+have a CRTC send data to more than one encoder. In that case, both encoders
+would receive data from the same scanout buffer, resulting in a \fIcloned\fP
+display configuration across the connectors attached to each encoder.
+.TP
+.B Connectors
+A \fIconnector\fP is the final destination of pixel\-data on a device, and
+usually connects directly to an external display device like a monitor or
+laptop panel. A connector can only be attached to one encoder at a time. The
+connector is also the structure where information about the attached display
+is kept, so it contains fields for display data, \fIEDID\fP data, \fIDPMS\fP and
+\fIconnection status\fP, and information about modes supported on the attached
+displays.
+.TP
+.B Framebuffers
+\fIFramebuffers\fP are abstract memory objects that provide a source of pixel
+data to scanout to a CRTC. Applications explicitly request the creation of
+framebuffers and can control their behavior. Framebuffers rely on the
+underneath memory manager for low\-level memory operations. When creating a
+framebuffer, applications pass a memory handle through the API which is used
+as backing storage. The framebuffer itself is only an abstract object with
+no data. It just refers to memory buffers that must be created with the
+\fBdrm\-memory\fP(7) API.
+.UNINDENT
+.SS Mode\-Setting
+.sp
+Before mode\-setting can be performed, an application needs to call
+\fBdrmSetMaster\fP(3) to become \fIDRM\-Master\fP\&. It then has exclusive access to
+the KMS API. A call to \fBdrmModeGetResources\fP(3) returns a list of \fICRTCs\fP,
+\fIConnectors\fP, \fIEncoders\fP and \fIPlanes\fP\&.
+.sp
+Normal procedure now includes: First, you select which connectors you want to
+use. Users are mostly interested in which monitor or display\-panel is active so
+you need to make sure to arrange them in the correct logical order and select
+the correct ones to use. For each connector, you need to find a CRTC to drive
+this connector. If you want to clone output to two or more connectors, you may
+use a single CRTC for all cloned connectors (if the hardware supports this). To
+find a suitable CRTC, you need to iterate over the list of encoders that are
+available for each connector. Each encoder contains a list of CRTCs that it can
+work with and you simply select one of these CRTCs. If you later program the
+CRTC to control a connector, it automatically selects the best encoder.
+However, this procedure is needed so your CRTC has at least one working encoder
+for the selected connector. See the \fIExamples\fP section below for more
+information.
+.sp
+All valid modes for a connector can be retrieved with a call to
+drmModeGetConnector3 You need to select the mode you want to use and save it.
+The first mode in the list is the default mode with the highest resolution
+possible and often a suitable choice.
+.sp
+After you have a working connector+CRTC+mode combination, you need to create a
+framebuffer that is used for scanout. Memory buffer allocation is
+driver\-depedent and described in \fBdrm\-memory\fP(7). You need to create a
+buffer big enough for your selected mode. Now you can create a framebuffer
+object that uses your memory\-buffer as scanout buffer. You can do this with
+\fBdrmModeAddFB\fP(3) and \fBdrmModeAddFB2\fP(3).
+.sp
+As a last step, you want to program your CRTC to drive your selected connector.
+You can do this with a call to \fBdrmModeSetCrtc\fP(3).
+.SS Page\-Flipping
+.sp
+A call to \fBdrmModeSetCrtc\fP(3) is executed immediately and forces the CRTC
+to use the new scanout buffer. If you want smooth\-transitions without tearing,
+you probably use double\-buffering. You need to create one framebuffer object
+for each buffer you use. You can then call \fBdrmModeSetCrtc\fP(3) on the next
+buffer to flip. If you want to synchronize your flips with \fIvertical\-blanks\fP,
+you can use \fBdrmModePageFlip\fP(3) which schedules your page\-flip for the
+next \fIvblank\fP\&.
+.SS Planes
+.sp
+Planes are controlled independently from CRTCs. That is, a call to
+\fBdrmModeSetCrtc\fP(3) does not affect planes. Instead, you need to call
+\fBdrmModeSetPlane\fP(3) to configure a plane. This requires the plane ID, a
+CRTC, a framebuffer and offsets into the plane\-framebuffer and the
+CRTC\-framebuffer. The CRTC then blends the content from the plane over the CRTC
+framebuffer buffer during scanout. As this does not involve any
+software\-blending, it is way faster than traditional blending. However, plane
+resources are limited. See \fBdrmModeGetPlaneResources\fP(3) for more
+information.
+.SS Cursors
+.sp
+Similar to planes, many hardware also supports cursors. A cursor is a very
+small buffer with an image that is blended over the CRTC framebuffer. You can
+set a different cursor for each CRTC with \fBdrmModeSetCursor\fP(3) and move it
+on the screen with \fBdrmModeMoveCursor\fP(3). This allows to move the cursor
+on the screen without rerendering. If no hardware cursors are supported, you
+need to rerender for each frame the cursor is moved.
+.SH EXAMPLES
+.sp
+Some examples of how basic mode\-setting can be done. See the man\-page of each
+DRM function for more information.
+.SS CRTC/Encoder Selection
+.sp
+If you retrieved all display configuration information via
+\fBdrmModeGetResources\fP(3) as \fBdrmModeRes *res\fP, selected a connector from
+the list in \fBres\->connectors\fP and retrieved the connector\-information as
+\fBdrmModeConnector *conn\fP via \fBdrmModeGetConnector\fP(3) then this example
+shows, how you can find a suitable CRTC id to drive this connector. This
+function takes a file\-descriptor to the DRM device (see \fBdrmOpen\fP(3)) as
+\fBfd\fP, a pointer to the retrieved resources as \fBres\fP and a pointer to the
+selected connector as \fBconn\fP\&. It returns an integer smaller than 0 on
+failure, otherwise, a valid CRTC id is returned.
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+static int modeset_find_crtc(int fd, drmModeRes *res, drmModeConnector *conn)
+{
+ drmModeEncoder *enc;
+ unsigned int i, j;
+
+ /* iterate all encoders of this connector */
+ for (i = 0; i < conn\->count_encoders; ++i) {
+ enc = drmModeGetEncoder(fd, conn\->encoders[i]);
+ if (!enc) {
+ /* cannot retrieve encoder, ignoring... */
+ continue;
+ }
+
+ /* iterate all global CRTCs */
+ for (j = 0; j < res\->count_crtcs; ++j) {
+ /* check whether this CRTC works with the encoder */
+ if (!(enc\->possible_crtcs & (1 << j)))
+ continue;
+
+
+ /* Here you need to check that no other connector
+ * currently uses the CRTC with id "crtc". If you intend
+ * to drive one connector only, then you can skip this
+ * step. Otherwise, simply scan your list of configured
+ * connectors and CRTCs whether this CRTC is already
+ * used. If it is, then simply continue the search here. */
+ if (res\->crtcs[j] "is unused") {
+ drmModeFreeEncoder(enc);
+ return res\->crtcs[j];
+ }
+ }
+
+ drmModeFreeEncoder(enc);
+ }
+
+ /* cannot find a suitable CRTC */
+ return \-ENOENT;
+}
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.SH REPORTING BUGS
+.sp
+Bugs in this manual should be reported to
+\fI\%https://gitlab.freedesktop.org/mesa/drm/\-/issues\fP
+.SH SEE ALSO
+.sp
+\fBdrm\fP(7), \fBdrm\-memory\fP(7), \fBdrmModeGetResources\fP(3),
+\fBdrmModeGetConnector\fP(3), \fBdrmModeGetEncoder\fP(3),
+\fBdrmModeGetCrtc\fP(3), \fBdrmModeSetCrtc\fP(3), \fBdrmModeGetFB\fP(3),
+\fBdrmModeAddFB\fP(3), \fBdrmModeAddFB2\fP(3), \fBdrmModeRmFB\fP(3),
+\fBdrmModePageFlip\fP(3), \fBdrmModeGetPlaneResources\fP(3),
+\fBdrmModeGetPlane\fP(3), \fBdrmModeSetPlane\fP(3), \fBdrmModeSetCursor\fP(3),
+\fBdrmModeMoveCursor\fP(3), \fBdrmSetMaster\fP(3), \fBdrmAvailable\fP(3),
+\fBdrmCheckModesettingSupported\fP(3), \fBdrmOpen\fP(3)
+.\" Generated by docutils manpage writer.
+.
diff --git a/lib/libdrm/mk/man/drm-memory.7 b/lib/libdrm/mk/man/drm-memory.7
new file mode 100644
index 000000000..e497d9962
--- /dev/null
+++ b/lib/libdrm/mk/man/drm-memory.7
@@ -0,0 +1,369 @@
+.\" Man page generated from reStructuredText.
+.
+.TH DRM-MEMORY 7 "September 2012" "" "Direct Rendering Manager"
+.SH NAME
+drm-memory \- DRM Memory Management
+.
+.nr rst2man-indent-level 0
+.
+.de1 rstReportMargin
+\\$1 \\n[an-margin]
+level \\n[rst2man-indent-level]
+level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
+-
+\\n[rst2man-indent0]
+\\n[rst2man-indent1]
+\\n[rst2man-indent2]
+..
+.de1 INDENT
+.\" .rstReportMargin pre:
+. RS \\$1
+. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
+. nr rst2man-indent-level +1
+.\" .rstReportMargin post:
+..
+.de UNINDENT
+. RE
+.\" indent \\n[an-margin]
+.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.nr rst2man-indent-level -1
+.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
+..
+.SH SYNOPSIS
+.sp
+\fB#include <xf86drm.h>\fP
+.SH DESCRIPTION
+.sp
+Many modern high\-end GPUs come with their own memory managers. They even
+include several different caches that need to be synchronized during access.
+Textures, framebuffers, command buffers and more need to be stored in memory
+that can be accessed quickly by the GPU. Therefore, memory management on GPUs
+is highly driver\- and hardware\-dependent.
+.sp
+However, there are several frameworks in the kernel that are used by more than
+one driver. These can be used for trivial mode\-setting without requiring
+driver\-dependent code. But for hardware\-accelerated rendering you need to read
+the manual pages for the driver you want to work with.
+.SS Dumb\-Buffers
+.sp
+Almost all in\-kernel DRM hardware drivers support an API called \fIDumb\-Buffers\fP\&.
+This API allows to create buffers of arbitrary size that can be used for
+scanout. These buffers can be memory mapped via \fBmmap\fP(2) so you can render
+into them on the CPU. However, GPU access to these buffers is often not
+possible. Therefore, they are fine for simple tasks but not suitable for
+complex compositions and renderings.
+.sp
+The \fBDRM_IOCTL_MODE_CREATE_DUMB\fP ioctl can be used to create a dumb buffer.
+The kernel will return a 32\-bit handle that can be used to manage the buffer
+with the DRM API. You can create framebuffers with \fBdrmModeAddFB\fP(3) and
+use it for mode\-setting and scanout. To access the buffer, you first need to
+retrieve the offset of the buffer. The \fBDRM_IOCTL_MODE_MAP_DUMB\fP ioctl
+requests the DRM subsystem to prepare the buffer for memory\-mapping and returns
+a fake\-offset that can be used with \fBmmap\fP(2).
+.sp
+The \fBDRM_IOCTL_MODE_CREATE_DUMB\fP ioctl takes as argument a structure of type
+\fBstruct drm_mode_create_dumb\fP:
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+struct drm_mode_create_dumb {
+ __u32 height;
+ __u32 width;
+ __u32 bpp;
+ __u32 flags;
+
+ __u32 handle;
+ __u32 pitch;
+ __u64 size;
+};
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+The fields \fIheight\fP, \fIwidth\fP, \fIbpp\fP and \fIflags\fP have to be provided by the
+caller. The other fields are filled by the kernel with the return values.
+\fIheight\fP and \fIwidth\fP are the dimensions of the rectangular buffer that is
+created. \fIbpp\fP is the number of bits\-per\-pixel and must be a multiple of 8. You
+most commonly want to pass 32 here. The flags field is currently unused and
+must be zeroed. Different flags to modify the behavior may be added in the
+future. After calling the ioctl, the handle, pitch and size fields are filled
+by the kernel. \fIhandle\fP is a 32\-bit gem handle that identifies the buffer. This
+is used by several other calls that take a gem\-handle or memory\-buffer as
+argument. The \fIpitch\fP field is the pitch (or stride) of the new buffer. Most
+drivers use 32\-bit or 64\-bit aligned stride\-values. The size field contains the
+absolute size in bytes of the buffer. This can normally also be computed with
+\fB(height * pitch + width) * bpp / 4\fP\&.
+.sp
+To prepare the buffer for \fBmmap\fP(2) you need to use the
+\fBDRM_IOCTL_MODE_MAP_DUMB\fP ioctl. It takes as argument a structure of type
+\fBstruct drm_mode_map_dumb\fP:
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+struct drm_mode_map_dumb {
+ __u32 handle;
+ __u32 pad;
+
+ __u64 offset;
+};
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+You need to put the gem\-handle that was previously retrieved via
+\fBDRM_IOCTL_MODE_CREATE_DUMB\fP into the \fIhandle\fP field. The \fIpad\fP field is
+unused padding and must be zeroed. After completion, the \fIoffset\fP field will
+contain an offset that can be used with \fBmmap\fP(2) on the DRM
+file\-descriptor.
+.sp
+If you don\(aqt need your dumb\-buffer, anymore, you have to destroy it with
+\fBDRM_IOCTL_MODE_DESTROY_DUMB\fP\&. If you close the DRM file\-descriptor, all open
+dumb\-buffers are automatically destroyed. This ioctl takes as argument a
+structure of type \fBstruct drm_mode_destroy_dumb\fP:
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+struct drm_mode_destroy_dumb {
+ __u32 handle;
+};
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+You only need to put your handle into the \fIhandle\fP field. After this call, the
+handle is invalid and may be reused for new buffers by the dumb\-API.
+.SS TTM
+.sp
+\fITTM\fP stands for \fITranslation Table Manager\fP and is a generic memory\-manager
+provided by the kernel. It does not provide a common user\-space API so you need
+to look at each driver interface if you want to use it. See for instance the
+radeon man pages for more information on memory\-management with radeon and TTM.
+.SS GEM
+.sp
+\fIGEM\fP stands for \fIGraphics Execution Manager\fP and is a generic DRM
+memory\-management framework in the kernel, that is used by many different
+drivers. GEM is designed to manage graphics memory, control access to the
+graphics device execution context and handle essentially NUMA environment
+unique to modern graphics hardware. GEM allows multiple applications to share
+graphics device resources without the need to constantly reload the entire
+graphics card. Data may be shared between multiple applications with gem
+ensuring that the correct memory synchronization occurs.
+.sp
+GEM provides simple mechanisms to manage graphics data and control execution
+flow within the linux DRM subsystem. However, GEM is not a complete framework
+that is fully driver independent. Instead, if provides many functions that are
+shared between many drivers, but each driver has to implement most of
+memory\-management with driver\-dependent ioctls. This manpage tries to describe
+the semantics (and if it applies, the syntax) that is shared between all
+drivers that use GEM.
+.sp
+All GEM APIs are defined as \fBioctl\fP(2) on the DRM file descriptor. An
+application must be authorized via \fBdrmAuthMagic\fP(3) to the current
+DRM\-Master to access the GEM subsystem. A driver that does not support GEM will
+return \fBENODEV\fP for all these ioctls. Invalid object handles return
+\fBEINVAL\fP and invalid object names return \fBENOENT\fP\&.
+.sp
+Gem provides explicit memory management primitives. System pages are allocated
+when the object is created, either as the fundamental storage for hardware
+where system memory is used by the graphics processor directly, or as backing
+store for graphics\-processor resident memory.
+.sp
+Objects are referenced from user\-space using handles. These are, for all
+intents and purposes, equivalent to file descriptors but avoid the overhead.
+Newer kernel drivers also support the \fBdrm\-prime\fP (7) infrastructure which
+can return real file\-descriptor for GEM\-handles using the linux DMA\-BUF API.
+Objects may be published with a name so that other applications and processes
+can access them. The name remains valid as long as the object exists.
+GEM\-objects are reference counted in the kernel. The object is only destroyed
+when all handles from user\-space were closed.
+.sp
+GEM\-buffers cannot be created with a generic API. Each driver provides its own
+API to create GEM\-buffers. See for example \fBDRM_I915_GEM_CREATE\fP,
+\fBDRM_NOUVEAU_GEM_NEW\fP or \fBDRM_RADEON_GEM_CREATE\fP\&. Each of these ioctls
+returns a GEM\-handle that can be passed to different generic ioctls. The
+\fIlibgbm\fP library from the \fImesa3D\fP distribution tries to provide a
+driver\-independent API to create GBM buffers and retrieve a GBM\-handle to them.
+It allows to create buffers for different use\-cases including scanout,
+rendering, cursors and CPU\-access. See the libgbm library for more information
+or look at the driver\-dependent man\-pages (for example \fBdrm\-intel\fP(7) or
+\fBdrm\-radeon\fP(7)).
+.sp
+GEM\-buffers can be closed with the \fBDRM_IOCTL_GEM_CLOSE\fP ioctl. It takes as
+argument a structure of type \fBstruct drm_gem_close\fP:
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+struct drm_gem_close {
+ __u32 handle;
+ __u32 pad;
+};
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+The \fIhandle\fP field is the GEM\-handle to be closed. The \fIpad\fP field is unused
+padding. It must be zeroed. After this call the GEM handle cannot be used by
+this process anymore and may be reused for new GEM objects by the GEM API.
+.sp
+If you want to share GEM\-objects between different processes, you can create a
+name for them and pass this name to other processes which can then open this
+GEM\-object. Names are currently 32\-bit integer IDs and have no special
+protection. That is, if you put a name on your GEM\-object, every other client
+that has access to the DRM device and is authenticated via
+\fBdrmAuthMagic\fP(3) to the current DRM\-Master, can \fIguess\fP the name and open
+or access the GEM\-object. If you want more fine\-grained access control, you can
+use the new \fBdrm\-prime\fP(7) API to retrieve file\-descriptors for
+GEM\-handles. To create a name for a GEM\-handle, you use the
+\fBDRM_IOCTL_GEM_FLINK\fP ioctl. It takes as argument a structure of type
+\fBstruct drm_gem_flink\fP:
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+struct drm_gem_flink {
+ __u32 handle;
+ __u32 name;
+};
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+You have to put your handle into the \fIhandle\fP field. After completion, the
+kernel has put the new unique name into the name field. You can now pass
+this name to other processes which can then import the name with the
+\fBDRM_IOCTL_GEM_OPEN\fP ioctl. It takes as argument a structure of type
+\fBstruct drm_gem_open\fP:
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+struct drm_gem_open {
+ __u32 name;
+
+ __u32 handle;
+ __u32 size;
+};
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+You have to fill in the \fIname\fP field with the name of the GEM\-object that you
+want to open. The kernel will fill in the \fIhandle\fP and \fIsize\fP fields with the
+new handle and size of the GEM\-object. You can now access the GEM\-object via
+the handle as if you created it with the GEM API.
+.sp
+Besides generic buffer management, the GEM API does not provide any generic
+access. Each driver implements its own functionality on top of this API. This
+includes execution\-buffers, GTT management, context creation, CPU access, GPU
+I/O and more. The next higher\-level API is \fIOpenGL\fP\&. So if you want to use more
+GPU features, you should use the \fImesa3D\fP library to create OpenGL contexts on
+DRM devices. This does \fInot\fP require any windowing\-system like X11, but can
+also be done on raw DRM devices. However, this is beyond the scope of this
+man\-page. You may have a look at other mesa3D man pages, including libgbm and
+libEGL. 2D software\-rendering (rendering with the CPU) can be achieved with the
+dumb\-buffer\-API in a driver\-independent fashion, however, for
+hardware\-accelerated 2D or 3D rendering you must use OpenGL. Any other API that
+tries to abstract the driver\-internals to access GEM\-execution\-buffers and
+other GPU internals, would simply reinvent OpenGL so it is not provided. But if
+you need more detailed information for a specific driver, you may have a look
+into the driver\-manpages, including \fBdrm\-intel\fP(7), \fBdrm\-radeon\fP(7) and
+\fBdrm\-nouveau\fP(7). However, the \fBdrm\-prime\fP(7) infrastructure and the
+generic GEM API as described here allow display\-managers to handle
+graphics\-buffers and render\-clients without any deeper knowledge of the GPU
+that is used. Moreover, it allows to move objects between GPUs and implement
+complex display\-servers that don\(aqt do any rendering on their own. See its
+man\-page for more information.
+.SH EXAMPLES
+.sp
+This section includes examples for basic memory\-management tasks.
+.SS Dumb\-Buffers
+.sp
+This examples shows how to create a dumb\-buffer via the generic DRM API.
+This is driver\-independent (as long as the driver supports dumb\-buffers)
+and provides memory\-mapped buffers that can be used for scanout. This
+example creates a full\-HD 1920x1080 buffer with 32 bits\-per\-pixel and a
+color\-depth of 24 bits. The buffer is then bound to a framebuffer which
+can be used for scanout with the KMS API (see \fBdrm\-kms\fP(7)).
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+struct drm_mode_create_dumb creq;
+struct drm_mode_destroy_dumb dreq;
+struct drm_mode_map_dumb mreq;
+uint32_t fb;
+int ret;
+void *map;
+
+/* create dumb buffer */
+memset(&creq, 0, sizeof(creq));
+creq.width = 1920;
+creq.height = 1080;
+creq.bpp = 32;
+ret = drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &creq);
+if (ret < 0) {
+ /* buffer creation failed; see "errno" for more error codes */
+ ...
+}
+/* creq.pitch, creq.handle and creq.size are filled by this ioctl with
+ * the requested values and can be used now. */
+
+/* create framebuffer object for the dumb\-buffer */
+ret = drmModeAddFB(fd, 1920, 1080, 24, 32, creq.pitch, creq.handle, &fb);
+if (ret) {
+ /* frame buffer creation failed; see "errno" */
+ ...
+}
+/* the framebuffer "fb" can now used for scanout with KMS */
+
+/* prepare buffer for memory mapping */
+memset(&mreq, 0, sizeof(mreq));
+mreq.handle = creq.handle;
+ret = drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &mreq);
+if (ret) {
+ /* DRM buffer preparation failed; see "errno" */
+ ...
+}
+/* mreq.offset now contains the new offset that can be used with mmap() */
+
+/* perform actual memory mapping */
+map = mmap(0, creq.size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, mreq.offset);
+if (map == MAP_FAILED) {
+ /* memory\-mapping failed; see "errno" */
+ ...
+}
+
+/* clear the framebuffer to 0 */
+memset(map, 0, creq.size);
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.SH REPORTING BUGS
+.sp
+Bugs in this manual should be reported to
+\fI\%https://gitlab.freedesktop.org/mesa/drm/\-/issues\fP
+.SH SEE ALSO
+.sp
+\fBdrm\fP(7), \fBdrm\-kms\fP(7), \fBdrm\-prime\fP(7), \fBdrmAvailable\fP(3),
+\fBdrmOpen\fP(3), \fBdrm\-intel\fP(7), \fBdrm\-radeon\fP(7), \fBdrm\-nouveau\fP(7)
+.\" Generated by docutils manpage writer.
+.
diff --git a/lib/libdrm/mk/man/drm.7 b/lib/libdrm/mk/man/drm.7
new file mode 100644
index 000000000..fb70e290f
--- /dev/null
+++ b/lib/libdrm/mk/man/drm.7
@@ -0,0 +1,100 @@
+.\" Man page generated from reStructuredText.
+.
+.TH DRM 7 "September 2012" "" "Direct Rendering Manager"
+.SH NAME
+drm \- Direct Rendering Manager
+.
+.nr rst2man-indent-level 0
+.
+.de1 rstReportMargin
+\\$1 \\n[an-margin]
+level \\n[rst2man-indent-level]
+level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
+-
+\\n[rst2man-indent0]
+\\n[rst2man-indent1]
+\\n[rst2man-indent2]
+..
+.de1 INDENT
+.\" .rstReportMargin pre:
+. RS \\$1
+. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
+. nr rst2man-indent-level +1
+.\" .rstReportMargin post:
+..
+.de UNINDENT
+. RE
+.\" indent \\n[an-margin]
+.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.nr rst2man-indent-level -1
+.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
+..
+.SH SYNOPSIS
+.sp
+\fB#include <xf86drm.h>\fP
+.SH DESCRIPTION
+.sp
+The \fIDirect Rendering Manager\fP (DRM) is a framework to manage \fIGraphics
+Processing Units\fP (GPUs). It is designed to support the needs of complex
+graphics devices, usually containing programmable pipelines well suited
+to 3D graphics acceleration. Furthermore, it is responsible for memory
+management, interrupt handling and DMA to provide a uniform interface to
+applications.
+.sp
+In earlier days, the kernel framework was solely used to provide raw
+hardware access to privileged user\-space processes which implement all
+the hardware abstraction layers. But more and more tasks were moved into
+the kernel. All these interfaces are based on \fBioctl\fP(2) commands on
+the DRM character device. The \fIlibdrm\fP library provides wrappers for these
+system\-calls and many helpers to simplify the API.
+.sp
+When a GPU is detected, the DRM system loads a driver for the detected
+hardware type. Each connected GPU is then presented to user\-space via a
+character\-device that is usually available as \fB/dev/dri/card0\fP and can
+be accessed with \fBopen\fP(2) and \fBclose\fP(2). However, it still
+depends on the graphics driver which interfaces are available on these
+devices. If an interface is not available, the syscalls will fail with
+\fBEINVAL\fP\&.
+.SS Authentication
+.sp
+All DRM devices provide authentication mechanisms. Only a DRM master is
+allowed to perform mode\-setting or modify core state and only one user
+can be DRM master at a time. See \fBdrmSetMaster\fP(3) for information
+on how to become DRM master and what the limitations are. Other DRM users
+can be authenticated to the DRM\-Master via \fBdrmAuthMagic\fP(3) so they
+can perform buffer allocations and rendering.
+.SS Mode\-Setting
+.sp
+Managing connected monitors and displays and changing the current modes
+is called \fIMode\-Setting\fP\&. This is restricted to the current DRM master.
+Historically, this was implemented in user\-space, but new DRM drivers
+implement a kernel interface to perform mode\-setting called \fIKernel Mode
+Setting\fP (KMS). If your hardware\-driver supports it, you can use the KMS
+API provided by DRM. This includes allocating framebuffers, selecting
+modes and managing CRTCs and encoders. See \fBdrm\-kms\fP(7) for more.
+.SS Memory Management
+.sp
+The most sophisticated tasks for GPUs today is managing memory objects.
+Textures, framebuffers, command\-buffers and all other kinds of commands
+for the GPU have to be stored in memory. The DRM driver takes care of
+managing all memory objects, flushing caches, synchronizing access and
+providing CPU access to GPU memory. All memory management is hardware
+driver dependent. However, two generic frameworks are available that are
+used by most DRM drivers. These are the \fITranslation Table Manager\fP
+(TTM) and the \fIGraphics Execution Manager\fP (GEM). They provide generic
+APIs to create, destroy and access buffers from user\-space. However,
+there are still many differences between the drivers so driver\-depedent
+code is still needed. Many helpers are provided in \fIlibgbm\fP (Graphics
+Buffer Manager) from the \fIMesa\fP project. For more information on DRM
+memory management, see \fBdrm\-memory\fP(7).
+.SH REPORTING BUGS
+.sp
+Bugs in this manual should be reported to
+\fI\%https://gitlab.freedesktop.org/mesa/drm/\-/issues\fP\&.
+.SH SEE ALSO
+.sp
+\fBdrm\-kms\fP(7), \fBdrm\-memory\fP(7), \fBdrmSetMaster\fP(3),
+\fBdrmAuthMagic\fP(3), \fBdrmAvailable\fP(3), \fBdrmOpen\fP(3)
+.\" Generated by docutils manpage writer.
+.
diff --git a/lib/libdrm/mk/man/drmAvailable.3 b/lib/libdrm/mk/man/drmAvailable.3
new file mode 100644
index 000000000..75f784af7
--- /dev/null
+++ b/lib/libdrm/mk/man/drmAvailable.3
@@ -0,0 +1,54 @@
+.\" Man page generated from reStructuredText.
+.
+.TH DRMAVAILABLE 3 "September 2012" "" "Direct Rendering Manager"
+.SH NAME
+drmAvailable \- determine whether a DRM kernel driver has been loaded
+.
+.nr rst2man-indent-level 0
+.
+.de1 rstReportMargin
+\\$1 \\n[an-margin]
+level \\n[rst2man-indent-level]
+level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
+-
+\\n[rst2man-indent0]
+\\n[rst2man-indent1]
+\\n[rst2man-indent2]
+..
+.de1 INDENT
+.\" .rstReportMargin pre:
+. RS \\$1
+. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
+. nr rst2man-indent-level +1
+.\" .rstReportMargin post:
+..
+.de UNINDENT
+. RE
+.\" indent \\n[an-margin]
+.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.nr rst2man-indent-level -1
+.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
+..
+.SH SYNOPSIS
+.sp
+\fB#include <xf86drm.h>\fP
+.sp
+\fBint drmAvailable(void);\fP
+.SH DESCRIPTION
+.sp
+\fBdrmAvailable\fP allows the caller to determine whether a kernel DRM
+driver is loaded.
+.SH RETURN VALUE
+.sp
+\fBdrmAvailable\fP returns 1 if a DRM driver is currently loaded.
+Otherwise 0 is returned.
+.SH REPORTING BUGS
+.sp
+Bugs in this function should be reported to
+\fI\%https://gitlab.freedesktop.org/mesa/drm/\-/issues\fP
+.SH SEE ALSO
+.sp
+\fBdrm\fP(7), \fBdrmOpen\fP(3)
+.\" Generated by docutils manpage writer.
+.
diff --git a/lib/libdrm/mk/man/drmHandleEvent.3 b/lib/libdrm/mk/man/drmHandleEvent.3
new file mode 100644
index 000000000..265a7ba29
--- /dev/null
+++ b/lib/libdrm/mk/man/drmHandleEvent.3
@@ -0,0 +1,81 @@
+.\" Man page generated from reStructuredText.
+.
+.TH DRMHANDLEEVENT 3 "September 2012" "" "Direct Rendering Manager"
+.SH NAME
+drmHandleEvent \- read and process pending DRM events
+.
+.nr rst2man-indent-level 0
+.
+.de1 rstReportMargin
+\\$1 \\n[an-margin]
+level \\n[rst2man-indent-level]
+level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
+-
+\\n[rst2man-indent0]
+\\n[rst2man-indent1]
+\\n[rst2man-indent2]
+..
+.de1 INDENT
+.\" .rstReportMargin pre:
+. RS \\$1
+. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
+. nr rst2man-indent-level +1
+.\" .rstReportMargin post:
+..
+.de UNINDENT
+. RE
+.\" indent \\n[an-margin]
+.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.nr rst2man-indent-level -1
+.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
+..
+.SH SYNOPSIS
+.sp
+\fB#include <xf86drm.h>\fP
+.sp
+\fBint drmHandleEvent(int fd, drmEventContextPtr evctx);\fP
+.SH DESCRIPTION
+.sp
+\fBdrmHandleEvent\fP processes outstanding DRM events on the DRM
+file\-descriptor passed as \fBfd\fP\&. This function should be called after
+the DRM file\-descriptor has polled readable; it will read the events and
+use the passed\-in \fBevctx\fP structure to call function pointers with the
+parameters noted below:
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+typedef struct _drmEventContext {
+ int version;
+ void (*vblank_handler) (int fd,
+ unsigned int sequence,
+ unsigned int tv_sec,
+ unsigned int tv_usec,
+ void *user_data)
+ void (*page_flip_handler) (int fd,
+ unsigned int sequence,
+ unsigned int tv_sec,
+ unsigned int tv_usec,
+ void *user_data)
+} drmEventContext, *drmEventContextPtr;
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.SH RETURN VALUE
+.sp
+\fBdrmHandleEvent\fP returns 0 on success, or if there is no data to
+read from the file\-descriptor. Returns \-1 if the read on the
+file\-descriptor fails or returns less than a full event record.
+.SH REPORTING BUGS
+.sp
+Bugs in this function should be reported to
+\fI\%https://gitlab.freedesktop.org/mesa/drm/\-/issues\fP
+.SH SEE ALSO
+.sp
+\fBdrm\fP(7), \fBdrm\-kms\fP(7), \fBdrmModePageFlip\fP(3),
+\fBdrmWaitVBlank\fP(3)
+.\" Generated by docutils manpage writer.
+.
diff --git a/lib/libdrm/mk/man/drmModeGetResources.3 b/lib/libdrm/mk/man/drmModeGetResources.3
new file mode 100644
index 000000000..a50fc77e9
--- /dev/null
+++ b/lib/libdrm/mk/man/drmModeGetResources.3
@@ -0,0 +1,111 @@
+.\" Man page generated from reStructuredText.
+.
+.TH DRMMODEGETRESOURCES 3 "September 2012" "" "Direct Rendering Manager"
+.SH NAME
+drmModeGetResources \- retrieve current display configuration information
+.
+.nr rst2man-indent-level 0
+.
+.de1 rstReportMargin
+\\$1 \\n[an-margin]
+level \\n[rst2man-indent-level]
+level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
+-
+\\n[rst2man-indent0]
+\\n[rst2man-indent1]
+\\n[rst2man-indent2]
+..
+.de1 INDENT
+.\" .rstReportMargin pre:
+. RS \\$1
+. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
+. nr rst2man-indent-level +1
+.\" .rstReportMargin post:
+..
+.de UNINDENT
+. RE
+.\" indent \\n[an-margin]
+.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.nr rst2man-indent-level -1
+.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
+..
+.SH SYNOPSIS
+.sp
+\fB#include <xf86drm.h>\fP
+.sp
+\fB#include <xf86drmMode.h>\fP
+.sp
+\fBdrmModeResPtr drmModeGetResources(int fd);\fP
+.SH DESCRIPTION
+.sp
+\fBdrmModeGetResources\fP allocates, populates, and returns a drmModeRes
+structure containing information about the current display
+configuration. The structure contains the following fields:
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+typedef struct _drmModeRes {
+ int count_fbs;
+ uint32_t *fbs;
+
+ int count_crtcs;
+ uint32_t *crtcs;
+
+ int count_connectors;
+ uint32_t *connectors;
+
+ int count_encoders;
+ uint32_t *encoders;
+
+ uint32_t min_width, max_width;
+ uint32_t min_height, max_height;
+} drmModeRes, *drmModeResPtr;
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+The \fIcount_fbs\fP and \fIfbs\fP fields indicate the number of currently allocated
+framebuffer objects (i.e., objects that can be attached to a given CRTC
+or sprite for display).
+.sp
+The \fIcount_crtcs\fP and \fIcrtcs\fP fields list the available CRTCs in the
+configuration. A CRTC is simply an object that can scan out a
+framebuffer to a display sink, and contains mode timing and relative
+position information. CRTCs drive encoders, which are responsible for
+converting the pixel stream into a specific display protocol (e.g., MIPI
+or HDMI).
+.sp
+The \fIcount_connectors\fP and \fIconnectors\fP fields list the available physical
+connectors on the system. Note that some of these may not be exposed
+from the chassis (e.g., LVDS or eDP). Connectors are attached to
+encoders and contain information about the attached display sink (e.g.,
+width and height in mm, subpixel ordering, and various other
+properties).
+.sp
+The \fIcount_encoders\fP and \fIencoders\fP fields list the available encoders on
+the device. Each encoder may be associated with a CRTC, and may be used
+to drive a particular encoder.
+.sp
+The \fImin_*\fP and \fImax_*\fP fields indicate the maximum size of a framebuffer
+for this device (i.e., the scanout size limit).
+.SH RETURN VALUE
+.sp
+\fBdrmModeGetResources\fP returns a drmModeRes structure pointer on
+success, NULL on failure. The returned structure must be freed with
+\fBdrmModeFreeResources\fP(3).
+.SH REPORTING BUGS
+.sp
+Bugs in this function should be reported to
+\fI\%https://gitlab.freedesktop.org/mesa/drm/\-/issues\fP
+.SH SEE ALSO
+.sp
+\fBdrm\fP(7), \fBdrm\-kms\fP(7), \fBdrmModeGetFB\fP(3), \fBdrmModeAddFB\fP(3),
+\fBdrmModeAddFB2\fP(3), \fBdrmModeRmFB\fP(3), \fBdrmModeDirtyFB\fP(3),
+\fBdrmModeGetCrtc\fP(3), \fBdrmModeSetCrtc\fP (3), \fBdrmModeGetEncoder\fP (3),
+\fBdrmModeGetConnector\fP(3)
+.\" Generated by docutils manpage writer.
+.
diff --git a/lib/libdrm/mk/pkgconfig/Makefile b/lib/libdrm/mk/pkgconfig/Makefile
new file mode 100644
index 000000000..9e607acba
--- /dev/null
+++ b/lib/libdrm/mk/pkgconfig/Makefile
@@ -0,0 +1,31 @@
+# $OpenBSD: Makefile,v 1.1 2021/02/11 10:34:51 jsg Exp $
+
+PC_FILES= libdrm.pc libdrm_amdgpu.pc libdrm_intel.pc libdrm_radeon.pc
+CLEANFILES+=${PC_FILES}
+
+all: ${PC_FILES}
+${PC_FILES}:
+
+libdrm.pc:
+ /bin/sh ${.CURDIR}/gen_libdrm.sh -c ${.CURDIR} -o ${.OBJDIR}
+
+libdrm_amdgpu.pc:
+ /bin/sh ${.CURDIR}/gen_libdrm_amdgpu.sh -c ${.CURDIR} -o ${.OBJDIR}
+
+libdrm_intel.pc:
+ /bin/sh ${.CURDIR}/gen_libdrm_intel.sh -c ${.CURDIR} -o ${.OBJDIR}
+
+libdrm_radeon.pc:
+ /bin/sh ${.CURDIR}/gen_libdrm_radeon.sh -c ${.CURDIR} -o ${.OBJDIR}
+
+install:
+.for PC in ${PC_FILES}
+ ${INSTALL} ${INSTALL_COPY} -o root -g ${SHAREGRP} \
+ -m ${SHAREMODE} ${.OBJDIR}/${PC} ${DESTDIR}${X11BASE}/lib/pkgconfig/
+.endfor
+
+obj: _xenocara_obj
+
+.include <bsd.xconf.mk>
+.include <bsd.prog.mk>
+.include <bsd.xorg.mk>
diff --git a/lib/libdrm/mk/pkgconfig/gen_libdrm.sh b/lib/libdrm/mk/pkgconfig/gen_libdrm.sh
new file mode 100644
index 000000000..2bd2739be
--- /dev/null
+++ b/lib/libdrm/mk/pkgconfig/gen_libdrm.sh
@@ -0,0 +1,66 @@
+#!/bin/sh
+#
+# $OpenBSD: gen_libdrm.sh,v 1.1 2021/02/11 10:34:51 jsg Exp $
+#
+# Copyright (c) 2010,2011 Jasper Lievisse Adriaanse <jasper@openbsd.org>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+# Generate pkg-config file for drm
+
+usage() {
+ echo "usage: ${0##*/} -c current_directory -o obj_directory"
+ exit 1
+}
+
+curdir=
+objdir=
+while getopts "c:o:" flag; do
+ case "$flag" in
+ c)
+ curdir=$OPTARG
+ ;;
+ o)
+ objdir=$OPTARG
+ ;;
+ *)
+ usage
+ ;;
+ esac
+done
+
+[ -n "${curdir}" ] || usage
+if [ ! -d "${curdir}" ]; then
+ echo "${0##*/}: ${curdir}: not found"
+ exit 1
+fi
+[ -n "${objdir}" ] || usage
+if [ ! -w "${objdir}" ]; then
+ echo "${0##*/}: ${objdir}: not found or not writable"
+ exit 1
+fi
+
+lib_version=$(fgrep -m1 version ${curdir}/../../meson.build | sed -e "s/^.*'\(.*\)'.*$/\1/")
+
+pc_file="${objdir}/libdrm.pc"
+cat > ${pc_file} << __EOF__
+prefix=/usr/X11R6
+libdir=\${prefix}/lib
+includedir=\${prefix}/include
+
+Name: libdrm
+Description: Userspace interface to kernel DRM services
+Version: ${lib_version}
+Libs: -L\${libdir} -ldrm
+Cflags: -I\${includedir} -I\${includedir}/libdrm
+__EOF__
diff --git a/lib/libdrm/mk/pkgconfig/gen_libdrm_amdgpu.sh b/lib/libdrm/mk/pkgconfig/gen_libdrm_amdgpu.sh
new file mode 100644
index 000000000..73e2397c0
--- /dev/null
+++ b/lib/libdrm/mk/pkgconfig/gen_libdrm_amdgpu.sh
@@ -0,0 +1,67 @@
+#!/bin/sh
+#
+# $OpenBSD: gen_libdrm_amdgpu.sh,v 1.1 2021/02/11 10:34:51 jsg Exp $
+#
+# Copyright (c) 2010,2011 Jasper Lievisse Adriaanse <jasper@openbsd.org>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+# Generate pkg-config file for libdrm_amdgpu
+
+usage() {
+ echo "usage: ${0##*/} -c current_directory -o obj_directory"
+ exit 1
+}
+
+curdir=
+objdir=
+while getopts "c:o:" flag; do
+ case "$flag" in
+ c)
+ curdir=$OPTARG
+ ;;
+ o)
+ objdir=$OPTARG
+ ;;
+ *)
+ usage
+ ;;
+ esac
+done
+
+[ -n "${curdir}" ] || usage
+if [ ! -d "${curdir}" ]; then
+ echo "${0##*/}: ${curdir}: not found"
+ exit 1
+fi
+[ -n "${objdir}" ] || usage
+if [ ! -w "${objdir}" ]; then
+ echo "${0##*/}: ${objdir}: not found or not writable"
+ exit 1
+fi
+
+lib_version=$(fgrep -m1 version ${curdir}/../../meson.build | sed -e "s/^.*'\(.*\)'.*$/\1/")
+
+pc_file="${objdir}/libdrm_amdgpu.pc"
+cat > ${pc_file} << __EOF__
+prefix=/usr/X11R6
+libdir=\${prefix}/lib
+includedir=\${prefix}/include
+
+Name: libdrm_amdgpu
+Description: Userspace interface to kernel DRM services for amdgpu
+Version: ${lib_version}
+Requires.private: libdrm
+Libs: -L\${libdir} -ldrm_amdgpu
+Cflags: -I\${includedir} -I\${includedir}/libdrm
+__EOF__
diff --git a/lib/libdrm/mk/pkgconfig/gen_libdrm_intel.sh b/lib/libdrm/mk/pkgconfig/gen_libdrm_intel.sh
new file mode 100644
index 000000000..54875e936
--- /dev/null
+++ b/lib/libdrm/mk/pkgconfig/gen_libdrm_intel.sh
@@ -0,0 +1,67 @@
+#!/bin/sh
+#
+# $OpenBSD: gen_libdrm_intel.sh,v 1.1 2021/02/11 10:34:51 jsg Exp $
+#
+# Copyright (c) 2010,2011 Jasper Lievisse Adriaanse <jasper@openbsd.org>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+# Generate pkg-config file for libdrm_intel
+
+usage() {
+ echo "usage: ${0##*/} -c current_directory -o obj_directory"
+ exit 1
+}
+
+curdir=
+objdir=
+while getopts "c:o:" flag; do
+ case "$flag" in
+ c)
+ curdir=$OPTARG
+ ;;
+ o)
+ objdir=$OPTARG
+ ;;
+ *)
+ usage
+ ;;
+ esac
+done
+
+[ -n "${curdir}" ] || usage
+if [ ! -d "${curdir}" ]; then
+ echo "${0##*/}: ${curdir}: not found"
+ exit 1
+fi
+[ -n "${objdir}" ] || usage
+if [ ! -w "${objdir}" ]; then
+ echo "${0##*/}: ${objdir}: not found or not writable"
+ exit 1
+fi
+
+lib_version=$(fgrep -m1 version ${curdir}/../../meson.build | sed -e "s/^.*'\(.*\)'.*$/\1/")
+
+pc_file="${objdir}/libdrm_intel.pc"
+cat > ${pc_file} << __EOF__
+prefix=/usr/X11R6
+libdir=\${prefix}/lib
+includedir=\${prefix}/include
+
+Name: libdrm_intel
+Description: Userspace interface to intel kernel DRM services
+Version: ${lib_version}
+Requires: libdrm
+Libs: -L\${libdir} -ldrm_intel
+Cflags: -I\${includedir} -I\${includedir}/libdrm
+__EOF__
diff --git a/lib/libdrm/mk/pkgconfig/gen_libdrm_radeon.sh b/lib/libdrm/mk/pkgconfig/gen_libdrm_radeon.sh
new file mode 100644
index 000000000..1860cc30f
--- /dev/null
+++ b/lib/libdrm/mk/pkgconfig/gen_libdrm_radeon.sh
@@ -0,0 +1,67 @@
+#!/bin/sh
+#
+# $OpenBSD: gen_libdrm_radeon.sh,v 1.1 2021/02/11 10:34:51 jsg Exp $
+#
+# Copyright (c) 2010,2011 Jasper Lievisse Adriaanse <jasper@openbsd.org>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+# Generate pkg-config file for libdrm_radeon
+
+usage() {
+ echo "usage: ${0##*/} -c current_directory -o obj_directory"
+ exit 1
+}
+
+curdir=
+objdir=
+while getopts "c:o:" flag; do
+ case "$flag" in
+ c)
+ curdir=$OPTARG
+ ;;
+ o)
+ objdir=$OPTARG
+ ;;
+ *)
+ usage
+ ;;
+ esac
+done
+
+[ -n "${curdir}" ] || usage
+if [ ! -d "${curdir}" ]; then
+ echo "${0##*/}: ${curdir}: not found"
+ exit 1
+fi
+[ -n "${objdir}" ] || usage
+if [ ! -w "${objdir}" ]; then
+ echo "${0##*/}: ${objdir}: not found or not writable"
+ exit 1
+fi
+
+lib_version=$(fgrep -m1 version ${curdir}/../../meson.build | sed -e "s/^.*'\(.*\)'.*$/\1/")
+
+pc_file="${objdir}/libdrm_radeon.pc"
+cat > ${pc_file} << __EOF__
+prefix=/usr/X11R6
+libdir=\${prefix}/lib
+includedir=\${prefix}/include
+
+Name: libdrm_radeon
+Description: Userspace interface to kernel DRM services for radeon
+Version: ${lib_version}
+Requires.private: libdrm
+Libs: -L\${libdir} -ldrm_radeon
+Cflags: -I\${includedir} -I\${includedir}/libdrm
+__EOF__