diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a6e3bd4a..b99dc912 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -14,7 +14,7 @@ # repository's registry will be used there as well. variables: UPSTREAM_REPO: mesa/drm - DEBIAN_TAG: "2019-11-16" + DEBIAN_TAG: "2020-11-15" DEBIAN_VERSION: buster-slim DEBIAN_IMAGE: "$CI_REGISTRY_IMAGE/debian/$DEBIAN_VERSION:$DEBIAN_TAG" @@ -122,10 +122,9 @@ meson-arch-daily: base-devel cairo cunit - docbook-xsl libatomic_ops libpciaccess - libxslt meson valgrind + python-docutils extends: .meson-build diff --git a/.gitlab-ci/debian-install.sh b/.gitlab-ci/debian-install.sh index b2f1a791..886e808f 100644 --- a/.gitlab-ci/debian-install.sh +++ b/.gitlab-ci/debian-install.sh @@ -33,7 +33,6 @@ apt-get install -y --no-remove \ libcairo2-dev \ libcunit1-dev \ libpciaccess-dev \ - libxslt1-dev \ meson \ ninja-build \ pkg-config \ @@ -41,8 +40,8 @@ apt-get install -y --no-remove \ python3-pip \ python3-wheel \ python3-setuptools \ - valgrind \ - xsltproc + python3-docutils \ + valgrind for arch in ${CROSS_ARCHITECTURES[@]}; do cross_file=/cross_file-$arch.txt diff --git a/man/drm-kms.7.rst b/man/drm-kms.7.rst new file mode 100644 index 00000000..e91fbe27 --- /dev/null +++ b/man/drm-kms.7.rst @@ -0,0 +1,229 @@ +======= +drm-kms +======= + +------------------- +Kernel Mode-Setting +------------------- + +:Date: September 2012 +:Manual section: 7 +:Manual group: Direct Rendering Manager + +Synopsis +======== + +``#include `` + +``#include `` + +Description +=========== + +Each DRM device provides access to manage which monitors and displays are +currently used and what frames to be displayed. This task is called *Kernel +Mode-Setting* (KMS). Historically, this was done in user-space and called +*User-space Mode-Setting* (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 +**drmModeSettingSupported**\ (3) to check whether your driver supports this. To +understand how KMS works, we need to introduce 5 objects: *CRTCs*, *Planes*, +*Encoders*, *Connectors* and *Framebuffers*. + +CRTCs + A *CRTC* short for *CRT Controller* 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 + **drmModeCrtcSet**\ (3) to drive the display devices. + +Planes + A *plane* 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). + +Encoders + An *encoder* 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 *cloned* + display configuration across the connectors attached to each encoder. + +Connectors + A *connector* 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, *EDID* data, *DPMS* and + *connection status*, and information about modes supported on the attached + displays. + +Framebuffers + *Framebuffers* 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 + **drm-memory**\ (7) API. + +Mode-Setting +------------ + +Before mode-setting can be performed, an application needs to call +**drmSetMaster**\ (3) to become *DRM-Master*. It then has exclusive access to +the KMS API. A call to **drmModeGetResources**\ (3) returns a list of *CRTCs*, +*Connectors*, *Encoders* and *Planes*. + +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 *Examples* section below for more +information. + +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. + +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 **drm-memory**\ (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 +**drmModeAddFB**\ (3) and **drmModeAddFB2**\ (3). + +As a last step, you want to program your CRTC to drive your selected connector. +You can do this with a call to **drmModeSetCrtc**\ (3). + +Page-Flipping +------------- + +A call to **drmModeSetCrtc**\ (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 **drmModeSetCrtc**\ (3) on the next +buffer to flip. If you want to synchronize your flips with *vertical-blanks*, +you can use **drmModePageFlip**\ (3) which schedules your page-flip for the +next *vblank*. + +Planes +------ + +Planes are controlled independently from CRTCs. That is, a call to +**drmModeSetCrtc**\ (3) does not affect planes. Instead, you need to call +**drmModeSetPlane**\ (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 **drmModeGetPlaneResources**\ (3) for more +information. + +Cursors +------- + +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 **drmModeSetCursor**\ (3) and move it +on the screen with **drmModeMoveCursor**\ (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. + +Examples +======== + +Some examples of how basic mode-setting can be done. See the man-page of each +DRM function for more information. + +CRTC/Encoder Selection +---------------------- + +If you retrieved all display configuration information via +**drmModeGetResources**\ (3) as ``drmModeRes *res``, selected a connector from +the list in ``res->connectors`` and retrieved the connector-information as +``drmModeConnector *conn`` via **drmModeGetConnector**\ (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 **drmOpen**\ (3)) as +``fd``, a pointer to the retrieved resources as ``res`` and a pointer to the +selected connector as ``conn``. It returns an integer smaller than 0 on +failure, otherwise, a valid CRTC id is returned. + +:: + + 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; + } + +Reporting Bugs +============== + +Bugs in this manual should be reported to +https://gitlab.freedesktop.org/mesa/drm/-/issues + +See Also +======== + +**drm**\ (7), **drm-memory**\ (7), **drmModeGetResources**\ (3), +**drmModeGetConnector**\ (3), **drmModeGetEncoder**\ (3), +**drmModeGetCrtc**\ (3), **drmModeSetCrtc**\ (3), **drmModeGetFB**\ (3), +**drmModeAddFB**\ (3), **drmModeAddFB2**\ (3), **drmModeRmFB**\ (3), +**drmModePageFlip**\ (3), **drmModeGetPlaneResources**\ (3), +**drmModeGetPlane**\ (3), **drmModeSetPlane**\ (3), **drmModeSetCursor**\ (3), +**drmModeMoveCursor**\ (3), **drmSetMaster**\ (3), **drmAvailable**\ (3), +**drmCheckModesettingSupported**\ (3), **drmOpen**\ (3) diff --git a/man/drm-kms.xml b/man/drm-kms.xml deleted file mode 100644 index 888df66a..00000000 --- a/man/drm-kms.xml +++ /dev/null @@ -1,341 +0,0 @@ - - - - - - - - Direct Rendering Manager - libdrm - September 2012 - - - Developer - David - Herrmann - dh.herrmann@googlemail.com - - - - - - drm-kms - 7 - - - - drm-kms - Kernel Mode-Setting - - - - - #include <xf86drm.h> - #include <xf86drmMode.h> - - - - - Description - Each DRM device provides access to manage which monitors and displays - are currently used and what frames to be displayed. This task is - called Kernel Mode-Setting (KMS). Historically, - this was done in user-space and called - User-space Mode-Setting (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 - drmModeSettingSupported3 - to check whether your driver supports this. To understand how KMS - works, we need to introduce 5 objects: CRTCs, - Planes, Encoders, - Connectors and - Framebuffers. - - - - CRTCs - - A CRTC short for - CRT Controller 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 - drmModeCrtcSet3 - to drive the display devices. - - - - Planes - - A plane 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). - - - - Encoders - - An encoder 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 cloned display - configuration across the connectors attached to each - encoder. - - - - Connectors - - A connector 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, EDID data, - DPMS and - connection status, and information about - modes supported on the attached displays. - - - - Framebuffers - - Framebuffers 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 - drm-memory7 - API. - - - - - - - Mode-Setting - Before mode-setting can be performed, an application needs to call - drmSetMaster3 - to become DRM-Master. It then has exclusive - access to the KMS API. A call to - drmModeGetResources3 - returns a list of CRTCs, - Connectors, Encoders and - Planes. - - 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 Examples - section below for more information. - - 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. - - 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 - drm-memory7. - 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 - drmModeAddFB3 - and - drmModeAddFB23. - - As a last step, you want to program your CRTC to drive your selected - connector. You can do this with a call to - drmModeSetCrtc3. - - - - Page-Flipping - A call to - drmModeSetCrtc3 - 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 - drmModeSetCrtc3 - on the next buffer to flip. If you want to synchronize your flips - with vertical-blanks, you can use - drmModePageFlip3 - which schedules your page-flip for the next - vblank. - - - - Planes - Planes are controlled independently from CRTCs. That is, a call to - drmModeSetCrtc3 - does not affect planes. Instead, you need to call - drmModeSetPlane3 - 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 - drmModeGetPlaneResources3 - for more information. - - - - Cursors - 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 - drmModeSetCursor3 - and move it on the screen with - drmModeMoveCursor3. - 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. - - - - - - Examples - Some examples of how basic mode-setting can be done. See the man-page - of each DRM function for more information. - - - CRTC/Encoder Selection - If you retrieved all display configuration information via - drmModeGetResources3 - as drmModeRes *res, - selected a connector from the list in - res->connectors - and retrieved the connector-information as - drmModeConnector *conn - via - drmModeGetConnector3 - 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 - drmOpen3) - as fd, a pointer to the retrieved resources as - res and a pointer to the selected connector as - conn. It returns an integer smaller than 0 on - failure, otherwise, a valid CRTC id is returned. - - -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; -} - - - - - - - - Reporting Bugs - Bugs in this manual should be reported to - https://gitlab.freedesktop.org/mesa/drm/-/issues - - - - See Also - - drm7, - drm-memory7, - drmModeGetResources3, - drmModeGetConnector3, - drmModeGetEncoder3, - drmModeGetCrtc3, - drmModeSetCrtc3, - drmModeGetFB3, - drmModeAddFB3, - drmModeAddFB23, - drmModeRmFB3, - drmModePageFlip3, - drmModeGetPlaneResources3, - drmModeGetPlane3, - drmModeSetPlane3, - drmModeSetCursor3, - drmModeMoveCursor3, - drmSetMaster3, - drmAvailable3, - drmCheckModesettingSupported3, - drmOpen3 - - - diff --git a/man/drm-memory.7.rst b/man/drm-memory.7.rst new file mode 100644 index 00000000..c272c994 --- /dev/null +++ b/man/drm-memory.7.rst @@ -0,0 +1,322 @@ +========== +drm-memory +========== + +--------------------- +DRM Memory Management +--------------------- + +:Date: September 2012 +:Manual section: 7 +:Manual group: Direct Rendering Manager + +Synopsis +======== + +``#include `` + +Description +=========== + +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. + +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. + +Dumb-Buffers +------------ + +Almost all in-kernel DRM hardware drivers support an API called *Dumb-Buffers*. +This API allows to create buffers of arbitrary size that can be used for +scanout. These buffers can be memory mapped via **mmap**\ (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. + +The ``DRM_IOCTL_MODE_CREATE_DUMB`` 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 **drmModeAddFB**\ (3) and +use it for mode-setting and scanout. To access the buffer, you first need to +retrieve the offset of the buffer. The ``DRM_IOCTL_MODE_MAP_DUMB`` ioctl +requests the DRM subsystem to prepare the buffer for memory-mapping and returns +a fake-offset that can be used with **mmap**\ (2). + +The ``DRM_IOCTL_MODE_CREATE_DUMB`` ioctl takes as argument a structure of type +``struct drm_mode_create_dumb``: + +:: + + struct drm_mode_create_dumb { + __u32 height; + __u32 width; + __u32 bpp; + __u32 flags; + + __u32 handle; + __u32 pitch; + __u64 size; + }; + +The fields *height*, *width*, *bpp* and *flags* have to be provided by the +caller. The other fields are filled by the kernel with the return values. +*height* and *width* are the dimensions of the rectangular buffer that is +created. *bpp* 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. *handle* 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 *pitch* 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 +``(height * pitch + width) * bpp / 4``. + +To prepare the buffer for **mmap**\ (2) you need to use the +``DRM_IOCTL_MODE_MAP_DUMB`` ioctl. It takes as argument a structure of type +``struct drm_mode_map_dumb``: + +:: + + struct drm_mode_map_dumb { + __u32 handle; + __u32 pad; + + __u64 offset; + }; + +You need to put the gem-handle that was previously retrieved via +``DRM_IOCTL_MODE_CREATE_DUMB`` into the *handle* field. The *pad* field is +unused padding and must be zeroed. After completion, the *offset* field will +contain an offset that can be used with **mmap**\ (2) on the DRM +file-descriptor. + +If you don't need your dumb-buffer, anymore, you have to destroy it with +``DRM_IOCTL_MODE_DESTROY_DUMB``. If you close the DRM file-descriptor, all open +dumb-buffers are automatically destroyed. This ioctl takes as argument a +structure of type ``struct drm_mode_destroy_dumb``: + +:: + + struct drm_mode_destroy_dumb { + __u32 handle; + }; + +You only need to put your handle into the *handle* field. After this call, the +handle is invalid and may be reused for new buffers by the dumb-API. + +TTM +--- + +*TTM* stands for *Translation Table Manager* 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. + +GEM +--- + +*GEM* stands for *Graphics Execution Manager* 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. + +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. + +All GEM APIs are defined as **ioctl**\ (2) on the DRM file descriptor. An +application must be authorized via **drmAuthMagic**\ (3) to the current +DRM-Master to access the GEM subsystem. A driver that does not support GEM will +return ``ENODEV`` for all these ioctls. Invalid object handles return +``EINVAL`` and invalid object names return ``ENOENT``. + +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. + +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 **drm-prime** (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. + +GEM-buffers cannot be created with a generic API. Each driver provides its own +API to create GEM-buffers. See for example ``DRM_I915_GEM_CREATE``, +``DRM_NOUVEAU_GEM_NEW`` or ``DRM_RADEON_GEM_CREATE``. Each of these ioctls +returns a GEM-handle that can be passed to different generic ioctls. The +*libgbm* library from the *mesa3D* 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 **drm-intel**\ (7) or +**drm-radeon**\ (7)). + +GEM-buffers can be closed with the ``DRM_IOCTL_GEM_CLOSE`` ioctl. It takes as +argument a structure of type ``struct drm_gem_close``: + +:: + + struct drm_gem_close { + __u32 handle; + __u32 pad; + }; + +The *handle* field is the GEM-handle to be closed. The *pad* 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. + +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 +**drmAuthMagic**\ (3) to the current DRM-Master, can *guess* the name and open +or access the GEM-object. If you want more fine-grained access control, you can +use the new **drm-prime**\ (7) API to retrieve file-descriptors for +GEM-handles. To create a name for a GEM-handle, you use the +``DRM_IOCTL_GEM_FLINK`` ioctl. It takes as argument a structure of type +``struct drm_gem_flink``: + +:: + + struct drm_gem_flink { + __u32 handle; + __u32 name; + }; + +You have to put your handle into the *handle* 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 +``DRM_IOCTL_GEM_OPEN`` ioctl. It takes as argument a structure of type +``struct drm_gem_open``: + +:: + + struct drm_gem_open { + __u32 name; + + __u32 handle; + __u32 size; + }; + +You have to fill in the *name* field with the name of the GEM-object that you +want to open. The kernel will fill in the *handle* and *size* 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. + +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 *OpenGL*. So if you want to use more +GPU features, you should use the *mesa3D* library to create OpenGL contexts on +DRM devices. This does *not* 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 **drm-intel**\ (7), **drm-radeon**\ (7) and +**drm-nouveau**\ (7). However, the **drm-prime**\ (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't do any rendering on their own. See its +man-page for more information. + +Examples +======== + +This section includes examples for basic memory-management tasks. + +Dumb-Buffers +------------ + +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 **drm-kms**\ (7)). + +:: + + 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); + +Reporting Bugs +============== + +Bugs in this manual should be reported to +https://gitlab.freedesktop.org/mesa/drm/-/issues + +See Also +======== + +**drm**\ (7), **drm-kms**\ (7), **drm-prime**\ (7), **drmAvailable**\ (3), +**drmOpen**\ (3), **drm-intel**\ (7), **drm-radeon**\ (7), **drm-nouveau**\ (7) diff --git a/man/drm-memory.xml b/man/drm-memory.xml deleted file mode 100644 index 33c05af5..00000000 --- a/man/drm-memory.xml +++ /dev/null @@ -1,429 +0,0 @@ - - - - - - - - Direct Rendering Manager - libdrm - September 2012 - - - Developer - David - Herrmann - dh.herrmann@googlemail.com - - - - - - drm-memory - 7 - - - - drm-memory - drm-mm - drm-gem - drm-ttm - DRM Memory Management - - - - - #include <xf86drm.h> - - - - - Description - 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. - - 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. - - - Dumb-Buffers - Almost all in-kernel DRM hardware drivers support an API called - Dumb-Buffers. This API allows to create buffers - of arbitrary size that can be used for scanout. These buffers can be - memory mapped via - mmap2 - 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. - - The DRM_IOCTL_MODE_CREATE_DUMB ioctl can be - used to create a dumb buffer. The kernel will return a 32bit handle - that can be used to manage the buffer with the DRM API. You can - create framebuffers with - drmModeAddFB3 - and use it for mode-setting and scanout. To access the buffer, you - first need to retrieve the offset of the buffer. The - DRM_IOCTL_MODE_MAP_DUMB ioctl requests the DRM - subsystem to prepare the buffer for memory-mapping and returns a - fake-offset that can be used with - mmap2. - - The DRM_IOCTL_MODE_CREATE_DUMB ioctl takes as - argument a structure of type - struct drm_mode_create_dumb: - - -struct drm_mode_create_dumb { - __u32 height; - __u32 width; - __u32 bpp; - __u32 flags; - - __u32 handle; - __u32 pitch; - __u64 size; -}; - - - The fields height, - width, bpp and - flags have to be provided by the caller. - The other fields are filled by the kernel with the return values. - height and - width are the dimensions of the - rectangular buffer that is created. bpp - 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. handle - is a 32bit gem handle that identifies the buffer. This is used by - several other calls that take a gem-handle or memory-buffer as - argument. The pitch field is the - pitch (or stride) of the new buffer. Most drivers use 32bit or 64bit - aligned stride-values. The size field - contains the absolute size in bytes of the buffer. This can normally - also be computed with - (height * pitch + width) * bpp / 4. - - To prepare the buffer for - mmap2 - you need to use the DRM_IOCTL_MODE_MAP_DUMB - ioctl. It takes as argument a structure of type - struct drm_mode_map_dumb: - - -struct drm_mode_map_dumb { - __u32 handle; - __u32 pad; - - __u64 offset; -}; - - - You need to put the gem-handle that was previously retrieved via - DRM_IOCTL_MODE_CREATE_DUMB into the - handle field. The - pad field is unused padding and must be - zeroed. After completion, the offset - field will contain an offset that can be used with - mmap2 - on the DRM file-descriptor. - - If you don't need your dumb-buffer, anymore, you have to destroy it - with DRM_IOCTL_MODE_DESTROY_DUMB. If you close - the DRM file-descriptor, all open dumb-buffers are automatically - destroyed. This ioctl takes as argument a structure of type - struct drm_mode_destroy_dumb: - - -struct drm_mode_destroy_dumb { - __u32 handle; -}; - - - You only need to put your handle into the - handle field. After this call, the handle - is invalid and may be reused for new buffers by the dumb-API. - - - - - TTM - TTM stands for - Translation Table Manager 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 manpages for more - information on memory-management with radeon and TTM. - - - - GEM - GEM stands for - Graphics Execution Manager 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. - - 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. - - All GEM APIs are defined as - ioctl2 - on the DRM file descriptor. An application must be authorized via - drmAuthMagic3 - to the current DRM-Master to access the GEM subsystem. A driver that - does not support gem will return ENODEV for all - these ioctls. Invalid object handles return - EINVAL and invalid object names return - ENOENT. - - 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. - - 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 - drm-prime7 - 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. - - Gem-buffers cannot be created with a generic API. Each driver - provides its own API to create gem-buffers. See for example - DRM_I915_GEM_CREATE, - DRM_NOUVEAU_GEM_NEW or - DRM_RADEON_GEM_CREATE. Each of these ioctls - returns a gem-handle that can be passed to different generic ioctls. - The libgbm library from the - mesa3D 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 - drm-intel7 - or - drm-radeon7). - - Gem-buffers can be closed with the - DRM_IOCTL_GEM_CLOSE ioctl. It takes as argument - a structure of type struct drm_gem_close: - - -struct drm_gem_close { - __u32 handle; - __u32 pad; -}; - - - The handle field is the gem-handle to be - closed. The pad 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. - - 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 32bit - 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 - drmAuthMagic3 - to the current DRM-Master, can guess the name - and open or access the gem-object. If you want more fine-grained - access control, you can use the new - drm-prime7 - API to retrieve file-descriptors for gem-handles. To create a name - for a gem-handle, you use the - DRM_IOCTL_GEM_FLINK ioctl. It takes as argument - a structure of type struct drm_gem_flink: - - -struct drm_gem_flink { - __u32 handle; - __u32 name; -}; - - - You have to put your handle into the - handle 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 - DRM_IOCTL_GEM_OPEN ioctl. It takes as argument - a structure of type struct drm_gem_open: - - -struct drm_gem_open { - __u32 name; - - __u32 handle; - __u32 size; -}; - - - You have to fill in the name field with - the name of the gem-object that you want to open. The kernel will - fill in the handle and - size 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. - - 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 OpenGL. So if you want to - use more GPU features, you should use the - mesa3D library to create OpenGL contexts on DRM - devices. This does not 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 manpages, 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 - drm-intel7, - drm-radeon7 - and - drm-nouveau7. - However, the - drm-prime7 - 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't do any rendering on their own. See its - man-page for more information. - - - - - Examples - This section includes examples for basic memory-management - tasks. - - - Dumb-Buffers - 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 - drm-kms7). - - -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); - - - - - - - - Reporting Bugs - Bugs in this manual should be reported to - https://gitlab.freedesktop.org/mesa/drm/-/issues - - - - See Also - - drm7, - drm-kms7, - drm-prime7, - drmAvailable3, - drmOpen3, - drm-intel7, - drm-radeon7, - drm-nouveau7 - - - diff --git a/man/drm.7.rst b/man/drm.7.rst new file mode 100644 index 00000000..c9b5696f --- /dev/null +++ b/man/drm.7.rst @@ -0,0 +1,91 @@ +=== +drm +=== + +------------------------ +Direct Rendering Manager +------------------------ + +:Date: September 2012 +:Manual section: 7 +:Manual group: Direct Rendering Manager + +Synopsis +======== + +``#include `` + +Description +=========== + +The *Direct Rendering Manager* (DRM) is a framework to manage *Graphics +Processing Units* (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. + +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 **ioctl**\ (2) commands on +the DRM character device. The *libdrm* library provides wrappers for these +system-calls and many helpers to simplify the API. + +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 ``/dev/dri/card0`` and can +be accessed with **open**\ (2) and **close**\ (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 +``EINVAL``. + +Authentication +-------------- + +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 **drmSetMaster**\ (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 **drmAuthMagic**\ (3) so they +can perform buffer allocations and rendering. + +Mode-Setting +------------ + +Managing connected monitors and displays and changing the current modes +is called *Mode-Setting*. 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 *Kernel Mode +Setting* (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 **drm-kms**\ (7) for more. + +Memory Management +----------------- + +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 *Translation Table Manager* +(TTM) and the *Graphics Execution Manager* (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 *libgbm* (Graphics +Buffer Manager) from the *Mesa* project. For more information on DRM +memory management, see **drm-memory**\ (7). + +Reporting Bugs +============== + +Bugs in this manual should be reported to +https://gitlab.freedesktop.org/mesa/drm/-/issues. + +See Also +======== + +**drm-kms**\ (7), **drm-memory**\ (7), **drmSetMaster**\ (3), +**drmAuthMagic**\ (3), **drmAvailable**\ (3), **drmOpen**\ (3) diff --git a/man/drm.xml b/man/drm.xml deleted file mode 100644 index e2e93abe..00000000 --- a/man/drm.xml +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - - - Direct Rendering Manager - libdrm - September 2012 - - - Developer - David - Herrmann - dh.herrmann@googlemail.com - - - - - - drm - 7 - - - - drm - Direct Rendering Manager - - - - - #include <xf86drm.h> - - - - - Description - The Direct Rendering Manager (DRM) is a framework - to manage Graphics Processing Units (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. - - 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 - ioctl2 - commands on the DRM character device. The libdrm - library provides wrappers for these system-calls and many helpers to - simplify the API. - - 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 - /dev/dri/card0 and can be accessed with - open2 - and - close2. - 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 EINVAL. - - - Authentication - 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 - drmSetMaster3 - for information on how to become DRM-Master and what the limitations - are. Other DRM users can be authenticated to the DRM-Master via - drmAuthMagic3 - so they can perform buffer allocations and rendering. - - - - Mode-Setting - Managing connected monitors and displays and changing the current - modes is called Mode-Setting. 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 - Kernel Mode Setting (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 - drm-kms7 - for more. - - - - Memory Management - 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 Translation Table Manager (TTM) and the - Graphics Execution Manager (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 - libgbm (Graphics Buffer Manager) from the - mesa-project. For more information on DRM - memory-management, see - drm-memory7. - - - - - Reporting Bugs - Bugs in this manual should be reported to - https://gitlab.freedesktop.org/mesa/drm/-/issues - - - - See Also - - drm-kms7, - drm-memory7, - drmSetMaster3, - drmAuthMagic3, - drmAvailable3, - drmOpen3 - - - diff --git a/man/drmAvailable.3.rst b/man/drmAvailable.3.rst new file mode 100644 index 00000000..5da77beb --- /dev/null +++ b/man/drmAvailable.3.rst @@ -0,0 +1,41 @@ +============ +drmAvailable +============ + +----------------------------------------------------- +determine whether a DRM kernel driver has been loaded +----------------------------------------------------- + +:Date: September 2012 +:Manual section: 3 +:Manual group: Direct Rendering Manager + +Synopsis +======== + +``#include `` + +``int drmAvailable(void);`` + +Description +=========== + +``drmAvailable`` allows the caller to determine whether a kernel DRM +driver is loaded. + +Return Value +============ + +``drmAvailable`` returns 1 if a DRM driver is currently loaded. +Otherwise 0 is returned. + +Reporting Bugs +============== + +Bugs in this function should be reported to +https://gitlab.freedesktop.org/mesa/drm/-/issues + +See Also +======== + +**drm**\ (7), **drmOpen**\ (3) diff --git a/man/drmAvailable.xml b/man/drmAvailable.xml deleted file mode 100644 index 2ea5b4db..00000000 --- a/man/drmAvailable.xml +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - - Direct Rendering Manager - libdrm - September 2012 - - - Developer - David - Herrmann - dh.herrmann@googlemail.com - - - - - - drmAvailable - 3 - - - - drmAvailable - determine whether a DRM kernel driver has been - loaded - - - - - - #include <xf86drm.h> - - - int drmAvailable - void - - - - - - - Description - drmAvailable allows the caller to determine - whether a kernel DRM driver is loaded. - - - - Return Value - drmAvailable returns 1 if a DRM driver is - currently loaded. Otherwise 0 is returned. - - - - Reporting Bugs - Bugs in this function should be reported to - https://gitlab.freedesktop.org/mesa/drm/-/issues - - - - See Also - - drm7, - drmOpen3 - - - diff --git a/man/drmHandleEvent.3.rst b/man/drmHandleEvent.3.rst new file mode 100644 index 00000000..ecc63ed0 --- /dev/null +++ b/man/drmHandleEvent.3.rst @@ -0,0 +1,62 @@ +============== +drmHandleEvent +============== + +----------------------------------- +read and process pending DRM events +----------------------------------- + +:Date: September 2012 +:Manual section: 3 +:Manual group: Direct Rendering Manager + +Synopsis +======== + +``#include `` + +``int drmHandleEvent(int fd, drmEventContextPtr evctx);`` + +Description +=========== + +``drmHandleEvent`` processes outstanding DRM events on the DRM +file-descriptor passed as ``fd``. This function should be called after +the DRM file-descriptor has polled readable; it will read the events and +use the passed-in ``evctx`` structure to call function pointers with the +parameters noted below: + +:: + + 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; + +Return Value +============ + +``drmHandleEvent`` 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. + +Reporting Bugs +============== + +Bugs in this function should be reported to +https://gitlab.freedesktop.org/mesa/drm/-/issues + +See Also +======== + +**drm**\ (7), **drm-kms**\ (7), **drmModePageFlip**\ (3), +**drmWaitVBlank**\ (3) diff --git a/man/drmHandleEvent.xml b/man/drmHandleEvent.xml deleted file mode 100644 index 0ca7494d..00000000 --- a/man/drmHandleEvent.xml +++ /dev/null @@ -1,101 +0,0 @@ - - - - - - - - Direct Rendering Manager - libdrm - September 2012 - - - Developer - David - Herrmann - dh.herrmann@googlemail.com - - - - - - drmHandleEvent - 3 - - - - drmHandleEvent - read and process pending DRM events - - - - - - #include <xf86drm.h> - - - int drmHandleEvent - int fd - drmEventContextPtr evctx - - - - - - - Description - drmHandleEvent processes outstanding DRM events - on the DRM file-descriptor passed as fd. This - function should be called after the DRM file-descriptor has polled - readable; it will read the events and use the passed-in - evctx structure to call function pointers - with the parameters noted below: - - -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; - - - - - - - - Return Value - drmHandleEvent 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. - - - - Reporting Bugs - Bugs in this function should be reported to - https://gitlab.freedesktop.org/mesa/drm/-/issues - - - - See Also - - drm7, - drm-kms7, - drmModePageFlip3, - drmWaitVBlank3 - - - diff --git a/man/drmModeGetResources.3.rst b/man/drmModeGetResources.3.rst new file mode 100644 index 00000000..d1358d22 --- /dev/null +++ b/man/drmModeGetResources.3.rst @@ -0,0 +1,92 @@ +=================== +drmModeGetResources +=================== + +-------------------------------------------------- +retrieve current display configuration information +-------------------------------------------------- + +:Date: September 2012 +:Manual section: 3 +:Manual group: Direct Rendering Manager + +Synopsis +======== + +``#include `` + +``#include `` + +``drmModeResPtr drmModeGetResources(int fd);`` + +Description +=========== + +``drmModeGetResources`` allocates, populates, and returns a drmModeRes +structure containing information about the current display +configuration. The structure contains the following fields: + +:: + + 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; + +The *count_fbs* and *fbs* fields indicate the number of currently allocated +framebuffer objects (i.e., objects that can be attached to a given CRTC +or sprite for display). + +The *count_crtcs* and *crtcs* 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). + +The *count_connectors* and *connectors* 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). + +The *count_encoders* and *encoders* 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. + +The *min_\** and *max_\** fields indicate the maximum size of a framebuffer +for this device (i.e., the scanout size limit). + +Return Value +============ + +``drmModeGetResources`` returns a drmModeRes structure pointer on +success, NULL on failure. The returned structure must be freed with +**drmModeFreeResources**\ (3). + +Reporting Bugs +============== + +Bugs in this function should be reported to +https://gitlab.freedesktop.org/mesa/drm/-/issues + +See Also +======== + +**drm**\ (7), **drm-kms**\ (7), **drmModeGetFB**\ (3), **drmModeAddFB**\ (3), +**drmModeAddFB2**\ (3), **drmModeRmFB**\ (3), **drmModeDirtyFB**\ (3), +**drmModeGetCrtc**\ (3), **drmModeSetCrtc** (3), **drmModeGetEncoder** (3), +**drmModeGetConnector**\ (3) diff --git a/man/drmModeGetResources.xml b/man/drmModeGetResources.xml deleted file mode 100644 index 64a711f2..00000000 --- a/man/drmModeGetResources.xml +++ /dev/null @@ -1,138 +0,0 @@ - - - - - - - - Direct Rendering Manager - libdrm - September 2012 - - - Developer - David - Herrmann - dh.herrmann@googlemail.com - - - - - - drmModeGetResources - 3 - - - - drmModeGetResources - retrieve current display configuration information - - - - - - #include <xf86drm.h> - #include <xf86drmMode.h> - - - drmModeResPtr drmModeGetResources - int fd - - - - - - - Description - drmModeGetResources allocates, populates, and - returns a drmModeRes structure containing - information about the current display configuration. The structure - contains the following fields: - - -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; - - - - - The count_fbs and - fbs fields indicate the number of currently - allocated framebuffer objects (i.e., objects that can be attached to - a given CRTC or sprite for display). - - The count_crtcs and - crtcs 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). - - The count_connectors and - connectors 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). - - The count_encoders and - encoders 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. - - The min* and - max* fields indicate the maximum size of a - framebuffer for this device (i.e., the scanout size limit). - - - - Return Value - drmModeGetResources returns a drmModeRes - structure pointer on success, NULL on failure. The - returned structure must be freed with - drmModeFreeResources3. - - - - Reporting Bugs - Bugs in this function should be reported to - https://gitlab.freedesktop.org/mesa/drm/-/issues - - - - See Also - - drm7, - drm-kms7, - drmModeGetFB3, - drmModeAddFB3, - drmModeAddFB23, - drmModeRmFB3, - drmModeDirtyFB3, - drmModeGetCrtc3, - drmModeSetCrtc3, - drmModeGetEncoder3, - drmModeGetConnector3 - - - diff --git a/man/meson.build b/man/meson.build index 45eaeda0..92a4c375 100644 --- a/man/meson.build +++ b/man/meson.build @@ -18,50 +18,23 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -xsltproc_args = [ - '--stringparam', 'man.authors.section.enabled', '0', - '--stringparam', 'man.copyright.section.enabled', '0', - '--stringparam', 'funcsynopsis.style', 'ansi', - '--stringparam', 'man.output.quietly', '1', - '--nonet', manpage_style, +rst_pages = [ + ['drm', '7'], + ['drm-kms', '7'], + ['drm-memory', '7'], + ['drmAvailable', '3'], + ['drmHandleEvent', '3'], + ['drmModeGetResources', '3'], ] - -xmls = [ - ['drm', '7'], ['drm-kms', '7'], ['drm-memory', '7'], ['drmAvailable', '3'], - ['drmHandleEvent', '3'], ['drmModeGetResources', '3'] -] -foreach x : xmls - m = x[0] - s = x[1] +foreach page : rst_pages + name = page[0] + '.' + page[1] + rst = files(name + '.rst') custom_target( - m, - input : files('@0@.xml'.format(m)), - output : '@0@.@1@'.format(m, s), - command : [prog_xslt, '-o', '@OUTPUT@', xsltproc_args, '@INPUT0@'], + name, + input : rst, + output : name, + command : [prog_rst2man, '@INPUT@', '@OUTPUT@'], install : true, - install_dir : join_paths(get_option('mandir'), 'man@0@'.format(s)), - build_by_default : true, - ) -endforeach - -foreach x : ['drm-mm', 'drm-gem', 'drm-ttm'] - gen = custom_target( - 'gen-@0@'.format(x), - input : 'drm-memory.xml', - output : '@0@.xml'.format(x), - command : [ - prog_sed, '-e', 's@^\.so \([a-z_]\+\)\.\([0-9]\)$$@\.so man\2\/\1\.\2@', - '@INPUT@', - ], - capture : true, - ) - custom_target( - '@0@.7'.format(x), - input : gen, - output : '@0@.7'.format(x, '7'), - command : [prog_xslt, '-o', '@OUTPUT@', xsltproc_args, '@INPUT@'], - install : true, - install_dir : join_paths(get_option('mandir'), 'man7'), - build_by_default : true, + install_dir : join_paths(get_option('mandir'), 'man' + page[1]), ) endforeach diff --git a/meson.build b/meson.build index 5cf8e04b..601360b4 100644 --- a/meson.build +++ b/meson.build @@ -261,18 +261,8 @@ else endif with_man_pages = get_option('man-pages') -prog_xslt = find_program('xsltproc', required : with_man_pages == 'true') -prog_sed = find_program('sed', required : with_man_pages == 'true') -manpage_style = 'http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl' -if prog_xslt.found() - if run_command(prog_xslt, '--nonet', manpage_style).returncode() != 0 - if with_man_pages == 'true' - error('Manpage style sheet cannot be found') - endif - with_man_pages = 'false' - endif -endif -with_man_pages = with_man_pages != 'false' and prog_xslt.found() and prog_sed.found() +prog_rst2man = find_program('rst2man', required: with_man_pages == 'true') +with_man_pages = with_man_pages != 'false' and prog_rst2man.found() config.set10('HAVE_VISIBILITY', cc.compiles('''int foo_hidden(void) __attribute__((visibility(("hidden"))));''',