man: convert to reStructuredText

DocBook makes it hard to write and maintain docs. Hopefully
reStructuredText can make this less painful.

The man pages were converted from DocBook to reStructuredText via
Pandoc:

    pandoc -s -f docbook -t rst -o man/drm.7.rst man/drm.xml

And then manual editing to fixup e.g. references to other man pages. To
compare the result with the DocBook version, this command was used:

    rst2man man/drm-kms.7.rst | man -l -

Signed-off-by: Simon Ser <contact@emersion.fr>
Reviewed-by: Eric Engestrom <eric@engestrom.ch>
main
Simon Ser 2020-06-03 11:58:07 +02:00
parent 9a7afcf198
commit 05b0a955d3
No known key found for this signature in database
GPG Key ID: 0FDE7BE0E88F5E48
16 changed files with 858 additions and 1279 deletions

View File

@ -14,7 +14,7 @@
# repository's registry will be used there as well. # repository's registry will be used there as well.
variables: variables:
UPSTREAM_REPO: mesa/drm UPSTREAM_REPO: mesa/drm
DEBIAN_TAG: "2019-11-16" DEBIAN_TAG: "2020-11-15"
DEBIAN_VERSION: buster-slim DEBIAN_VERSION: buster-slim
DEBIAN_IMAGE: "$CI_REGISTRY_IMAGE/debian/$DEBIAN_VERSION:$DEBIAN_TAG" DEBIAN_IMAGE: "$CI_REGISTRY_IMAGE/debian/$DEBIAN_VERSION:$DEBIAN_TAG"
@ -122,10 +122,9 @@ meson-arch-daily:
base-devel base-devel
cairo cairo
cunit cunit
docbook-xsl
libatomic_ops libatomic_ops
libpciaccess libpciaccess
libxslt
meson meson
valgrind valgrind
python-docutils
extends: .meson-build extends: .meson-build

View File

@ -33,7 +33,6 @@ apt-get install -y --no-remove \
libcairo2-dev \ libcairo2-dev \
libcunit1-dev \ libcunit1-dev \
libpciaccess-dev \ libpciaccess-dev \
libxslt1-dev \
meson \ meson \
ninja-build \ ninja-build \
pkg-config \ pkg-config \
@ -41,8 +40,8 @@ apt-get install -y --no-remove \
python3-pip \ python3-pip \
python3-wheel \ python3-wheel \
python3-setuptools \ python3-setuptools \
valgrind \ python3-docutils \
xsltproc valgrind
for arch in ${CROSS_ARCHITECTURES[@]}; do for arch in ${CROSS_ARCHITECTURES[@]}; do
cross_file=/cross_file-$arch.txt cross_file=/cross_file-$arch.txt

229
man/drm-kms.7.rst Normal file
View File

@ -0,0 +1,229 @@
=======
drm-kms
=======
-------------------
Kernel Mode-Setting
-------------------
:Date: September 2012
:Manual section: 7
:Manual group: Direct Rendering Manager
Synopsis
========
``#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
**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)

View File

