我们在开发rk3399的时候,我们可以知道,mesa正在实现panfrost来做rk3399的mali T860显卡的开源方案,并且arm公司也给每个芯片方案厂商提供了闭源的libmali方案。现在时间来到了rk3588作为主流芯片的时代,我们可以借鉴之前的内容,实现两套显卡驱动互相切换的功能,做到操作系统中,从而更好的使得客户使用操作系统。
rk3588的两个方案分别为
mesa panfrost libmali legacy
为了让linux平台支持panfrost版本,我们需要更新和升级mesa库,根据参考信息和社区的一些行为,我们需要升级到mesa到23版本及以上
https://gitlab.freedesktop.org/mesa/mesa/-/tree/main/src/panfrost
于是,我们可以从如下源获取mesa-23
https://dev.kylinos.cn/~rk3588/+archive/kylin-desktop/common
我构建的版本号为:1:23.0.5-0kylin1panforkrk1 如下:
注意,mesa依赖llvm-14,我们需要同时更新系统的llvm到14,如下
对于已经安装的系统,我们需要替换如下包:
此时,我们通过glmark2测试,可以看到是基于panfrost的opengl方案,如下
同样的,glmark2-es2也能看到是基于panfrost的opengl es方案,如下
如果我们需要使得系统支持libmali legacy的方案,我们需要更新显卡驱动为libmali.so,并且更换xorg为rk修改和定制的xorg
对于libmali,我们需要更新版本如下:
https://dev.kylinos.cn/~rk3588/+archive/kylin-desktop/common/+packages
对于xorg,我们需要更新版本如下:
https://dev.kylinos.cn/~rk3588/+archive/kylin-desktop/x11/+index?batch=50&memo=50&start=50
此时我建议更新的具体包如下:
至此,我们的系统可以默认支持legacy mali方案,此时我们可用glmark2-es2测试,如下:
但是此时,我们无法通过glmark2测试
根据上面的信息,我们已经具备能力将显卡方案选择任意一种,但是没有具备一个能力让应用程序运行时自动选择任意一种显卡方案进行渲染和显示。
故我们的目标是将其两种方案的融合,其主要思路如下
开机默认使用mesa的panfrost方案显卡 用户可以通过环境变量的方式使用libmali legacy方案 在上述思路完成的情况下,我们还需要使得libmali legacy的方案支持opengl。我们还需要
通过gl4es库转换opengl es的实现到opengl上
根据上述我们可以知道,我们已经更新mesa到panfrost了,但是panfrost需要加载mali_csffw.bin,所以我们需要一个加载mali_csffw.bin的包, 如下
这个包可以自动根据mali的版本选择固件mali_csffw.bin,所以我们可以看到如下:
至此,下次加载显卡过程中,会主动读取/usr/lib/firmware/mali_csffw.bin的文件内容,将显卡固件通过驱动加载到显卡中。然后我们的显卡便可以正常工作了。
根据上面我们可以知道,我们如果使用libmali和rk修改的xorg,我们可以让系统默认通过legacy启动显卡,但是如果我们需要实施动态选择显卡的方案,我们xorg不能使用rk定制的,而libmali不需要添加到ld.conf中,所以我们首先需要拿到libmali的代码,如下:
https://github.com/JeffyCN/mirrors/tree/libmali
然后我们需要修改libmali的默认ldconfig的行为,如下补丁
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(
此时,编译出来的libmali将不包含00-aarch64-mali.conf。
我们知道,如果我们使用legacy的mali,那么opengl的程序将无法运行,此时我们需要通过libgl4es库使其支持此功能,gl4es库地址如下:
https://github.com/ptitSeb/gl4es.git
我们需要找到其稳定的tag,这里以1.1.6为例,如下
https://github.com/ptitSeb/gl4es/tree/v1.1.6
对于此包,其默认包含debian文件,故我们可以直接编译和生成包,地址如下
我们可以知道libgl4es包的内容如下
如果我们通过ld library path配置了gl4es,则默认可以将opengl的内容翻译成opengles渲染,如下
export LD_LIBRARY_PATH+=/usr/lib/gl4es/
至此,我们可以将legacy mali上不支持opengl的应用的问题解决
我们通过解析libmali.so的string,我们可以知道其默认只支持dri2,如下
而对于现在的操作系统,默认启用dri3,我们需要为这个场景下的将dri2 转换到dri3,从而让支持dri3的应用正常通过libmali legacy执行渲染。
对于此,我们需要仓库如下:
https://github.com/hbiyik/dri2to3
这个仓库我们需要自行生成和编写debian配置,从而形成软件包
此仓库编译出来后,我们需要用ld preload加载,如下
export LD_PRELOAD=/usr/lib/aarch64-linux-gnu/libdri2to3.so
对于上述的功能,我们需要提供一个加载器的deb包,加载器的仓库如下:
https://gitlab2.kylin.com/shanghai-team/3588/rkmali-loader
我们需要实现一个加载脚本rkmali,其代码如下:
#!/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 "$@"
故,我们提供rkmali的deb包,其内容如下
至此我们可以通过加载器让应用程序使用legacy mali,方法如下:
根据上面的描述,我们可以动态的选择显卡渲染方式(通过mesa或libmali),这里提供一个测试脚本如下:
#!/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
此脚本24小时运行正常即可。