RK3588 Graphics Switching Solution

During the development of RK3399, we learned that Mesa was implementing Panfrost to provide an open-source solution for the Mali T860 graphics card, and ARM also provided a closed-source libmali solution to each chip solution vendor. Now, as we enter the era of RK3588 as a mainstream chip, we can leverage previous content to implement a feature that allows switching between two graphics drivers within the operating system, thereby enhancing the user experience.

1. Introduction

The two solutions for RK3588 are as follows:

mesa: panfrost
libmali: legacy

1.1 Panfrost

To support the Panfrost version on the Linux platform, we need to update and upgrade the Mesa library. Based on reference information and community activities, we need to upgrade Mesa to version 23 or higher.

https://gitlab.freedesktop.org/mesa/mesa/-/tree/main/src/panfrost

Thus, we can obtain Mesa-23 from the following source:

https://dev.kylinos.cn/~rk3588/+archive/kylin-desktop/common

The version I built is: 1:23.0.5-0kylin1~panfork~rk1 as shown below:

RK3588 Graphics Switching Solution

Note that Mesa depends on LLVM-14, so we also need to update the system’s LLVM to version 14 as follows:

RK3588 Graphics Switching Solution

For systems that are already installed, we need to replace the following packages:

RK3588 Graphics Switching Solution

At this point, we can see from the glmark2 test that it is based on the Panfrost OpenGL solution, as shown below:RK3588 Graphics Switching Solution

Similarly, glmark2-es2 can also see that it is based on the Panfrost OpenGL ES solution, as shown below:RK3588 Graphics Switching Solution

1.2 Libmali Legacy

If we need the system to support the libmali legacy solution, we need to update the graphics driver to libmali.so and replace Xorg with the RK-modified and customized Xorg.

For libmali, we need to update the version as follows:

RK3588 Graphics Switching Solution

For Xorg, we need to update the version as follows:

RK3588 Graphics Switching Solution

The specific packages I recommend updating are as follows:

RK3588 Graphics Switching Solution

RK3588 Graphics Switching SolutionRK3588 Graphics Switching Solution

At this point, our system can default to support the legacy Mali solution. We can test it using glmark2-es2 as follows:

RK3588 Graphics Switching Solution

However, at this point, we cannot pass the glmark2 test:RK3588 Graphics Switching Solution

2. Implementation Plan

Based on the information above, we now have the capability to choose either graphics solution, but we lack the ability to allow applications to automatically select either graphics solution for rendering and display during runtime.

Therefore, our goal is to integrate the two solutions, with the main idea as follows:

Boot with the default Mesa Panfrost graphics solution.Users can use the libmali legacy solution through environment variables.Once the above idea is completed, we also need to ensure that the libmali legacy solution supports OpenGL. We also need to:

Use the gl4es library to convert OpenGL ES implementations to OpenGL.

2.1 Boot Default Mesa Panfrost

As we know, we have updated Mesa to Panfrost, but Panfrost requires loading mali_csffw.bin, so we need a way to load mali_csffw.bin.

This package can automatically select the firmware mali_csffw.bin based on the Mali version, so we can see the following:

RK3588 Graphics Switching Solution

At this point, during the next graphics card loading process, it will actively read the contents of the file /usr/lib/firmware/mali_csffw.bin, loading the graphics card firmware through the driver. Then our graphics card can function normally.

2.2 Setting Legacy Mali via Environment Variables

2.2.1 Compiling Libmali

As we know, if we use libmali and the RK-modified Xorg, we can set the system to default to start the graphics card through legacy. However, if we need to implement a dynamic graphics card selection scheme, we cannot use the RK-customized Xorg, and libmali does not need to be added to ld.conf. Therefore, we first need to obtain the libmali code as follows:

https://github.com/JeffyCN/mirrors/tree/libmali

Then we need to modify the default ldconfig behavior of libmali as follows:

diff --git a/meson.build b/meson.build
index 9add735..89c5366 100644
--- a/meson.build
+++ b/meson.build
@@ -345,7 +345,7 @@ if vendor_package
     command : ['echo', get_option('prefix') / wrapper_libdir],
     capture : true,
     install_dir : '/etc/ld.so.conf.d',
-    install : true)
+    install : false)
 elif get_option('khr-header')
   # Install optional KHR header
   install_data(

At this point, the compiled libmali will not include 00-aarch64-mali.conf.

2.2.2 Compiling Gl4es

We know that if we use the legacy Mali, OpenGL programs will not run. Therefore, we need to use the libgl4es library to support this functionality. The gl4es library can be found at:

https://github.com/ptitSeb/gl4es.git

We need to find its stable tag; here we take 1.1.6 as an example:

https://github.com/ptitSeb/gl4es/tree/v1.1.6

This package includes Debian files by default, so we can directly compile and generate the package. The address is as follows:

RK3588 Graphics Switching Solution

The contents of libgl4es are as follows:RK3588 Graphics Switching Solution

If we configure gl4es through LD_LIBRARY_PATH, it can translate OpenGL content into OpenGLES rendering by default, as follows:

export LD_LIBRARY_PATH+=/usr/lib/gl4es/

At this point, we can solve the issue of applications that do not support OpenGL on legacy Mali.

2.2.3 DRI2 to DRI3

By analyzing the string of libmali.so, we can see that it only supports DRI2 by default, as shown below:

RK3588 Graphics Switching Solution

For current operating systems, DRI3 is enabled by default. We need to convert DRI2 to DRI3 for this scenario, allowing applications that support DRI3 to execute rendering through libmali legacy.

For this, we need the following repository:

https://github.com/hbiyik/dri2to3

This repository requires us to generate and write Debian configurations to form a software package.

After compiling this repository, we need to load it using LD_PRELOAD as follows:

export LD_PRELOAD=/usr/lib/aarch64-linux-gnu/libdri2to3.so

2.2.4 Graphics Card Loader

For the above functionality, we need to provide a loader deb package. The repository for the loader is as follows:

https://gitlab2.kylin.com/shanghai-team/3588/rkmali-loader

We need to implement a loading script called rkmali, with the following code:

#!/bin/bash
export LD_PRELOAD=/usr/lib/aarch64-linux-gnu/libdri2to3.so
export LD_LIBRARY_PATH=/usr/lib/aarch64-linux-gnu/mali:/usr/lib/gl4es/
exec "$@"

Thus, we provide the rkmali deb package, which contains the following:

RK3588 Graphics Switching Solution

At this point, we can use the loader to allow applications to utilize legacy Mali, as follows:

RK3588 Graphics Switching Solution

RK3588 Graphics Switching Solution

3. Testing and Verification

Based on the above description, we can dynamically select the graphics rendering method (via Mesa or libmali). Here is a test script:

#!/bin/bash

while((1))
do
        # test mesa panfrost OpenGL
        glmark2

        sleep 1

        # test mesa panfrost OpenGLES
        glmark2-es2

        sleep 1

        # test rkmali OpenGLES
        rkmali glmark2-es2

        sleep 1

        # test rkmali OpenGL wrapper (gl4es)
        rkmali glmark2

        sleep 1

        # test mesa es2gears
        es2gears

        sleep 1

        # test rkmali es2gears
        rkmali es2gears

        sleep 1

done > rkmali-loader-test-$(date "+%F").log

This script should run normally 24/7.

# Building a World-Class Operating System

For more articles, please follow the public account: Kylin Embedded

Leave a Comment