@ -1,341 +0,0 @@
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<!--
Written 2012 by David Herrmann <dh.herrmann@googlemail.com>
Dedicated to the Public Domain
-->
<refentry id="drm-kms">
<refentryinfo>
<title>Direct Rendering Manager</title>
<productname>libdrm</productname>
<date>September 2012</date>
<authorgroup>
<author>
<contrib>Developer</contrib>
<firstname>David</firstname>
<surname>Herrmann</surname>
<email>dh.herrmann@googlemail.com</email>
</author>
</authorgroup>
</refentryinfo>
<refmeta>
<refentrytitle>drm-kms</refentrytitle>
<manvolnum>7</manvolnum>
</refmeta>
<refnamediv>
<refname>drm-kms</refname>
<refpurpose>Kernel Mode-Setting</refpurpose>
</refnamediv>
<refsynopsisdiv>
<funcsynopsis>
<funcsynopsisinfo>#include &lt;xf86drm.h&gt;</funcsynopsisinfo>
<funcsynopsisinfo>#include &lt;xf86drmMode.h&gt;</funcsynopsisinfo>
</funcsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>Each DRM device provides access to manage which monitors and displays
are currently used and what frames to be displayed. This task is
called <emphasis>Kernel Mode-Setting</emphasis> (KMS). Historically,
this was done in user-space and called
<emphasis>User-space Mode-Setting</emphasis> (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
<citerefentry><refentrytitle>drmModeSettingSupported</refentrytitle><manvolnum>3</manvolnum></citerefentry>
to check whether your driver supports this. To understand how KMS
works, we need to introduce 5 objects: <emphasis>CRTCs</emphasis>,
<emphasis>Planes</emphasis>, <emphasis>Encoders</emphasis>,
<emphasis>Connectors</emphasis> and
<emphasis>Framebuffers</emphasis>.
<variablelist>
<varlistentry>
<term>CRTCs</term>
<listitem>
<para>A <emphasis>CRTC</emphasis> short for
<emphasis>CRT Controller</emphasis> 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
<citerefentry><refentrytitle>drmModeCrtcSet</refentrytitle><manvolnum>3</manvolnum></citerefentry>
to drive the display devices.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Planes</term>
<listitem>
<para>A <emphasis>plane</emphasis> 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).</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Encoders</term>
<listitem>
<para>An <emphasis>encoder</emphasis> 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 <emphasis>cloned</emphasis> display
configuration across the connectors attached to each
encoder.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Connectors</term>
<listitem>
<para>A <emphasis>connector</emphasis> 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, <emphasis>EDID</emphasis> data,
<emphasis>DPMS</emphasis> and
<emphasis>connection status</emphasis>, and information about
modes supported on the attached displays.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Framebuffers</term>
<listitem>
<para><emphasis>Framebuffers</emphasis> 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
<citerefentry><refentrytitle>drm-memory</refentrytitle><manvolnum>7</manvolnum></citerefentry>
API.</para>
</listitem>
</varlistentry>
</variablelist>
</para>
<refsect2>
<title>Mode-Setting</title>
<para>Before mode-setting can be performed, an application needs to call
<citerefentry><refentrytitle>drmSetMaster</refentrytitle><manvolnum>3</manvolnum></citerefentry>
to become <emphasis>DRM-Master</emphasis>. It then has exclusive
access to the KMS API. A call to
<citerefentry><refentrytitle>drmModeGetResources</refentrytitle><manvolnum>3</manvolnum></citerefentry>
returns a list of <emphasis>CRTCs</emphasis>,
<emphasis>Connectors</emphasis>, <emphasis>Encoders</emphasis> and
<emphasis>Planes</emphasis>.</para>
<para>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 <emphasis>Examples</emphasis>
section below for more information.</para>
<para>All valid modes for a connector can be retrieved with a call to
<citerefentry><refentrytitle>drmModeGetConnector</refentrytitle><manvolnum>3</manvolnum></citerefentry>
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.</para>
<para>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
<citerefentry><refentrytitle>drm-memory</refentrytitle><manvolnum>7</manvolnum></citerefentry>.
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
<citerefentry><refentrytitle>drmModeAddFB</refentrytitle><manvolnum>3</manvolnum></citerefentry>
and
<citerefentry><refentrytitle>drmModeAddFB2</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
<para>As a last step, you want to program your CRTC to drive your selected
connector. You can do this with a call to
<citerefentry><refentrytitle>drmModeSetCrtc</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
</refsect2>
<refsect2>
<title>Page-Flipping</title>
<para>A call to
<citerefentry><refentrytitle>drmModeSetCrtc</refentrytitle><manvolnum>3</manvolnum></citerefentry>
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
<citerefentry><refentrytitle>drmModeSetCrtc</refentrytitle><manvolnum>3</manvolnum></citerefentry>
on the next buffer to flip. If you want to synchronize your flips
with <emphasis>vertical-blanks</emphasis>, you can use
<citerefentry><refentrytitle>drmModePageFlip</refentrytitle><manvolnum>3</manvolnum></citerefentry>
which schedules your page-flip for the next
<emphasis>vblank</emphasis>.</para>
</refsect2>
<refsect2>
<title>Planes</title>
<para>Planes are controlled independently from CRTCs. That is, a call to
<citerefentry><refentrytitle>drmModeSetCrtc</refentrytitle><manvolnum>3</manvolnum></citerefentry>
does not affect planes. Instead, you need to call
<citerefentry><refentrytitle>drmModeSetPlane</refentrytitle><manvolnum>3</manvolnum></citerefentry>
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
<citerefentry><refentrytitle>drmModeGetPlaneResources</refentrytitle><manvolnum>3</manvolnum></citerefentry>
for more information.</para>
</refsect2>
<refsect2>
<title>Cursors</title>
<para>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
<citerefentry><refentrytitle>drmModeSetCursor</refentrytitle><manvolnum>3</manvolnum></citerefentry>
and move it on the screen with
<citerefentry><refentrytitle>drmModeMoveCursor</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
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.</para>
</refsect2>
</refsect1>
<refsect1>
<title>Examples</title>
<para>Some examples of how basic mode-setting can be done. See the man-page
of each DRM function for more information.</para>
<refsect2>
<title>CRTC/Encoder Selection</title>
<para>If you retrieved all display configuration information via
<citerefentry><refentrytitle>drmModeGetResources</refentrytitle><manvolnum>3</manvolnum></citerefentry>
as <structname>drmModeRes</structname> *<varname>res</varname>,
selected a connector from the list in
<varname>res</varname>-><structfield>connectors</structfield>
and retrieved the connector-information as
<structname>drmModeConnector</structname> *<varname>conn</varname>
via
<citerefentry><refentrytitle>drmModeGetConnector</refentrytitle><manvolnum>3</manvolnum></citerefentry>
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
<citerefentry><refentrytitle>drmOpen</refentrytitle><manvolnum>3</manvolnum></citerefentry>)
as <varname>fd</varname>, a pointer to the retrieved resources as
<varname>res</varname> and a pointer to the selected connector as
<varname>conn</varname>. It returns an integer smaller than 0 on
failure, otherwise, a valid CRTC id is returned.</para>
<programlisting>
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 &lt; 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 &lt; res->count_crtcs; ++j) {
/* check whether this CRTC works with the encoder */
if (!(enc->possible_crtcs &amp; (1 &lt;&lt; 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;
}
</programlisting>
</refsect2>
</refsect1>
<refsect1>
<title>Reporting Bugs</title>
<para>Bugs in this manual should be reported to
https://gitlab.freedesktop.org/mesa/drm/-/issues</para>
</refsect1>
<refsect1>
<title>See Also</title>
<para>
<citerefentry><refentrytitle>drm</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drm-memory</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drmModeGetResources</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drmModeGetConnector</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drmModeGetEncoder</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drmModeGetCrtc</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drmModeSetCrtc</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drmModeGetFB</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drmModeAddFB</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drmModeAddFB2</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drmModeRmFB</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drmModePageFlip</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drmModeGetPlaneResources</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drmModeGetPlane</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drmModeSetPlane</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drmModeSetCursor</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drmModeMoveCursor</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drmSetMaster</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drmAvailable</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drmCheckModesettingSupported</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drmOpen</refentrytitle><manvolnum>3</manvolnum></citerefentry>
</para>
</refsect1>
</refentry>

322
man/drm-memory.7.rst Normal file
View File

@ -0,0 +1,322 @@
==========
drm-memory
==========
---------------------
DRM Memory Management
---------------------
:Date: September 2012
:Manual section: 7
:Manual group: Direct Rendering Manager
Synopsis
========
``#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 **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)

View File

@ -1,429 +0,0 @@
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<!--
Written 2012 by David Herrmann <dh.herrmann@googlemail.com>
Dedicated to the Public Domain
-->
<refentry id="drm-memory">
<refentryinfo>
<title>Direct Rendering Manager</title>
<productname>libdrm</productname>
<date>September 2012</date>
<authorgroup>
<author>
<contrib>Developer</contrib>
<firstname>David</firstname>
<surname>Herrmann</surname>
<email>dh.herrmann@googlemail.com</email>
</author>
</authorgroup>
</refentryinfo>
<refmeta>
<refentrytitle>drm-memory</refentrytitle>
<manvolnum>7</manvolnum>
</refmeta>
<refnamediv>
<refname>drm-memory</refname>
<refname>drm-mm</refname>
<refname>drm-gem</refname>
<refname>drm-ttm</refname>
<refpurpose>DRM Memory Management</refpurpose>
</refnamediv>
<refsynopsisdiv>
<funcsynopsis>
<funcsynopsisinfo>#include &lt;xf86drm.h&gt;</funcsynopsisinfo>
</funcsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>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.</para>
<para>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.</para>
<refsect2>
<title>Dumb-Buffers</title>
<para>Almost all in-kernel DRM hardware drivers support an API called
<emphasis>Dumb-Buffers</emphasis>. This API allows to create buffers
of arbitrary size that can be used for scanout. These buffers can be
memory mapped via
<citerefentry><refentrytitle>mmap</refentrytitle><manvolnum>2</manvolnum></citerefentry>
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.</para>
<para>The <constant>DRM_IOCTL_MODE_CREATE_DUMB</constant> 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
<citerefentry><refentrytitle>drmModeAddFB</refentrytitle><manvolnum>3</manvolnum></citerefentry>
and use it for mode-setting and scanout. To access the buffer, you
first need to retrieve the offset of the buffer. The
<constant>DRM_IOCTL_MODE_MAP_DUMB</constant> ioctl requests the DRM
subsystem to prepare the buffer for memory-mapping and returns a
fake-offset that can be used with
<citerefentry><refentrytitle>mmap</refentrytitle><manvolnum>2</manvolnum></citerefentry>.</para>
<para>The <constant>DRM_IOCTL_MODE_CREATE_DUMB</constant> ioctl takes as
argument a structure of type
<structname>struct drm_mode_create_dumb</structname>:
<programlisting>
struct drm_mode_create_dumb {
__u32 height;
__u32 width;
__u32 bpp;
__u32 flags;
__u32 handle;
__u32 pitch;
__u64 size;
};
</programlisting>
The fields <structfield>height</structfield>,
<structfield>width</structfield>, <structfield>bpp</structfield> and
<structfield>flags</structfield> have to be provided by the caller.
The other fields are filled by the kernel with the return values.
<structfield>height</structfield> and
<structfield>width</structfield> are the dimensions of the
rectangular buffer that is created. <structfield>bpp</structfield>
is the number of bits-per-pixel and must be a multiple of
<literal>8</literal>. You most commonly want to pass
<literal>32</literal> here. The <structfield>flags</structfield>
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 <structfield>handle</structfield>,
<structfield>pitch</structfield> and <structfield>size</structfield>
fields are filled by the kernel. <structfield>handle</structfield>
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 <structfield>pitch</structfield> field is the
pitch (or stride) of the new buffer. Most drivers use 32bit or 64bit
aligned stride-values. The <structfield>size</structfield> field
contains the absolute size in bytes of the buffer. This can normally
also be computed with
<emphasis>(height * pitch + width) * bpp / 4</emphasis>.</para>
<para>To prepare the buffer for
<citerefentry><refentrytitle>mmap</refentrytitle><manvolnum>2</manvolnum></citerefentry>
you need to use the <constant>DRM_IOCTL_MODE_MAP_DUMB</constant>
ioctl. It takes as argument a structure of type
<structname>struct drm_mode_map_dumb</structname>:
<programlisting>
struct drm_mode_map_dumb {
__u32 handle;
__u32 pad;
__u64 offset;
};
</programlisting>
You need to put the gem-handle that was previously retrieved via
<constant>DRM_IOCTL_MODE_CREATE_DUMB</constant> into the
<structfield>handle</structfield> field. The
<structfield>pad</structfield> field is unused padding and must be
zeroed. After completion, the <structfield>offset</structfield>
field will contain an offset that can be used with
<citerefentry><refentrytitle>mmap</refentrytitle><manvolnum>2</manvolnum></citerefentry>
on the DRM file-descriptor.</para>
<para>If you don't need your dumb-buffer, anymore, you have to destroy it
with <constant>DRM_IOCTL_MODE_DESTROY_DUMB</constant>. If you close
the DRM file-descriptor, all open dumb-buffers are automatically
destroyed. This ioctl takes as argument a structure of type
<structname>struct drm_mode_destroy_dumb</structname>:
<programlisting>
struct drm_mode_destroy_dumb {
__u32 handle;
};
</programlisting>
You only need to put your handle into the
<structfield>handle</structfield> field. After this call, the handle
is invalid and may be reused for new buffers by the dumb-API.</para>
</refsect2>
<refsect2>
<title>TTM</title>
<para><emphasis>TTM</emphasis> stands for
<emphasis>Translation Table Manager</emphasis> 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.</para>
</refsect2>
<refsect2>
<title>GEM</title>
<para><emphasis>GEM</emphasis> stands for
<emphasis>Graphics Execution Manager</emphasis> 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.</para>
<para>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.</para>
<para>All GEM APIs are defined as
<citerefentry><refentrytitle>ioctl</refentrytitle><manvolnum>2</manvolnum></citerefentry>
on the DRM file descriptor. An application must be authorized via
<citerefentry><refentrytitle>drmAuthMagic</refentrytitle><manvolnum>3</manvolnum></citerefentry>
to the current DRM-Master to access the GEM subsystem. A driver that
does not support gem will return <constant>ENODEV</constant> for all
these ioctls. Invalid object handles return
<constant>EINVAL</constant> and invalid object names return
<constant>ENOENT</constant>.</para>
<para>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.</para>
<para>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
<citerefentry><refentrytitle>drm-prime</refentrytitle><manvolnum>7</manvolnum></citerefentry>
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.</para>
<para>Gem-buffers cannot be created with a generic API. Each driver
provides its own API to create gem-buffers. See for example
<constant>DRM_I915_GEM_CREATE</constant>,
<constant>DRM_NOUVEAU_GEM_NEW</constant> or
<constant>DRM_RADEON_GEM_CREATE</constant>. Each of these ioctls
returns a gem-handle that can be passed to different generic ioctls.
The <emphasis>libgbm</emphasis> library from the
<emphasis>mesa3D</emphasis> 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
<citerefentry><refentrytitle>drm-intel</refentrytitle><manvolnum>7</manvolnum></citerefentry>
or
<citerefentry><refentrytitle>drm-radeon</refentrytitle><manvolnum>7</manvolnum></citerefentry>).</para>
<para>Gem-buffers can be closed with the
<constant>DRM_IOCTL_GEM_CLOSE</constant> ioctl. It takes as argument
a structure of type <structname>struct drm_gem_close</structname>:
<programlisting>
struct drm_gem_close {
__u32 handle;
__u32 pad;
};
</programlisting>
The <structfield>handle</structfield> field is the gem-handle to be
closed. The <structfield>pad</structfield> 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.</para>
<para>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
<citerefentry><refentrytitle>drmAuthMagic</refentrytitle><manvolnum>3</manvolnum></citerefentry>
to the current DRM-Master, can <emphasis>guess</emphasis> the name
and open or access the gem-object. If you want more fine-grained
access control, you can use the new
<citerefentry><refentrytitle>drm-prime</refentrytitle><manvolnum>7</manvolnum></citerefentry>
API to retrieve file-descriptors for gem-handles. To create a name
for a gem-handle, you use the
<constant>DRM_IOCTL_GEM_FLINK</constant> ioctl. It takes as argument
a structure of type <structname>struct drm_gem_flink</structname>:
<programlisting>
struct drm_gem_flink {
__u32 handle;
__u32 name;
};
</programlisting>
You have to put your handle into the
<structfield>handle</structfield> field. After completion, the
kernel has put the new unique name into the
<structfield>name</structfield> field. You can now pass this name to
other processes which can then import the name with the
<constant>DRM_IOCTL_GEM_OPEN</constant> ioctl. It takes as argument
a structure of type <structname>struct drm_gem_open</structname>:
<programlisting>
struct drm_gem_open {
__u32 name;
__u32 handle;
__u32 size;
};
</programlisting>
You have to fill in the <structfield>name</structfield> field with
the name of the gem-object that you want to open. The kernel will
fill in the <structfield>handle</structfield> and
<structfield>size</structfield> 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.</para>
<para>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 <emphasis>OpenGL</emphasis>. So if you want to
use more GPU features, you should use the
<emphasis>mesa3D</emphasis> library to create OpenGL contexts on DRM
devices. This does <emphasis>not</emphasis> 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
<citerefentry><refentrytitle>drm-intel</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drm-radeon</refentrytitle><manvolnum>7</manvolnum></citerefentry>
and
<citerefentry><refentrytitle>drm-nouveau</refentrytitle><manvolnum>7</manvolnum></citerefentry>.
However, the
<citerefentry><refentrytitle>drm-prime</refentrytitle><manvolnum>7</manvolnum></citerefentry>
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.</para>
</refsect2>
</refsect1>
<refsect1>
<title>Examples</title>
<para>This section includes examples for basic memory-management
tasks.</para>
<refsect2>
<title>Dumb-Buffers</title>
<para>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
<citerefentry><refentrytitle>drm-kms</refentrytitle><manvolnum>7</manvolnum></citerefentry>).</para>
<programlisting>
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(&amp;creq, 0, sizeof(creq));
creq.width = 1920;
creq.height = 1080;
creq.bpp = 32;
ret = drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &amp;creq);
if (ret &lt; 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, &amp;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(&amp;mreq, 0, sizeof(mreq));
mreq.handle = creq.handle;
ret = drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &amp;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);
</programlisting>
</refsect2>
</refsect1>
<refsect1>
<title>Reporting Bugs</title>
<para>Bugs in this manual should be reported to
https://gitlab.freedesktop.org/mesa/drm/-/issues</para>
</refsect1>
<refsect1>
<title>See Also</title>
<para>
<citerefentry><refentrytitle>drm</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drm-kms</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drm-prime</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drmAvailable</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drmOpen</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drm-intel</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drm-radeon</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drm-nouveau</refentrytitle><manvolnum>7</manvolnum></citerefentry>
</para>
</refsect1>
</refentry>

