- Yogesh Rao
- May 10, 2022
3D Graphics Driver for Linux: DRM Implementation
Introduction
YouTube undoubtedly is the leading video streaming platform, and with the advent of new technologies from sensor, semiconductors and broadcasting technologies, the quality of video keeps improving manyfold. We all prefer to watch videos in 4K/FHD rather than a 240p. Now, to have the best video streaming experience, your supporting hardware/infrastructure should be capable and advanced. To render this streaming seamlessly, efficient software should be present to interact with the hardware. This calls for the DRM – Direct Rendering Manager.
In this blog, we throw some light on the basics of the Direct Rendering Manager and its purpose and working and the advantages over the conventional Frame Buffer Device driver. We highlight the need for expertise in this area and talk about our opportunity to be involved in developing a driver to take advantage of the DRM subsystem. It provides a lot of scope for us to develop custom solutions and generic implementations along with the capability to take advantage of GPUs (Graphics Programming Unit) to satisfy the display needs.
DRM has been around for quite a while and is predominant in Linux based distributions. In fact, DRM was specifically developed for Linux distributions to take advantage of modern video cards. The job of the DRM is simple – to provide the userspace with an API (Application Programming Interface) which can be used to relay commands and signals to the underlying GPU (Graphics Programming Unit) and perform various operations like aspect ratio control, refresh rate, resolution of the screen, etc. If YouTube is the userspace program, then DRM can be thought of as the software settings which changes the resolution, playback speed, etc. of the video. This knowledge and ability to manipulate the data flow from DRM to GPU has a lot of significance in qualifying multiple userspace programs across multiple multimedia platforms.
Overview of Direct Rendering Manager
Residing in the Kernel space, the DRM was created to manage and allocate GPU resources seamlessly among applications in a sense keeping the user experience hardware agnostic. This is achieved via the core, which allows hardware specific LLDs to register and provide the userspace (application) with IOCtl hooks through which the video rendering can be enhanced and streamed.
The figure above shows the working of the DRM device. The DRM framebuffer is populated with the image frame to be rendered on the display. The CRTC then scans out this framebuffer. If there is more than one plane, then only the state change in the plane is applied and sent to the CRTC. The CRTC then feeds the Encoder which converts the frame to the supported format and sends it out to the connector and finally to the display device.
The DRM involves multiple blocks/modules that are required to be configured while rendering a video.
This can be broadly subdivided into 3 modules each having its specific roles to play:
- DRM Driver
- Connectors
- CRTC
The main goal of the driver is to establish a pipeline which can accommodate for transfer of frames to the display device, map the video buffer / pipelines to the memory and provide the userspace easy handles to implement the application.
The connector module takes care of the connector properties of the display. If the driver is generic, which means that it drives more than 1 display, we store the type of connector associated with each display. We obtain the information about the display through querying for the EDID – Extended Display Identification Data. The relevant information is then passed to the DRM subsystem. It then checks if this type of connector is supported by the hardware and registers it. The connector module also contains the additional helper functions which take care of functionality in case the connector is busy, unplugged, etc.
The crtc module takes care of registering the encoders and implements the functionality which flushes or updates the display with the frames. Planes are obtained and support for more than one plane can be enabled, which is then updated with the new state. The crtc and the encoder pipelines perform the state checks and updates. There are helper callback functions which can be filled with custom functions which update the display with the new plane state. These can in turn be substituted with inbuilt helper functions by the DRM which initialises a complete display pipeline with basic functionality. This can then be customised to send the frames to the type of display being driven.
Once the DRM driver is registered and the successful probing occurs, the DRM subsystem creates a filesystem node on /dev/dri/cardX which is then used as a file that can be opened, read from or written to. This is where the libdrm comes into picture. Libdrm is an API provided to the userspace to implement the applications which can interact with the DRM drivers present in the kernel space. A simple application can be written which lists the connectors, encoders and crtcs used and then writes a simple frame to the card (on the FS). Default applications called modeset and modetest utilities can be used for the same.
The difference between DRM and FBDev
The FBDev or the Linux Framebuffer Device is a subsystem in Linux to show the graphics on a display device. It was developed to be a hardware independent driver to provide the userspace with software access to the framebuffer (or the memory containing the video) using very basic facilities. Though this subsystem remains relevant, its use has mostly been superseded by the DRM. The main differences can be summarised as follows:
In addition to the above differences, the framebuffer device is not apt for hardware accelerated support nor 3D graphics, both of which are the focus of the DRM. This has pushed the DRM subsystem to be the primary development tool for the Linux Kernel over Framebuffer Device. The DRM has broader applications, opensource tools (like OpenGL) and a wide range of Mode Settings (KMS) over the framebuffer Device.
Conclusion
To summarise in layman’s terms, the role of DRM (Direct Rendering Manager) is to provide a means for the userspace program to control the modes of a display device. Screen resolution, colour depth, refresh rate etc. at which the display operates is referred to as modes. The rapid progress of technology, which is evident in the picture below (shows that the transition from CRT to HD took almost 10 years and from 4k to 8k, it took just 3 years) throws up many different challenges. One such challenge is how to make sure that userspace programs are kept in sync with changing technology landscape, where even the number userspace programs have increased multi-fold.
Although the DRM is a great tool to handle graphics on Linux, the usage of KMS and memory management is not easy or straightforward. It takes thorough understanding of the vast DRM subsystem and its API to have an optimized implementation. Ignitarium has been working in the Multimedia space for over a decade, both on the frameworks and on the driver implementations and we thrive to create end to end solutions for our customers, which are optimized for the underlying hardware of choice.
These end-to-end solutions can be for the implementation of a DRM driver – from a hardware specific display driver to a generic custom display driver. We would also involve in the process of rigorous testing and application driven userspace programs to help use the Driver for the suitable purpose. Since DRM is open source, it has a wide range of applications. We hope to make the best of this range to be able to cater to the needs of the consumer.