githubEdit

Write DRM Engine Driver for Your GPU

Writing a driver of the DRM engine for your GPU.

Table of Contents

Overview

In order to support modern graphics cards or GPUs, we introduced a new NEWGAL engine of drm. Developers can use this engine to run MiniGUI apps on a Linux system on which the DRI (Direct Rendering Infrastructure) is enabled.

The drm engine uses libdrm developed by Free Desktop project:

https://dri.freedesktop.org/wiki/arrow-up-right

Libdrm is a user-space library which implements the Direct Rendering Manager. MiniGUI mainly uses this library to support the dumb frame buffer (no hardware acceleration). However, you can write a driver for your graphics cards or GPUs to implement the hardware accelerated features.

To avoid modifying the MiniGUI source code when supporting a new GPU, the drm engine has adopted a scalable design:

  • You can directly use the drm engine to run MiniGUI on a GPU which supports dumb frame buffer.

  • When you want to take advantage of the hardware acceleration of your GPU, you can write some code for your GPU as a sub driver of drm engine outside MiniGUI.

This document describes how to enable drm engine and write a hardware-accelerating driver for your own GPU.

Note that, generally, the driver will be implemented by the GPU or SoC vendors. The MiniGUI app developers do not need to care about this.

Also note that, we changed the driver interface since MiniGUI 4.0.7. In fact, we changed the interface when developing MiniGUI 5.0.0, and introduced the changes to MiniGUI 4.0.7. Now, no matter which version you use, we will keep the driver interface is consistent for MiniGUI 4.0.7 or later and 5.0.x.

Therefore, this document conforms to both MiniGUI 4.0.7 or later and MiniGUI 5.0.x. We recommend that you upgrade to MiniGUI 4.0.7 or MiniGUI 5.0.0 as soon as possible.

Compile-time Configuration

There is one configure options related to the drm engine:

  • --enable-videodrm enables the drm engine, and --disable-videodrm disables the drm engine. Note that the drm engine is only available on Linux, and you need to install the libdrm 2.4 or later first.

Before version 4.0.4, we use the option --with-targetname=external to enable the external DRM driver; when you configure MiniGUI with this option, MiniGUI will use the external function __drm_ex_driver_get to initialize the DRM driver.

Since 4.0.4, we use dlopen to load the DRM driver. So the above option does not make sense for DRM engine.

Run-time Configuration

For drm engine, we introduced a new section in MiniGUI runtime configuration:

Note that the defaultmode and dpi keys are standard keys for a NEWGAL engine. These two keys define the screen resolution for MiniGUI.

For drm engine, you can use the key drm.device to specify your DRI device. Generally, it is /dev/dri/card0.

You can use the key drm.pixelformat to specify the DRM pixel format of the screen. We use libdrm's fourcc code to defined the pixel format of the screen surface in MiniGUI run-time configuration. For example, XR24 means X8R8G8B8 pixel format (DRM_FORMAT_XRGB8888), and AR24 means A8R8G8B8 pixel format (DRM_FORMAT_ARGB8888).

For more information, please see <drm/drm_fourcc.h> header file. Note that only 8/16/24/32 bits per pixel formats are supported.

You can use the key drm.exdriver to specify the SO name of the shared library, which implements the DRM driver for your GPU and export an external symbol called __drm_ex_driver_get to initialize the DRM driver.

For MiniGUI 5.0.0 or later, you can also use another runtime configuration option drm.double_buffering. This option specifies whether double buffering is enabled. Use true or yes for enabled, anything else for disabled. Note that under compositing schema, double buffering is always enabled.

Implementing a DRM driver

The header file <minigui/exstubs.h> defines the external stubs and the driver operations (a set of callback functions) you need to implement for your GPU externally.

First, you need to implement the following external stub:

This function takes three arguments and returns NULL or a valid pointer of DrmDriverOpsto MiniGUI.

This function can return different DrmDriverOpsto MiniGUI according to the driver name and device file descriptor. In this way, your DRM engine driver implementation can support multiple GPUs.

If the external stub returns NULL, MiniGUI will try to use the dumb frame buffer instead. The arguments of this function have the following meanings:

  • driver_name: This argument gives the driver name determined by MiniGUI. Generally, it is the kernel driver name for your GPU. For example, for Intel i915/i965 GPUs, the driver name will be i915.

  • device_fd: This argument gives the file descriptor of the opened DRI device.

  • version: A pointer to an integer which will be used to return the interface version of the DRM engine driver.

Note that We use the version control since 4.0.7. It will be initialized to zero by MiniGUI before calling this function. Because an old driver for MiniGUI 4.0.6 or earlier will not change the value, MiniGUI will deny to load the old driver.

The constant DRM_DRIVER_VERSION defines the current interface version code. A correctly implemented DRM engine driver should always return this constant value to MiniGUI.

The DrmDriverOps is a structure type consisting of a set of operations (callbacks):

If the external stub __drm_ex_driver_get returns a valid pointer of DrmDriverOps and the version code is matched, MiniGUI will call the operation create_driver to initialize the DRM driver. The operation will return a pointer to the type of DrmDriver. All other operations of DrmDriverOps need this pointer as the context of your DRM driver.

Note that MiniGUI does not define the detailed structure of DrmDriver, it is up to your implementation:

For other operations, please see the comments above.

As an example, we implement a sample DRM driver for i915 graphics chard in mg-tests/drm-engine/. Please refer to mg-tests repository:

https://github.com/VincentWei/mg-tests/tree/master/drm-enginearrow-up-right

DRM Drivers for HybridOS

HybridOSarrow-up-right uses MiniGUI as the underlying windowing system. The HybridOS project maintains the DRM drivers for MiniGUI in the following repo (hiDRMDrivers):

https://github.com/FMSoftCN/hidrmdriversarrow-up-right

By using DRM engines and DRM drivers, MiniGUI and HybridOS now provide the GPU integration via hiMesa and hiCairo:

For the usage and samples, please refer to the chapter Integrating with GPUarrow-up-right in the MiniGUI Programming Guide.

Precautions

Since MiniGUI 4.0.7/5.0.0, the DRM engine provides complete support for the MiniGUI-Processes runtime mode. However, you need to pay attention for the following matter:

The server (mginit) needs the root privilege to call drmSetMaster to act as the master process of Linux DRI. Only after a client was authenticated through the server (mginit), the client can get the rights to allocate buffers from the GPU. Otherwise, the client processes will failed to initialize the hardware accelerated DRM engine driver.

Also note that, only the server (mginit) needs the root privilege.

Known Issues

The following known issues are about hardware cursor of DRM engine (only for MiniGUI 5.0.0):

  • drmSetCursor2 and drmMoveCursor do not work correctly in DRM engine. Libdrm does not provide an interface to set the correct cursor plane, and it seems that X held the cursor plane on my Linux PC.

  • When using a AR24 plane for cursor, drmSetPlane seems having a bad performance.

Future Features

In the near future, the MiniGUI team will:

  • Enhance drm engine to support video plane/overlay.

Last updated