91
man/drm.7.rst Normal file
View File

@ -0,0 +1,91 @@
===
drm
===
------------------------
Direct Rendering Manager
------------------------
:Date: September 2012
:Manual section: 7
:Manual group: Direct Rendering Manager
Synopsis
========
``#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 **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)

View File

@ -1,136 +0,0 @@
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<!--
Written 2012 by David Herrmann <dh.herrmann@googlemail.com>
Dedicated to the Public Domain
-->
<refentry id="drm">
<refentryinfo>
<title>Direct Rendering Manager</title>
<productname>libdrm</productname>
<date>September 2012</date>
<authorgroup>
<author>
<contrib>Developer</contrib>
<firstname>David</firstname>
<surname>Herrmann</surname>
<email>dh.herrmann@googlemail.com</email>
</author>
</authorgroup>
</refentryinfo>
<refmeta>
<refentrytitle>drm</refentrytitle>
<manvolnum>7</manvolnum>
</refmeta>
<refnamediv>
<refname>drm</refname>
<refpurpose>Direct Rendering Manager</refpurpose>
</refnamediv>
<refsynopsisdiv>
<funcsynopsis>
<funcsynopsisinfo>#include &lt;xf86drm.h&gt;</funcsynopsisinfo>
</funcsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>The <emphasis>Direct Rendering Manager</emphasis> (DRM) is a framework
to manage <emphasis>Graphics Processing Units</emphasis> (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.</para>
<para>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
<citerefentry><refentrytitle>ioctl</refentrytitle><manvolnum>2</manvolnum></citerefentry>
commands on the DRM character device. The <emphasis>libdrm</emphasis>
library provides wrappers for these system-calls and many helpers to
simplify the API.</para>
<para>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
<filename>/dev/dri/card0</filename> and can be accessed with
<citerefentry><refentrytitle>open</refentrytitle><manvolnum>2</manvolnum></citerefentry>
and
<citerefentry><refentrytitle>close</refentrytitle><manvolnum>2</manvolnum></citerefentry>.
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 <literal>EINVAL</literal>.</para>
<refsect2>
<title>Authentication</title>
<para>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
<citerefentry><refentrytitle>drmSetMaster</refentrytitle><manvolnum>3</manvolnum></citerefentry>
for information on how to become DRM-Master and what the limitations
are. Other DRM users can be authenticated to the DRM-Master via
<citerefentry><refentrytitle>drmAuthMagic</refentrytitle><manvolnum>3</manvolnum></citerefentry>
so they can perform buffer allocations and rendering.</para>
</refsect2>
<refsect2>
<title>Mode-Setting</title>
<para>Managing connected monitors and displays and changing the current
modes is called <emphasis>Mode-Setting</emphasis>. 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
<emphasis>Kernel Mode Setting</emphasis> (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
<citerefentry><refentrytitle>drm-kms</refentrytitle><manvolnum>7</manvolnum></citerefentry>
for more.</para>
</refsect2>
<refsect2>
<title>Memory Management</title>
<para>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 <emphasis>Translation Table Manager</emphasis> (TTM) and the
<emphasis>Graphics Execution Manager</emphasis> (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
<emphasis>libgbm</emphasis> (Graphics Buffer Manager) from the
<emphasis>mesa-project</emphasis>. For more information on DRM
memory-management, see
<citerefentry><refentrytitle>drm-memory</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
</refsect2>
</refsect1>
<refsect1>
<title>Reporting Bugs</title>
<para>Bugs in this manual should be reported to
https://gitlab.freedesktop.org/mesa/drm/-/issues</para>
</refsect1>
<refsect1>
<title>See Also</title>
<para>
<citerefentry><refentrytitle>drm-kms</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drm-memory</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drmSetMaster</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drmAuthMagic</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drmAvailable</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drmOpen</refentrytitle><manvolnum>3</manvolnum></citerefentry>
</para>
</refsect1>
</refentry>

41
man/drmAvailable.3.rst Normal file
View File

@ -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 <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
========
**drm**\ (7), **drmOpen**\ (3)

View File

@ -1,74 +0,0 @@
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<!--
Written 2012 by David Herrmann <dh.herrmann@googlemail.com>
Dedicated to the Public Domain
-->
<refentry id="drmAvailable">
<refentryinfo>
<title>Direct Rendering Manager</title>
<productname>libdrm</productname>
<date>September 2012</date>
<authorgroup>
<author>
<contrib>Developer</contrib>
<firstname>David</firstname>
<surname>Herrmann</surname>
<email>dh.herrmann@googlemail.com</email>
</author>
</authorgroup>
</refentryinfo>
<refmeta>
<refentrytitle>drmAvailable</refentrytitle>
<manvolnum>3</manvolnum>
</refmeta>
<refnamediv>
<refname>drmAvailable</refname>
<refpurpose>determine whether a DRM kernel driver has been
loaded</refpurpose>
</refnamediv>
<refsynopsisdiv>
<funcsynopsis>
<funcsynopsisinfo>#include &lt;xf86drm.h&gt;</funcsynopsisinfo>
<funcprototype>
<funcdef>int <function>drmAvailable</function></funcdef>
<paramdef>void</paramdef>
</funcprototype>
</funcsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para><function>drmAvailable</function> allows the caller to determine
whether a kernel DRM driver is loaded.</para>
</refsect1>
<refsect1>
<title>Return Value</title>
<para><function>drmAvailable</function> returns 1 if a DRM driver is
currently loaded. Otherwise 0 is returned.</para>
</refsect1>
<refsect1>
<title>Reporting Bugs</title>
<para>Bugs in this function should be reported to
https://gitlab.freedesktop.org/mesa/drm/-/issues</para>
</refsect1>
<refsect1>
<title>See Also</title>
<para>
<citerefentry><refentrytitle>drm</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drmOpen</refentrytitle><manvolnum>3</manvolnum></citerefentry>
</para>
</refsect1>
</refentry>

62
man/drmHandleEvent.3.rst Normal file
View File

@ -0,0 +1,62 @@
==============
drmHandleEvent
==============
-----------------------------------
read and process pending DRM events
-----------------------------------
:Date: September 2012
:Manual section: 3
:Manual group: Direct Rendering Manager
Synopsis
========
``#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
========
**drm**\ (7), **drm-kms**\ (7), **drmModePageFlip**\ (3),
**drmWaitVBlank**\ (3)

View File

@ -1,101 +0,0 @@
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<!--
Written 2012 by David Herrmann <dh.herrmann@googlemail.com>
Dedicated to the Public Domain
-->
<refentry id="drmHandleEvent">
<refentryinfo>
<title>Direct Rendering Manager</title>
<productname>libdrm</productname>
<date>September 2012</date>
<authorgroup>
<author>
<contrib>Developer</contrib>
<firstname>David</firstname>
<surname>Herrmann</surname>
<email>dh.herrmann@googlemail.com</email>
</author>
</authorgroup>
</refentryinfo>
<refmeta>
<refentrytitle>drmHandleEvent</refentrytitle>
<manvolnum>3</manvolnum>
</refmeta>
<refnamediv>
<refname>drmHandleEvent</refname>
<refpurpose>read and process pending DRM events</refpurpose>
</refnamediv>
<refsynopsisdiv>
<funcsynopsis>
<funcsynopsisinfo>#include &lt;xf86drm.h&gt;</funcsynopsisinfo>
<funcprototype>
<funcdef>int <function>drmHandleEvent</function></funcdef>
<paramdef>int <parameter>fd</parameter></paramdef>
<paramdef>drmEventContextPtr <parameter>evctx</parameter></paramdef>
</funcprototype>
</funcsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para><function>drmHandleEvent</function> processes outstanding DRM events
on the DRM file-descriptor passed as <parameter>fd</parameter>. This
function should be called after the DRM file-descriptor has polled
readable; it will read the events and use the passed-in
<parameter>evctx</parameter> structure to call function pointers
with the parameters noted below:
<programlisting>
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;
</programlisting>
</para>
</refsect1>
<refsect1>
<title>Return Value</title>
<para><function>drmHandleEvent</function> returns <literal>0</literal> on
success, or if there is no data to read from the file-descriptor.
Returns <literal>-1</literal> if the read on the file-descriptor fails
or returns less than a full event record.</para>
</refsect1>
<refsect1>
<title>Reporting Bugs</title>
<para>Bugs in this function should be reported to
https://gitlab.freedesktop.org/mesa/drm/-/issues</para>
</refsect1>
<refsect1>
<title>See Also</title>
<para>
<citerefentry><refentrytitle>drm</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drm-kms</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drmModePageFlip</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drmWaitVBlank</refentrytitle><manvolnum>3</manvolnum></citerefentry>
</para>
</refsect1>
</refentry>

View File

@ -0,0 +1,92 @@
===================
drmModeGetResources
===================
--------------------------------------------------
retrieve current display configuration information
--------------------------------------------------
:Date: September 2012
:Manual section: 3
:Manual group: Direct Rendering Manager
Synopsis
========
``#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
**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)

View File

@ -1,138 +0,0 @@
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<!--
Written 2012 by David Herrmann <dh.herrmann@googlemail.com>
Dedicated to the Public Domain
-->
<refentry id="drmModeGetResources">
<refentryinfo>
<title>Direct Rendering Manager</title>
<productname>libdrm</productname>
<date>September 2012</date>
<authorgroup>
<author>
<contrib>Developer</contrib>
<firstname>David</firstname>
<surname>Herrmann</surname>
<email>dh.herrmann@googlemail.com</email>
</author>
</authorgroup>
</refentryinfo>
<refmeta>
<refentrytitle>drmModeGetResources</refentrytitle>
<manvolnum>3</manvolnum>
</refmeta>
<refnamediv>
<refname>drmModeGetResources</refname>
<refpurpose>retrieve current display configuration information</refpurpose>
</refnamediv>
<refsynopsisdiv>
<funcsynopsis>
<funcsynopsisinfo>#include &lt;xf86drm.h&gt;</funcsynopsisinfo>
<funcsynopsisinfo>#include &lt;xf86drmMode.h&gt;</funcsynopsisinfo>
<funcprototype>
<funcdef>drmModeResPtr <function>drmModeGetResources</function></funcdef>
<paramdef>int <parameter>fd</parameter></paramdef>
</funcprototype>
</funcsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para><function>drmModeGetResources</function> allocates, populates, and
returns a <structname>drmModeRes</structname> structure containing
information about the current display configuration. The structure
contains the following fields:
<programlisting>
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;
</programlisting>
</para>
<para>The <structfield>count_fbs</structfield> and
<structfield>fbs</structfield> fields indicate the number of currently
allocated framebuffer objects (i.e., objects that can be attached to
a given CRTC or sprite for display).</para>
<para>The <structfield>count_crtcs</structfield> and
<structfield>crtcs</structfield> 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).</para>
<para>The <structfield>count_connectors</structfield> and
<structfield>connectors</structfield> 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).</para>
<para>The <structfield>count_encoders</structfield> and
<structfield>encoders</structfield> 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.</para>
<para>The <structfield>min*</structfield> and
<structfield>max*</structfield> fields indicate the maximum size of a
framebuffer for this device (i.e., the scanout size limit).</para>
</refsect1>
<refsect1>
<title>Return Value</title>
<para><function>drmModeGetResources</function> returns a drmModeRes
structure pointer on success, <literal>NULL</literal> on failure. The
returned structure must be freed with
<citerefentry><refentrytitle>drmModeFreeResources</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
</refsect1>
<refsect1>
<title>Reporting Bugs</title>
<para>Bugs in this function should be reported to
https://gitlab.freedesktop.org/mesa/drm/-/issues</para>
</refsect1>
<refsect1>
<title>See Also</title>
<para>
<citerefentry><refentrytitle>drm</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drm-kms</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drmModeGetFB</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drmModeAddFB</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drmModeAddFB2</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drmModeRmFB</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drmModeDirtyFB</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drmModeGetCrtc</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drmModeSetCrtc</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drmModeGetEncoder</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>drmModeGetConnector</refentrytitle><manvolnum>3</manvolnum></citerefentry>
</para>
</refsect1>
</refentry>

View File

@ -18,50 +18,23 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE. # SOFTWARE.
xsltproc_args = [ rst_pages = [
'--stringparam', 'man.authors.section.enabled', '0', ['drm', '7'],
'--stringparam', 'man.copyright.section.enabled', '0', ['drm-kms', '7'],
'--stringparam', 'funcsynopsis.style', 'ansi', ['drm-memory', '7'],
'--stringparam', 'man.output.quietly', '1', ['drmAvailable', '3'],
'--nonet', manpage_style, ['drmHandleEvent', '3'],
['drmModeGetResources', '3'],
] ]
foreach page : rst_pages
xmls = [ name = page[0] + '.' + page[1]
['drm', '7'], ['drm-kms', '7'], ['drm-memory', '7'], ['drmAvailable', '3'], rst = files(name + '.rst')
['drmHandleEvent', '3'], ['drmModeGetResources', '3']
]
foreach x : xmls
m = x[0]
s = x[1]
custom_target( custom_target(
m, name,
input : files('@0@.xml'.format(m)), input : rst,
output : '@0@.@1@'.format(m, s), output : name,
command : [prog_xslt, '-o', '@OUTPUT@', xsltproc_args, '@INPUT0@'], command : [prog_rst2man, '@INPUT@', '@OUTPUT@'],
install : true, install : true,
install_dir : join_paths(get_option('mandir'), 'man@0@'.format(s)), install_dir : join_paths(get_option('mandir'), 'man' + page[1]),
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,
) )
endforeach endforeach

View File

@ -261,18 +261,8 @@ else
endif endif
with_man_pages = get_option('man-pages') with_man_pages = get_option('man-pages')
prog_xslt = find_program('xsltproc', required : with_man_pages == 'true') prog_rst2man = find_program('rst2man', required: with_man_pages == 'true')
prog_sed = find_program('sed', required : with_man_pages == 'true') with_man_pages = with_man_pages != 'false' and prog_rst2man.found()
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()
config.set10('HAVE_VISIBILITY', config.set10('HAVE_VISIBILITY',
cc.compiles('''int foo_hidden(void) __attribute__((visibility(("hidden"))));''', cc.compiles('''int foo_hidden(void) __attribute__((visibility(("hidden"))));''',