Rockchip RK3399 - Mali-T860 GPU驱动(mesa+Panfrost)
----------------------------------------------------------------------------------------------------------------------------
开发板 :NanoPC-T4开发板
eMMC :16GB
LPDDR3 :4GB
显示屏 :15.6英寸HDMI接口显示屏
u-boot :uboot 2023.04
linux :6.3、5.2.8
----------------------------------------------------------------------------------------------------------------------------
需要注意的是:本篇博客是以linux 6.3版本为主体介绍的,但是内容同样适用于linux 5.2.8版本。
一、图像界面卡顿问题
在前面的文章我们已经移植了在NanoPC-T4开发板上移植了uboot 2023.04、linux 6.3、以及ubuntu 20.04.4根文件系统。然后在使用ubuntu桌面环境的时候,发现了一个问题,在firefox随便打开一个网页,视频都加载很慢,同时看到CPU的占用率会急剧升高;

1.1 图像卡顿原因
造成这种情况一般由两个原因:
- 开发板上主控
SoC的性能比较弱,没有带3D图形加速(即GPU)功能; - 开发板上的
SoC带了GPU,但是没有用起来;
第一个原因基本是无解的,如果你选的SoC上面没有带GPU,唯一的办法就是尽量去跑轻量级的图形界面,如果想跑debian、ubuntu这种发行版上默认搭配的GNOME或者KDE,这种没有GPU支持,所有的图像合成渲染都要通过CPU来运算,是很难跑流畅的。所以如果你对图形显示功能比较看重,在选开发板的时候一定要查阅与之搭配的主控SoC是否带有GPU。
也有很多人被卡在了第二个关卡,SoC上搭配了强劲的GPU、比如RK3399,S912,他们都搭载了ARM Mali GPU,但是mainline内核(指的是主线linux内核)却缺少相应的驱动支持,GPU驱动一般分为两部分:
- 一小部分在
linux内核中; - 另外一大部分在
Userspace,在Userspace的部分向下操作内核中的驱动,向上对应用层提供标准的API接口,例如:OpenGL ES 1.1、2.0、3.0、3.1、3.2;OpenCL 1.1、1.2、2.0;Vulkan 1.0;RenderScript(受支持的API列表因二进制和GPU类型而异)。
1.2 ARM Mail GPU
Mali GPU IP提供商ARM公司只开放了内核部分驱动,而且这部分驱动还没有按照linux kernel的规范以DRM的框架去实现,所以它无法被linux mainline接受,还有一个更重要的部分,Userspace部分ARM没有开源,只是以库的形式提供给购买了Mali GPU授权的SoC厂商,比如Rockchip,Amlogic。而且这套代码主要是为Android系统设计的,对debian、ubuntu这种系统的兼容性也不好。
看到这里,也许你就想骂ARM了,其实也不能完全怪他们,因为这并不是ARM独创的玩法,其他的GPU供应商也都这样玩,比如Nvidia、Vivante、Imagination。大神Linus为这事还对Nvidia竖过中指呢,怒吼:“Nvidia,F*K you!”。
面对这种状况,很多人为了能够利用GPU加速,就只能使用SoC原厂提供的内核,和他们定制的系统,这种内核和系统一般都比较老。
如果想跑mainline的内核,基本就没法使用GPU加速了,这也是为什么我们目前看到的大部分开发板如果搭载了mainline内核,基本都不会有GPU加速功能,或者直接就不开图形显示功能。
但是也有一部分黑客们不满于这种封锁,他们勇于探索,积极尝试,逆向了ARM发布的二进制库,然后重写了针对ARM Mali GPU的开源驱动,最终在Linux 5.2发布的时候合并到mainline中:
- 针对
Mali-400/Mali-450的驱动叫做Lima,针对Mali-T6xx / Mali-T7xx / Mali-T8xx GPU和GXX系列的叫做Panfrost; Usersacpe部分的开源库叫做mesa,对Mali GPU的支持从mesa 19.2开始,这个我们在介绍OpenGL的实现的时候已经提及到了;
这里我们将学习如何在运行linux kernel 6.3的RK3399开发板上开启GPU加速:RK3399集成了Mali-T860 GPU,所以我们可以利用linux kernel的Panfrost驱动 + Userspace的mesa来解锁3D图形加速功能。
1.2.1 Panfrost
Panfrost驱动程序栈包括基于Midgard和Bifrost微架构的ARM Mali GPU的OpenGL ES实现,目前支持以下硬件:
| Product | Architecture | OpenGL ES | OpenGL |
|---|---|---|---|
| Mali T620 | Midgard (v4) | 2.0 | 2.1 |
| Mali T720 | Midgard (v4) | 2.0 | 2.1 |
| Mali T760 | Midgard (v5) | 3.1 | 3.1 |
| Mali T820 | Midgard (v5) | 3.1 | 3.1 |
| Mali T830 | Midgard (v5) | 3.1 | 3.1 |
| Mali T860 | Midgard (v5) | 3.1 | 3.1 |
| Mali T880 | Midgard (v5) | 3.1 | 3.1 |
| Mali G72 | Bifrost (v6) | 3.1 | 3.1 |
| Mali G31 | Bifrost (v7) | 3.1 | 3.1 |
| Mali G51 | Bifrost (v7) | 3.1 | 3.1 |
| Mali G52 | Bifrost (v7) | 3.1 | 3.1 |
| Mali G76 | Bifrost (v7) | 3.1 | 3.1 |
| Mali G57 | Valhall (v9) | 3.1 | 3.1 |
目前,Panfrost驱动程序还不支持其它基于Midgard和Bifrost架构的芯片(如T604、G71)。
对于基于Utgard架构的旧款Mali芯片(如Mali 400、Mali 450),可以在Lima驱动程序中找到支持。Lima驱动程序也可在mesa中使用。
另外,当前版本的Panfrost驱动程序不支持其它图形API(如Vulkan、OpenCL)。
在支持OpenGL的过程中,Panfrost驱动程序需要实现以下功能:
OpenGL指令解析和翻译:Panfrost驱动程序需要解析应用程序发送的OpenGL指令,并将其翻译成适用于Mali GPU的底层指令,这包括顶点处理、片段处理、纹理映射、着色器处理等;OpenGL状态管理: 驱动程序需要管理OpenGL中的状态机,确保正确地跟踪和应用OpenGL中的状态变化,以便正确地渲染图形;OpenGL内存管理: 驱动程序需要管理GPU内存,确保OpenGL中的图形数据被正确地加载到GPU内存中,并在需要时被释放;OpenGL渲染管线控制: 驱动程序需要控制GPU的渲染管线,确保正确地处理顶点数据、执行着色器程序、进行光栅化等操作;OpenGL版本兼容性: 驱动程序需要确保对OpenGL标准的不同版本提供兼容性支持,以便能够正确地处理来自应用程序的不同版本的OpenGL指令。
注意:以上内容来自https://docs.mesa3d.org/drivers/panfrost.html。
1.2.2 mesa
mesa 也称为mesa3D和mesa 3D图形库,是OpenGL、Vulkan和其他图形API规范的开源实现。 mesa将这些API规范转换为特定于供应商的图形硬件驱动程序。
mesa项目最初是作为OpenGL规范的开源实现而开始。经过多年来发展,具有跨平台支持、高性能、开源和扩展性等特点,并且该项目已经扩展到实现更多的图形API, 包括OpenGL ES、OpenCL、OpenMAX、VDPAU、VA-API、Vulkan和EGL。
1.2.3 架构图
总的来说,Panfrost驱动程序通过mesa 3D图形库来实现对OpenGL标准的支持,它需要解析、翻译和执行来自应用程序的OpenGL指令,并管理GPU的状态、内存和渲染管线,以实现对OpenGL的兼容性支持,整体架构图大致如下;

上图中:
/dev/dri/renderD128:代表了显卡的渲染节点。这个节点通常用于渲染加速,比如OpenGL和Vulkan,以及视频编解码等任务;libpanfrost_dri.so:Panfrost GPU驱动的Direct Rendering Infrastructure(DRI)库,用于与Panfrost驱动程序交互,管理GPU资源、执行图形渲染和处理命令等;libgallium_dri.so:提供了通用的Direct Rendering Infrastructure(DRI)支持,实现了对不同图形硬件的支持;libEGL.so:EGL动态库,提供了EGL API的实现,用在OpenGL ES、OpenGL、Vulkan等图形API与底层本地平台窗口系统之间建立连接;libGLESv1_CM.so、libGLESv2.so:OpenGL ES动态库,OpenGL ES是一种用于嵌入式系统(如手机、平板电脑)的图形API,它是OpenGL的子集,优化了性能和内存使用;libgbm.so:是Generic Buffer Manager的库文件,它用于管理系统中缓冲区对象的内存管理和分配,通常用于Wayland或Direct Rendering Infrastructure(DRI)等环境中,用于分配图形缓冲区并进行图像呈现;libglapi.so:这是一个共享GLAPI库,用于提供OpenGL API调用的间接层;
此外可能还有:
libGL.so:这是传统的OpenGL库,提供了OpenGL API的实现。它用于支持全功能的OpenGL(不是OpenGL ES),通常用于桌面和工作站级图形应用程序;libOpenGL.so:这是新的OpenGL库,它与libGL.so类似,但遵循了新的GLVND(OpenGL Vendor Neutral Dispatch)架构,GLVND旨在提供更好的供应商中立性,使得可以在同一个系统上安装多个OpenGL驱动而不会相互冲突;libMesaOpenCL.so:mesa gallium clover OpenCL ICD驱动程序实现库(OpenCL开源实现);libRusticlOpenCL.so:mesa gallium rusticl OpenCL ICD驱动程序实现库(OpenCL开源实现);libOpenCL.so:OpenCL ICD Loader库;
二、图形API
既然上面提到了OpenGL,那么就来简单了解一下计算机图形程序接口,计算机图像程序接口包括OpenGL、OpenGLES、OpenCL、Vulkan等。
2.1 OpenGL
2.1.1 OpenGL简介
OpenGL(全写Open Graphics Library)是一套开放的图形编程接口规范。它定义了一系列函数、常量和数据类型,用于渲染2D和3D图形,并提供了与图形硬件交互的方法。
OpenGL规范由Khronos Group组织制定和维护,它是跨平台的,可以在不同的操作系统(如windows、linux、macOS等)和硬件上使用。
通过遵循OpenGL规范,开发人员可以编写跨平台的图形应用程序,而不必关心底层图形硬件的差异。不同的GPU供应商可以实现自己的OpenGL驱动程序来支持该规范,并提供硬件加速的图形渲染功能。开发人员可以使用OpenGL接口调用这些功能,从而实现高性能的图形渲染和可视化效果。
EGL 是一个依赖于平台的API,是OpenGL ES和本地窗口系统之间的一个中间接口层,它主要根据具体系统实现。
2.1.2 OpenGL ES简介
OpenGL ES (OpenGL for Embedded Systems) 是免授权费的,跨平台的,功能完善的2D和3D图形应用程序接口API,是一种用于嵌入式系统(如手机、平板电脑)的图形API,它是OpenGL的子集,优化了性能和内存使用。
2.1.3 WebGL简介
WebGL(Web Graphics Library)是一种3D绘图协议,这种绘图技术标准允许把JavaScript和OpenGL ES 2.0结合在一起,通过增加OpenGL ES 2.0的一个JavaScript绑定,WebGL可以为HTML5 Canvas提供硬件3D加速渲染,这样Web开发人员就可以借助系统显卡来在浏览器里更流畅地展示3D场景和模型了,还能创建复杂的导航和数据视觉化。显然,WebGL技术标准免去了开发网页专用渲染插件的麻烦,可被用于创建具有复杂3D结构的网站页面,甚至可以用来设计3D网页游戏等等。
WebGL完美地解决了现有的Web交互式三维动画的两个问题:
- 它通过
HTML脚本本身实现Web交互式三维动画的制作,无需任何浏览器插件支持; - 它利用底层的图形硬件加速功能进行的图形渲染,是通过统一的、标准的、跨平台的
OpenGL接口实现的。
WebGL标准已出现在Mozilla Firefox、Apple Safari及开发者预览版Google Chrome等浏览器中,这项技术支持Web开发人员借助系统显示芯片在浏览器中展示各种3D模型和场景,未来有望推出3D网页游戏及复杂3D结构的网站页面。
2.1.4 OpenGL实现
Khronos Group本身并没有实现一套自己的OpenGL。Khronos Group是一个由多家硬件和软件公司组成的行业联盟,旨在制定和推动开放的标准和规范。他们负责维护和发展OpenGL规范,但具体的实现是由各个GPU供应商自行开发。
不同的GPU供应商(如NVidia、AMD、Intel等)根据OpenGL规范来实现自己的OpenGL驱动程序。这些驱动程序会与具体的硬件架构和操作系统进行交互,以提供对OpenGL功能的支持和硬件加速。因此,每个GPU供应商实现的OpenGL驱动程序可能会有一些差异,但它们都遵循了OpenGL规范,以确保兼容性和可移植性。
以下是一些常见的OpenGL实现:
Microsoft Windows上的OpenGL实现:windows操作系统通常使用由各个显卡供应商提供的OpenGL实现。例如,NVIDIA提供了针对其显卡的OpenGL驱动程序,而AMD和Intel也提供了相应的驱动程序;macOS上的OpenGL实现:macOS使用苹果自己的OpenGL实现,称为Apple OpenGL或macOS OpenGL。这是基于OpenGL规范的实现,与苹果的硬件和操作系统紧密集成;Linux上的OpenGL实现:Linux上有多个供应商提供的OpenGL实现,包括开源的mesa 3D项目。mesa提供了一个开源的OpenGL实现,可以在许多Linux发行版上使用。此外,显卡供应商如NVIDIA、AMD和Intel也提供了针对Linux的专有OpenGL驱动程序;- 移动平台上的
OpenGL ES实现:OpenGL ES(OpenGL for Embedded Systems)是针对移动设备和嵌入式系统的精简版OpenGL。针对Android设备,Google提供了OpenGL ES的实现,而对于iOS设备,苹果提供了Metal API,它可以用于绘制2D和3D图形。
2.2 OpenCL
OpenCL(Open Computing Language开放计算语言)是一种开放的、免版税的标准,用于超级计算机、云服务器、个人计算机、移动设备和嵌入式平台中各种加速器的跨平台并行编程。
OpenCL是由Khronos Group创建和管理的。OpenCL使应用程序能够使用系统或设备中的并行处理能力,从而使应用程序运行得更快、更流畅。
2.2.1 平台&设备
一个OpenCL平台通常对应一个供应商。它负责为其设备提供OpenCL实现。例如,具有i7-4790 intel cpu的机器将会有一个OpenCL平台,大概命名为intel opencl,该平台将包括两个OpenCL设备:一个是intel cpu本身,另一个是intel hd graphics 4600 GPU。这个intel opencl平台正在为这两个设备提供OpenCL实现,并负责管理它们。
OpenCL平台可以有一个或多个设备;- 相同的设备可以具有来自不同供应商的一个或多个
OpenCL实现。换句话说,OpenCL设备不仅可以属于一个平台。; - 该平台的
OpenCL版本不一定与设备的OpenCL版本相同;
2.2.2 ICD&ICD Loader
OpenCL Installable Client Driver (ICD),它是针对某个特定设备的专门的OpenCL实现,也就是OpenCL运行时,可以在libIntelOpenCL.so、libnvidia-opencl.so、libMesaOpenCL.so这样的文件中找到它。
从OpenCL 1.2开始,OpenCL提供了一个ICD扩展(cl_khr_icd),它允许不同厂商的多个OpenCL驱动共存于一个主机系统。
OpenCL Installable Client Driver (ICD) Loader是实现OpenCL应用程序与各硬件厂商提供的OpenCL驱动之间隔离的中间库;
- 它与
OpenCL应用程序相关联,并作为ICD的占位符; - 应用程序调用
ICD加载程序库导出的函数。然而,ICD加载器根据所选的OpenCL平台决定要重定向到哪个ICD; ICD加载机制是必需的,因为供应商的OpenCL实现通常只支持该供应商的硬件,但您可能希望在同一个OpenCL应用程序中使用来自不同供应商的多个设备。
OpenCL ICD Loader实现了ICD扩展并提供了所有OpenCL API接口,OpenCL ICD Loader允许应用程序调用clIcdGetPlatformIDsKHR函数已经安装的OpenCL驱动中选择使用一个平台,应用程序的所有OpenCL API请求将被转发到指定的平台。
简单的说,这个OpenCL ICD Loader Library只是个二传手,它提供了所有OpenCL API的接口,但没有提供实现,所有通过Loader Library调用的OpenCL API请求都会被传递到指定的OpenCL驱动。有了这个中间库,你的项目代码中的OpenCL API请求可以不依赖于任何厂商的OpenCL SDK,可以在没有安装任何OpenCL SDK的环境实现代码编译,你可以以动态库的形式使用它,也可以把这个中间库静态编译到自己的项目代码中,真正的实现OpenCL SDK无关性、设备无关性。
注意:一台机器可以有几个OpenCL 平台,每个平台都有自己的驱动程序和OpenCL 版本,总是只有一个ICD Loader程序。ICD Loader程充当所有安装的OpenCL平台的主管,并为所有OpenCL调用提供了唯一的入口点。基于平台ID,它将OpenCL主机调用分配到正确的驱动程序。
在linux系统,编写OpenCL应用程序需要:
OpenCL头文件:CL/cl.h;ICD Loader库文件:libOpenCL.so;ICD定义文件,一般位于/etc/OpenCL/vendors/,在该目录下存放OpenCL实现的厂商特定文件;在这个目录中,通常会有一个或多个.icd文件,用于指定可用的OpenCL平台,这些文件包含OpenCL实现的信息,包括库文件路径;当系统加载OpenCL时,它会检查该目录下的.icd文件,并根据文件中的内容确定可用的OpenCL平台,每个.icd文件通常包含一个供应商库文件的路径;ICD:由设备制造商提供,针对某个特定设备的专门的OpenCL实现;
2.3 VulKan
Vulkan是Khronos组织制定的下一代开放的图形显示API。是与DirectX12能够匹敌的GPU API标准。Vulkan是基于AMD的Mantle API演化而来,Vulkan提供了能直接控制和访问底层GPU的显示驱动抽象层。 显示驱动仅仅是对硬件薄薄的封装,这样能够显著提升操作GPU硬件的效率和性能。之前OpenGL的驱动层对开发人员隐藏的非常多细节,如今都暴露出来。Vulkan甚至不包括执行期的错误检查层。驱动层干的事情少了,隐藏的bug也就少了。
Vulkan不再使用OpenGL的状态机设计,内部也不保存全局状态变量。显示资源全然由应用层负责管理。包括内存管理、线程管理、多线程绘制命令产生、渲染队列提交等。应用程序能够充分利用CPU的多核多线程的计算资源,降低CPU等待,降低延迟。 带来的问题是。线程间的同步问题也由应用程序负责,从而对开发人员的要求也更高。
三、配置Panfrost驱动
关于linux 6.3内核的下载和配置、编译参考:Rockchip RK3399 - 移植uboot 2023.04 & linux 6.3。
3.1 配置内核
3.1.1 Panfrost GPU驱动
在linux内核根目录下执行make menuconfig命令,进入如下配置:
Device Drivers --->
Graphics support --->
<*> Panfrost (DRM support for ARM Mali Midgard/Bifrost GPUs)
默认编译到内核中或者以模块的形式加载都可以。
3.1.2 驱动代码
驱动位于drivers/gpu/drm/panfrost/文件夹下;
root@zhengyang:/work/sambashare/rk3399/linux-6.3# ll drivers/gpu/drm/panfrost/
总用量 1720
drwxrwxr-x 2 root root 4096 Jun 5 20:58 ./
drwxrwxr-x 64 root root 16384 Jun 5 20:22 ../-rw-rw-r-- 1 root root 472 Aug 9 2019 Kconfig
-rw-rw-r-- 1 root root 225 Aug 9 2019 Makefile-rw-rw-r-- 1 root root 5934 Aug 9 2019 panfrost_devfreq.c
-rw-rw-r-- 1 root root 441 Aug 9 2019 panfrost_devfreq.h-rw-rw-r-- 1 root root 6427 Aug 9 2019 panfrost_device.c
-rw-rw-r-- 1 root root 2678 Aug 9 2019 panfrost_device.h-rw-rw-r-- 1 root root 11971 Aug 9 2019 panfrost_drv.c-rw-rw-r-- 1 root root 11398 Aug 9 2019 panfrost_features.h
-rw-rw-r-- 1 root root 2353 Aug 9 2019 panfrost_gem.c
-rw-rw-r-- 1 root root 785 Aug 9 2019 panfrost_gem.h-rw-rw-r-- 1 root root 10974 Aug 9 2019 panfrost_gpu.c
-rw-rw-r-- 1 root root 586 Aug 9 2019 panfrost_gpu.h-rw-rw-r-- 1 root root 3944 Aug 9 2019 panfrost_issues.h
-rw-rw-r-- 1 root root 13584 Aug 9 2019 panfrost_job.c
-rw-rw-r-- 1 root root 1428 Aug 9 2019 panfrost_job.h-rw-rw-r-- 1 root root 9752 Aug 9 2019 panfrost_mmu.c
-rw-rw-r-- 1 root root 486 Aug 9 2019 panfrost_mmu.h-rw-rw-r-- 1 root root 14759 Aug 9 2019 panfrost_regs.h
-rw-rw-r-- 1 root root 880 Aug 9 2019 TODO
驱动入口文件在panfrost_drv.c,在该文件我们可以看到支持的GPU型号;
static const struct of_device_id dt_match[] = {
/* Set first to probe before the generic compatibles */
{ .compatible = "amlogic,meson-gxm-mali",
.data = &amlogic_data, },
{ .compatible = "amlogic,meson-g12a-mali",
.data = &amlogic_data, },
{ .compatible = "arm,mali-t604", .data = &default_data, },
{ .compatible = "arm,mali-t624", .data = &default_data, },
{ .compatible = "arm,mali-t628", .data = &default_data, },
{ .compatible = "arm,mali-t720", .data = &default_data, },
{ .compatible = "arm,mali-t760", .data = &default_data, },
{ .compatible = "arm,mali-t820", .data = &default_data, },
{ .compatible = "arm,mali-t830", .data = &default_data, },
{ .compatible = "arm,mali-t860", .data = &default_data, },
{ .compatible = "arm,mali-t880", .data = &default_data, },
{ .compatible = "arm,mali-bifrost", .data = &default_data, },
{ .compatible = "arm,mali-valhall-jm", .data = &default_data, },
{ .compatible = "mediatek,mt8183-mali", .data = &mediatek_mt8183_data },
{}
};
MODULE_DEVICE_TABLE(of, dt_match);
static struct platform_driver panfrost_driver = {
.probe = panfrost_probe,
.remove = panfrost_remove,
.driver = {
.name = "panfrost",
.pm = pm_ptr(&panfrost_pm_ops),
.of_match_table = dt_match,
},
};
module_platform_driver(panfrost_driver);
3.2 gpu设备节点
我们可以在arch/arm64/boot/dts/rockchip/rk3399.dtsi文件找到gpu设备节点的定义:
gpu: gpu@ff9a0000 {
compatible = "rockchip,rk3399-mali", "arm,mali-t860";
reg = <0x0 0xff9a0000 0x0 0x10000>;
interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH 0>,
<GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH 0>,
<GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH 0>;
interrupt-names = "job", "mmu", "gpu";
clocks = <&cru ACLK_GPU>;
#cooling-cells = <2>;
power-domains = <&power RK3399_PD_GPU>;
status = "disabled";
};
其中:
compatible:说明了设备兼容的驱动名称,即"rockchip,rk3399-mali"和"arm,mali-t860";可以看到arm,mali-t860是和panfrost驱动相匹配的,因此会执行驱动的.probe函数,这里就不深入研究了;reg:指定了寄存器的基地址和大小,即基地址0xff9a0000,大小为0x10000;interrupts和interrupt-names:分别指定了该设备所使用的中断号和中断的名称;clocks:指定了使用哪个时钟控制器(CRU)提供GPU时钟;power-domains:用于指定设备所属的电源域,即RK3399_PD_GPU;status:设置为"disabled"表示GPU设备当前处于禁用状态,无法使用;
3.2.1 设备节点gpu新增属性
我们需要在arch/arm64/boot/dts/rockchip/rk3399-evb.dts文件中为gpu设备节点新增以下属性;
&gpu {
mali-supply = <&vdd_gpu>;
status = "okay";
};
其中:
-
mali-supply:指定了GPU设备使用的电源管脚; -
status:指定GPU设备的状态("okay" 表示设备正常工作);
3.2.2 GPU电源接线原理图
我们看一下GPU电源的接线图;
从图中可以看到VDD_GPU是由SYR838PKC输出的,SYR837/SYR838是一款高效率的同步降压DC/DC变换器芯片,内部应该就是通过BUCK降压电路实现的。其主要特点包括:
- 最大输出电流可达
6A; - 宽输入电压范围:
2.6V至5.5V; - 集成主开关和同步开关,具有非常低的导通损耗(即
R DS(ON)值很低); - 输出电压可以通过
I2C接口编程,范围从0.7125V到1.5V;
SYR837/SYR838具有I2C接口,允许主处理器通过控制输出电压来实现电压缩放(DVS)功能。I2C接口支持最高达3.4MHz的时钟速度,并使用标准的I2C命令。SYR837/SYR838始终作为从设备运行,并通过一个由7位从地址和一个第8位读写标志组成的地址被寻址。SYR837的I2C地址在出厂时设置为0x40H,SYR838的地址设置为0x41H。
通过I2C接口,主处理器可以向SYR837/SYR838发送命令,以控制输出电压大小,实现电压缩放功能,从而适应不同的工作负载和功耗需求。此外,I2C接口还可以实现对芯片的配置、监测和故障诊断等功能,提高了系统的可靠性和灵活性。
I2C接线如下:
| SYR838PKC | RK3399 | 描述 |
|---|---|---|
| SCL | I2C_SCL_PMIC(GPIO1_C0/SPI3_TXD/I2C0_SCL) | I2C串行时钟线 |
| SDA | I2C_SDA_PMIC(GPIO1_B7/SPI3_RXD/I2C0_SDA) | I2C串行数据线 |
| VSEL | GPU_SLEEP(GPIO1_B6/PWM3B_IR) | 电压选择引脚; 低电平时,该芯片将根据VSEL0寄存器的值来设置输出电压VOUT; 高电平时,该芯片将根据VSEL1寄存器的值来设置输出电压VOUT。 |
| VIN | VCC3V3_SYS | 输入电压 |
| VOUT | VDDGPU(GPU_VDD1~20) | 输出电压 |
需要注意的是:以上内容来自SYR838PKC datasheet,更多细节请自己查看手册。
3.2.3 设备节点vdd_gpu
vdd_gpu设备节点描述GPU所需的电源配置信息。具体来说,它描述了一个名为vdd_gpu的稳压管(也就是SYR828PKC芯片),用于为GPU提供电源。
vdd_gpu设备节点节点是i2c0设备节点的子节点,配置如下
vdd_gpu: regulator@41 {
compatible = "silergy,syr828";
reg = <0x41>;
fcs,suspend-voltage-selector = <1>;
pinctrl-names = "default";
pinctrl-0 = <&gpu_sleep>;
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <712500>;
regulator-max-microvolt = <1500000>;
regulator-name = "vdd_gpu";
regulator-ramp-delay = <1000>;
vin-supply = <&vcc3v3_sys>;
regulator-state-mem {
regulator-off-in-suspend;
};
};
这个稳压管的配置信息包括:
compatible:指定了稳压管使用的驱动程序类型和版本信息;reg:指定了I2C设备的地址;fcs,suspend-voltage-selector:指定了稳压管在睡眠模式下的工作电压;pinctrl-names:设置了引脚的默认状态,引脚配置设置为gpu_sleep;pinctrl-0:指定了default状态的对应的引脚配置,即gpu_sleep;regulator-always-on:表示稳压管始终处于开启状态;regulator-boot-on:表示稳压管在启动时自动开启;regulator-min-microvolt:指定了稳压管的最小输出电压;regulator-max-microvolt:指定了稳压管的最大输出电压;regulator-name:指定了稳压管在的名称。regulator-ramp-delay:指定了稳压管从关闭到开启时的延迟时间;vin-supply:指定了稳压管的输入电源,VCC3V3_SYS是由电源输入的12V电源经过稳压管NB680GD输出得到的;
既然我们已经看到这里了,不妨继续看一下引脚配置节点gpu_sleep,其定义在pinctrl设备节点下:
pmic {
cpu_b_sleep: cpu-b-sleep {
rockchip,pins = <1 RK_PC1 RK_FUNC_GPIO &pcfg_pull_down>;
};
gpu_sleep: gpu-sleep {
rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_down>;
};
pmic_int_l: pmic-int-l {
rockchip,pins = <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>;
};
};
可以看到这里配置GPIO1_B6引脚功能为GPIO,电气特性为pcfg_pull_down,表示下拉。GPIO1_B6连接的就是SYR838PKC的VSEL引脚。
至于设备vcc3v3_sys设备节点,实际上就比较简单了,其它描述了一个名为vcc3v3_sys的稳压管(也就是NB680GD芯片,其输出电压是固定的就是3.3V,因此也没啥好说的);
vcc3v3_sys: vcc3v3-sys {
compatible = "regulator-fixed";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-name = "vcc3v3_sys";
};
3.3 保存配置
配置完内核之后记得保存配置:

存档:
root@zhengyang:/work/sambashare/rk3399/linux-6.3# mv rk3399_defconfig ./arch/arm64/configs/
重新配置内核:
root@zhengyang:/work/sambashare/rk3399/linux-6.3# make rk3399_defconfig
3.4 编译并烧录
3.4.1 编译内核
在linux内核根目录下执行如下命令进行编译内核:
root@zhengyang:/work/sambashare/rk3399/linux-6.3# make -j8
u-boot-2023.04路径下的mkimage工具拷贝过来,然后在命令行使用mkimage工具编译即可:
root@zhengyang:/work/sambashare/rk3399/linux-6.3# cp ../u-boot-2023.04/tools/mkimage ./
root@zhengyang:/work/sambashare/rk3399/linux-6.3# ./mkimage -f kernel.its kernel.itb
需要注意的是这里一定不能指定-E参数,不然uboot在进行kernel镜像hash校验的时候就会失败。
3.4.2 通过tftp烧录内核
给开发板上电,同时连接上网线,进入uboot命令行。我们将内核拷贝到tftp文件目录:
root@zhengyang:/work/sambashare/rk3399/linux-6.3# cp kernel.itb /work/tftpboot/
接着通过uboot命令行将kernel.itb下到内存地址0x10000000处:
=> tftp 0x10000000 kernel.itb
通过mmc write命令将内核镜像烧录到eMMC第0x8000个扇区处:
=> mmc erase 0x8000 0xA000
=> mmc write 0x10000000 0x8000 0xA000
3.4.3 启动内核
我们重新启动开发板,如果Panfrost GPU驱动正常加载,我们会看到类似下面的日志:
[ 5.136204] panfrost ff9a0000.gpu: clock rate = 500000000
[ 5.144160] panfrost ff9a0000.gpu: mali-t860 id 0x860 major 0x2 minor 0x0 status 0x0
[ 5.152968] panfrost ff9a0000.gpu: features: 00000000,00000407, issues: 00000000,24040400
[ 5.162213] panfrost ff9a0000.gpu: Features: L2:0x07120206 Shader:0x00000000 Tiler:0x00000809 Mem:0x1 MMU:0x00002830 AS:0xff JS:0x7
[ 5.175546] panfrost ff9a0000.gpu: shader_present=0xf l2_present=0x1
[ 5.187126] [drm] Initialized panfrost 1.2.0 20180908 for ff9a0000.gpu on minor
我们通过cat /proc/interrupts查看的中断资源申请信息:
root@rk3399:~# cat /proc/interrupts
CPU0 CPU1 CPU2 CPU3 CPU4 CPU5
18: 0 0 0 0 0 0 GICv3 25 Level vgic
20: 0 0 0 0 0 0 GICv3 27 Level kvm guest vtimer
23: 5229218 11382094 1217261 10038778 19054827 11981523 GICv3 30 Level arch_timer
25: 5780853 20309476 5439994 5787820 7385356 6471922 GICv3 113 Level rk_timer
31: 0 0 0 0 0 0 GICv3-23 0 Level arm-pmu
32: 0 0 0 0 0 0 GICv3-23 1 Level arm-pmu
33: 1 0 0 0 0 0 GICv3 59 Level rockchip_usb2phy
34: 1 0 0 0 0 0 GICv3 135 Level rockchip_usb2phy_bvalid
35: 0 0 0 0 0 0 GICv3 136 Level rockchip_usb2phy_id
36: 1 0 0 0 0 0 GICv3 63 Level rockchip_usb2phy
37: 0 0 0 0 0 0 GICv3 37 Level ff6d0000.dma-controller
38: 0 0 0 0 0 0 GICv3 38 Level ff6d0000.dma-controller
39: 0 0 0 0 0 0 GICv3 39 Level ff6e0000.dma-controller
40: 0 0 0 0 0 0 GICv3 40 Level ff6e0000.dma-controller
41: 330 0 0 0 0 0 GICv3 132 Level ttyS2
42: 0 0 0 0 0 0 GICv3 147 Level ff650800.iommu
43: 0 0 0 0 0 0 GICv3 149 Level ff660480.iommu
44: 9968693 0 0 0 0 0 GICv3 151 Level ff8f3f00.iommu, ff8f0000.vop
45: 0 0 0 0 0 0 GICv3 150 Level ff903f00.iommu, ff900000.vop
46: 0 0 0 0 0 0 GICv3 75 Level ff914000.iommu
47: 0 0 0 0 0 0 GICv3 76 Level ff924000.iommu
48: 0 0 0 0 0 0 GICv3 137 Level dwc3-otg, xhci-hcd:usb4
49: 0 0 0 0 0 0 GICv3 142 Level xhci-hcd:usb7
50: 2 0 0 0 0 0 GICv3 58 Level ehci_hcd:usb5
51: 2 0 0 0 0 0 GICv3 62 Level ehci_hcd:usb2
52: 32 0 0 0 0 0 GICv3 60 Level ohci_hcd:usb1
53: 10281 0 0 0 0 0 GICv3 64 Level ohci_hcd:usb3
54: 36 0 0 0 0 0 GICv3 91 Level ff110000.i2c
55: 1545 0 0 0 0 0 GICv3 68 Level ff160000.i2c
56: 4881 0 0 0 0 0 GICv3 89 Level ff3c0000.i2c
57: 0 0 0 0 0 0 rockchip_gpio_irq 21 Level rk808
63: 0 0 0 0 0 0 rk808 5 Edge RTC alarm
67: 213 0 0 0 0 0 GICv3 88 Level ff3d0000.i2c
68: 2 0 0 0 0 0 rockchip_gpio_irq 2 Level fsc_interrupt_int_n
69: 0 0 0 0 0 0 GICv3 129 Level rockchip_thermal
70: 0 0 0 0 0 0 GICv3 152 Edge ff848000.watchdog
71: 2241639 0 0 0 0 0 GICv3 96 Level dw-mci
72: 0 0 0 0 0 0 GICv3 97 Level dw-mci
73: 623332 0 0 0 0 0 GICv3 43 Level mmc0
74: 0 0 0 0 0 0 rockchip_gpio_irq 7 Edge fe320000.mmc cd
75: 1 0 0 0 0 0 rockchip_gpio_irq 4 Edge bt_default_wake_host_irq
76: 307 0 0 0 0 0 GICv3 55 Level ff940000.hdmi, dw-hdmi-cec
77: 4232 0 0 0 0 0 GICv3 51 Level panfrost-gpu
78: 0 0 0 0 0 0 GICv3 53 Level panfrost-mmu
79: 39658637 0 0 0 0 0 GICv3 52 Level panfrost-job
80: 66773 0 0 0 0 0 GICv3 44 Level eth0
81: 14 0 0 0 0 0 rockchip_gpio_irq 10 Level stmmac-0:01
82: 0 0 0 0 0 0 rockchip_gpio_irq 28 Edge Headphone detection
83: 0 0 0 0 0 0 rockchip_gpio_irq 5 Edge GPIO Key Power
IPI0: 4343 4603 3990 4186 5412 5236 Rescheduling interrupts
IPI1: 4635845 55709763 13055109 47287583 12174799 14089449 Function call interrupts
IPI2: 0 0 0 0 0 0 CPU stop interrupts
IPI3: 0 0 0 0 0 0 CPU stop (for crash dump) interrupts
IPI4: 6096518 14214971 3055613 26838525 11759114 8812762 Timer broadcast interrupts
IPI5: 4181228 0 0 0 0 0 IRQ work interrupts
IPI6: 0 0 0 0 0 0 CPU wake-up interrupts
Err: 0
gpu、 job、mmu都是Panfrost GPU驱动注册的中断,都是电平触发类型的中断,高电平触发。左边的数字4232和39658637是当前产生的中断的数量。
四、安装mesa 21.2.6
ARM Mali GPU驱动Usersacpe部分的开源库叫做mesa,安装mesa有两种方式,一种是直接通过apt install安装,还有一种是通过编译源码安装,用户可以自行选择哪一种安装方式。
编译安装比较繁琐,我们后面单独来介绍。本节我们先介绍apt install安装方式。然后在后面的章节介绍:
- 在
ubuntu 20.04编译安装mesa 22.0.0; - 在
ubuntu 22.04编译安装mesa 24.0.0(推荐);
4.1 安装依赖
我们首先安装一些常见的工具包:
root@rk3399:/opt# apt install cmake git build-essential meson python3-pip
其中:
cmake: 用于构建C++项目的跨平台构建工具;git: 版本控制系统,用于管理代码库;meson: 构建系统,用于自动化项目的构建过程;python3-pip:Python包管理器,用于安装和管理Python包。
4.1.1 安装mesa-utils
首先我们需要先安装mesa-utils,mesa-utils是一个Linux上的实用工具包,用于与mesa图形库(用于支持OpenGL)进行交互和诊断,用于查看图形驱动的信息、测试OpenGL的功能和性能以及检查3D加速是否正常工作;
root@rk3399:/opt# apt install mesa-utils
以下是mesa-utils的一些常见用途:
glxinfo:该工具提供了有关系统上安装的OpenGL实现的详细信息(实际上,ubuntu系统已经默认支持了OpenGL)。您可以使用glxinfo命令查看OpenGL版本、支持的扩展、渲染器信息等。例如,运行glxinfo | grep "OpenGL version"可以查看系统上安装的OpenGL版本;glxgears: 这是一个简单的测试工具,用于检测系统对OpenGL的支持情况。它会显示一个旋转的齿轮动画,并报告每秒渲染的帧数;glxheads: 这个工具可以列出当前系统中可用的X11窗口和OpenGL上下文,并提供有关它们的详细信息;
注意:mesa-utils并不是开发mesa应用程序所必需的,而是一个用于调试和测试的辅助工具集。
4.1.2 安装OpenGL开发依赖包
如果需要开发OpenGL应用程序,需要安装开发环境依赖包:
root@rk3399:/opt# apt install libgl1-mesa-dev libgles2-mesa-dev libegl1-mesa-dev
其中:
libgl1-mesa-dev(依赖libgl-dev、libglvnd-dev): 包含了OpenGL的开发头文件和库,可以在开发环境中使用OpenGL来编写和运行应用程序,具体如下:libgl-dev:Vendor neutral GL dispatch library -- GL development files,安装部分/usr/include/GL头文件、以及/usr/include/KHR/khrplatform.h;libgl1:Vendor neutral GL dispatch library -- legacy GL support,安装/usr/lib/aarch64-linux-gnu/libGL.so.1.7.0;libglx-dev:Vendor neutral GL dispatch library -- GLX development files,安装部分/usr/include/GL头文件;
libgles2-mesa-dev(依赖libgles-dev、libglvnd-dev): 包含了Open GLES的开发头文件和库,可以在开发环境中使用GLES1、GLES2来编写和运行应用程序,具体如下:libgles-dev:Vendor neutral GL dispatch library -- GLES development files,安装/usr/include/GLES、/usr/include/GLES2、/usr/include/GLES3头文件;-
libegl-dev:Vendor neutral GL dispatch library -- EGL development files,安装/usr/include/EGL头文件;ligegl1:Vendor neutral GL dispatch library -- EGL support,安装/usr/lib/aarch64-linux-gnu/libEGL.so.1.1.0;libgl-dev:上面已经介绍;libx11-dev(依赖libx11-6、libxcb1-dev、x11proto-dev等);X11 client-side library (development headers),安装/usr/include/X11头文件,以及/usr/lib/aarch64-linux-gnu/libX11.a库文件;
-
libgl-dev:上面已经介绍; -
libgles1:Vendor neutral GL dispatch library -- GLESv1 support,安装/usr/lib/aarch64-linux-gnu/libGLESv1_CM.so.1.2.0; -
libgles2:Vendor neutral GL dispatch library -- GLESv2 support,安装/usr/lib/aarch64-linux-gnu/libGLESv2.so.2.1.0;
-
libegl1-mesa-dev(依赖libegl-dev、libglvnd-dev):free implementation of the EGL API -- development files,可以在开发环境中使用EGL来创建和管理窗口系统的集成;libegl-dev:上面已经介绍;
注意:上面包安装时除了安装上面介绍的动态库外,还会进行创建链接文件等操作。
4.1.3 安装OpenCL
ocl-icd-libopencl1和ocl-icd-opencl-dev是OpenCL ICD Loader的包,用于在Linux系统中加载OpenCL平台。安装命令如下:
root@rk3399:/opt# apt install opencl-headers ocl-icd-libopencl1 ocl-icd-opencl-dev
其中:
opencl-headers:OpenCL (Open Computing Language) header files;opencl-c-headers:OpenCL (Open Computing Language) C header files,安装部分/usr/include/CL头文件;opencl-clhpp-headers:C++ headers for OpenCL development,安装部分/usr/include/CL头文件;
ocl-icd-libopencl1:Generic OpenCL ICD Loader,安装/usr/lib/aarch64-linux-gnu/libOpenCL.so.1.0.0;ocl-icd-opencl-dev(依赖ocl-icd-libopencl1、opencl-headers):OpenCL development files;
安装mesa gallium clover OpenCL ICD驱动程序(OpenCL开源实现):
root@rk3399:/opt# apt install mesa-opencl-icd
其中:
mesa-opencl-icd:free implementation of the OpenCL API -- ICD runtime,安装/usr/lib/aarch64-linux-gnu/libMesaOpenCL.so.1.0.0以及/usr/lib/aarch64-linux-gnu/gallium-pipe/下若干库文件;
我们可以查看/etc/OpenCL/vendors/目录获取当前系统中可用的OpenCL平台;
root@rk3399:/opt# ls -l /etc/OpenCL/vendors/
-rw-r--r-- 1 root root 19 Jan 20 19:50 mesa.icd
root@rk3399:/opt# cat /etc/OpenCL/vendors/mesa.icd
libMesaOpenCL.so.1
4.1.4 查看头文件和库文件
安装完mesa图像库之后,我们可以在系统找到安装的开发库和头文件:
root@rk3399:/opt# find /usr | grep lib.*GL.*.so # OpenGL等库,实际上ubuntu操作系统默认已经预置了这些
# OpenGL
/usr/lib/aarch64-linux-gnu/libOpenGL.so # 链接文件
/usr/lib/aarch64-linux-gnu/libOpenGL.so.0 # 链接文件
/usr/lib/aarch64-linux-gnu/libOpenGL.so.0.0.0 # libopengl0包安装
# GL
/usr/lib/aarch64-linux-gnu/libGL.so # 链接文件
/usr/lib/aarch64-linux-gnu/libGL.so.1 # 链接文件
/usr/lib/aarch64-linux-gnu/libGL.so.1.7.0 # libgl1包安装
# EGL
/usr/lib/aarch64-linux-gnu/libEGL.so # 链接文件
/usr/lib/aarch64-linux-gnu/libEGL.so.1 # 链接文件
/usr/lib/aarch64-linux-gnu/libEGL.so.1.1.0 # ligegl1包安装
/usr/lib/aarch64-linux-gnu/libEGL_mesa.so.0 # 链接文件
/usr/lib/aarch64-linux-gnu/libEGL_mesa.so.0.0.0 # libegl-mesa0包安装
# GLES v1
/usr/lib/aarch64-linux-gnu/libGLESv1_CM.so # 链接文件
/usr/lib/aarch64-linux-gnu/libGLESv1_CM.so.1 # 链接文件
/usr/lib/aarch64-linux-gnu/libGLESv1_CM.so.1.2.0 # libgles1包安装
# GLES v2
/usr/lib/aarch64-linux-gnu/libGLESv2.so # 链接文件
/usr/lib/aarch64-linux-gnu/libGLESv2.so.2 # 链接文件
/usr/lib/aarch64-linux-gnu/libGLESv2.so.2.1.0 # libgles2包安装
# GLX
/usr/lib/aarch64-linux-gnu/libGLX.so # 链接文件
/usr/lib/aarch64-linux-gnu/libGLX.so.0 # 链接文件
/usr/lib/aarch64-linux-gnu/libGLX.so.0.0.0 # libglx0包安装
/usr/lib/aarch64-linux-gnu/libGLX_indirect.so.0 # 链接文件
/usr/lib/aarch64-linux-gnu/libGLX_mesa.so.0 # 链接文件
/usr/lib/aarch64-linux-gnu/libGLX_mesa.so.0.0.0 # libglx-mesa0包安装
# GLU
/usr/lib/aarch64-linux-gnu/libGLU.so.1 # 链接文件
/usr/lib/aarch64-linux-gnu/libGLU.so.1.3.1 # libglu1-mesa包安装
# 其它
/usr/lib/libreoffice/program/libOGLTranslo.so
/usr/lib/aarch64-linux-gnu/libGLdispatch.so # 链接文件
/usr/lib/aarch64-linux-gnu/libGLdispatch.so.0 # 链接文件
/usr/lib/aarch64-linux-gnu/libGLdispatch.so.0.0.0 # libglvnd0包安装
root@rk3399:/opt# ls -l /usr/lib/aarch64-linux-gnu/dri/ # dri库,ubuntu操作系统默认带有
-rw-r--r-- 38 root root 23619952 Mar 9 2022 armada-drm_dri.so
-rw-r--r-- 38 root root 23619952 Mar 9 2022 d3d12_dri.so
-rw-r--r-- 38 root root 23619952 Mar 9 2022 etnaviv_dri.so
-rw-r--r-- 38 root root 23619952 Mar 9 2022 exynos_dri.so
-rw-r--r-- 38 root root 23619952 Mar 9 2022 hx8357d_dri.so
-rw-r--r-- 38 root root 23619952 Mar 9 2022 ili9225_dri.so
-rw-r--r-- 38 root root 23619952 Mar 9 2022 ili9341_dri.so
-rw-r--r-- 38 root root 23619952 Mar 9 2022 imx-dcss_dri.so
-rw-r--r-- 38 root root 23619952 Mar 9 2022 imx-drm_dri.so
-rw-r--r-- 38 root root 23619952 Mar 9 2022 ingenic-drm_dri.so
-rw-r--r-- 38 root root 23619952 Mar 9 2022 kgsl_dri.so
-rw-r--r-- 38 root root 23619952 Mar 9 2022 kms_swrast_dri.so
-rw-r--r-- 38 root root 23619952 Mar 9 2022 lima_dri.so
-rw-r--r-- 38 root root 23619952 Mar 9 2022 mali-dp_dri.so
-rw-r--r-- 38 root root 23619952 Mar 9 2022 mcde_dri.so
-rw-r--r-- 38 root root 23619952 Mar 9 2022 mediatek_dri.so
-rw-r--r-- 38 root root 23619952 Mar 9 2022 meson_dri.so
-rw-r--r-- 38 root root 23619952 Mar 9 2022 mi0283qt_dri.so
-rw-r--r-- 38 root root 23619952 Mar 9 2022 msm_dri.so
-rw-r--r-- 38 root root 23619952 Mar 9 2022 mxsfb-drm_dri.so
-rw-r--r-- 38 root root 23619952 Mar 9 2022 nouveau_dri.so
-rw-r--r-- 3 root root 5796048 Mar 9 2022 nouveau_vieux_dri.so
-rw-r--r-- 38 root root 23619952 Mar 9 2022 panfrost_dri.so
-rw-r--r-- 38 root root 23619952 Mar 9 2022 pl111_dri.so
-rw-r--r-- 3 root root 5796048 Mar 9 2022 r200_dri.so
-rw-r--r-- 38 root root 23619952 Mar 9 2022 r300_dri.so
-rw-r--r-- 38 root root 23619952 Mar 9 2022 r600_dri.so
-rw-r--r-- 3 root root 5796048 Mar 9 2022 radeon_dri.so
-rw-r--r-- 38 root root 23619952 Mar 9 2022 radeonsi_dri.so
-rw-r--r-- 38 root root 23619952 Mar 9 2022 repaper_dri.so
-rw-r--r-- 38 root root 23619952 Mar 9 2022 rockchip_dri.so
-rw-r--r-- 38 root root 23619952 Mar 9 2022 st7586_dri.so
-rw-r--r-- 38 root root 23619952 Mar 9 2022 st7735r_dri.so
-rw-r--r-- 38 root root 23619952 Mar 9 2022 stm_dri.so
-rw-r--r-- 38 root root 23619952 Mar 9 2022 sun4i-drm_dri.so
-rw-r--r-- 38 root root 23619952 Mar 9 2022 swrast_dri.so
-rw-r--r-- 38 root root 23619952 Mar 9 2022 tegra_dri.so
-rw-r--r-- 38 root root 23619952 Mar 9 2022 v3d_dri.so
-rw-r--r-- 38 root root 23619952 Mar 9 2022 vc4_dri.so
-rw-r--r-- 38 root root 23619952 Mar 9 2022 virtio_gpu_dri.so
-rw-r--r-- 38 root root 23619952 Mar 9 2022 zink_dri.so
root@rk3399:/opt/mesa-22.0.0# ls -l /usr/lib/aarch64-linux-gnu/*OpenCL* # OpenCL库
# ocl-icd-opencl-dev包安装
lrwxrwxrwx 1 root root 18 Apr 5 2017 /usr/lib/aarch64-linux-gnu/libOpenCL.so -> libOpenCL.so.1.0.0
# ocl-icd-libopencl1包安装
lrwxrwxrwx 1 root root 18 Apr 5 2017 /usr/lib/aarch64-linux-gnu/libOpenCL.so.1 -> libOpenCL.so.1.0.0
-rw-r--r-- 1 root root 34808 Apr 5 2017 /usr/lib/aarch64-linux-gnu/libOpenCL.so.1.0.0
# mesa-opencl-icd包安装
lrwxrwxrwx 1 root root 18 Mar 9 2022 /usr/lib/aarch64-linux-gnu/libMesaOpenCL.so -> libMesaOpenCL.so.1
lrwxrwxrwx 1 root root 22 Mar 9 2022 /usr/lib/aarch64-linux-gnu/libMesaOpenCL.so.1 -> libMesaOpenCL.so.1.0.0
-rw-r--r-- 1 root root 1372512 Mar 9 2022 /usr/lib/aarch64-linux-gnu/libMesaOpenCL.so.1.0.0
# 以下头文件均是新安装
root@rk3399:/opt# ls /usr/include | grep GL
EGL GL GLES GLES2 GLES3
root@rk3399:/opt# ls -l /usr/include/EGL/ # libegl-dev包安装
-rw-r--r-- 1 root root 20345 Jun 26 2020 egl.h
-rw-r--r-- 1 root root 68048 Jun 26 2020 eglext.h
-rw-r--r-- 1 root root 3192 Nov 25 2021 eglextchromium.h
-rw-r--r-- 1 root root 2129 Nov 25 2021 eglmesaext.h
-rw-r--r-- 1 root root 6049 Jun 26 2020 eglplatform.h
root@rk3399:/opt# ls -l /usr/include/GL
-rw-r--r-- 1 root root 80393 Jun 26 2020 gl.h # libgl-dev包安装
-rw-r--r-- 1 root root 421339 Jun 26 2020 glcorearb.h # libgl-dev包安装
-rw-r--r-- 1 root root 848032 Jun 26 2020 glext.h # libgl-dev包安装
-rw-r--r-- 1 root root 16906 Jun 26 2020 glx.h # libglx-dev包安装
-rw-r--r-- 1 root root 48370 Jun 26 2020 glxext.h # libglx-dev包安装
-rw-r--r-- 1 root root 4695 Mar 9 2020 glxint.h # x11proto-dev包安装
-rw-r--r-- 1 root root 2085 Mar 9 2020 glxmd.h # x11proto-dev包安装
-rw-r--r-- 1 root root 78531 Mar 9 2020 glxproto.h # x11proto-dev包安装
-rw-r--r-- 1 root root 11429 Mar 9 2020 glxtokens.h # x11proto-dev包安装
drwxr-xr-x 2 root root 4096 Nov 13 13:22
root@rk3399:/opt# ls -l /usr/include/GLES # libgles-dev包安装
-rw-r--r-- 1 root root 922 Jun 26 2020 egl.h
-rw-r--r-- 1 root root 31669 Jun 26 2020 gl.h
-rw-r--r-- 1 root root 53780 Jun 26 2020 glext.h
-rw-r--r-- 1 root root 1152 Jun 26 2020 glplatform.h
root@rk3399:/opt# ls -l /usr/include/GLES2 # libgles-dev包安装
-rw-r--r-- 1 root root 43996 Jun 26 2020 gl2.h
-rw-r--r-- 1 root root 231362 Jun 26 2020 gl2ext.h
-rw-r--r-- 1 root root 1160 Jun 26 2020 gl2platform.h
root@rk3399:/opt# ls -l /usr/include/GLES3 # libgles-dev包安装
-rw-r--r-- 1 root root 82674 Jun 26 2020 gl3.h
-rw-r--r-- 1 root root 107463 Jun 26 2020 gl31.h
-rw-r--r-- 1 root root 128343 Jun 26 2020 gl32.h
-rw-r--r-- 1 root root 166 Jun 26 2020 gl3ext.h
-rw-r--r-- 1 root root 1160 Jun 26 2020 gl3platform.h
4.2 测试GPU
4.2.1 glxinfo
进入桌面后,打开一个终端,使用glxinfo -B命令查看GPU驱动,可以看到Device: Mali-T860 (Panfrost)、OpenGL version string: 3.1 mesa 21.2.6;
root@rk3399:/opt# export DISPLAY=:0.0; glxinfo -B
name of display: :0.0
display: :0 screen: 0
direct rendering: Yes
Extended renderer info (GLX_MESA_query_renderer):
Vendor: Panfrost (0xffffffff)
Device: Mali T860 (Panfrost) (0xffffffff)
Version: 21.2.6
Accelerated: yes
Video memory: 3851MB
Unified memory: yes
Preferred profile: core (0x1)
Max core profile version: 3.1
Max compat profile version: 3.1
Max GLES1 profile version: 1.1
Max GLES[23] profile version: 3.1
OpenGL vendor string: Panfrost
OpenGL renderer string: Mali T860 (Panfrost)
OpenGL core profile version string: 3.1 Mesa 21.2.6
OpenGL core profile shading language version string: 1.40
OpenGL core profile context flags: (none)
OpenGL version string: 3.1 Mesa 21.2.6
OpenGL shading language version string: 1.40
OpenGL context flags: (none)
OpenGL ES profile version string: OpenGL ES 3.1 Mesa 21.2.6
OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.10
前面有讲到,GPU驱动分两部分,一部分在内核中,我们已经启动了,另外还有一个重要的部分在Userspace中,对于Panfrost GPU驱动来说,它叫做mesa。
mesa中实现了Panfrost GPU驱动的Userspace部分,在Userspace的部分向下操作内核中的驱动,向上对应用层提供标准的 API接口。
我们在输出的信息中可以看到如下信息,这说明mesa也已经安装了,版本号也是大于19.2的。
OpenGL version string: 3.1 mesa 21.2.6
4.2.2 screenfetch
使用screenfetch命令也可以看到GPU驱动使用的是Mali T860 (Panfrost);
roott@rk3399:/opt# apt install screenfetch
roott@rk3399:/opt# screenfetch
`oo++.
./+o+- zhengyang@rk3399
yyyyy- -yyyyyy+ OS: Ubuntu 20.04 focal
://+//////-yyyyyyo Kernel: aarch64 Linux 6.3.0
.++ .:/++++++/-.+sss/` Uptime: 8m
.:++o: /++++++++/:--:/- Packages: 1601
o:+o+:++.`..```.-/oo+++++/ Shell: bash 5.0.17
.:+o:+o/. `+sssoo+/ Resolution: 1920x1080
.++/+:+oo+o:` /sssooo. WM: Mutter
/+++//+:`oo+o /::--:. WM Theme: Adwaita
\+/+o+++`o++o ++////. GTK Theme: Adwaita [GTK3]
.++.o+++oo+:` /dddhhh. Disk: 6.6G / 17G (42%)
.+.o+oo:. `oddhhhh+ CPU: 6x Unknown
\+.++o+o``-````.:ohdhhhhh+ GPU: Mali T860 (Panfrost)
`:o+++ `ohhhhhhhhyo++os: RAM: 903MiB / 3851MiB
.o:`.syhhhhhhh/.oo++o`
/osyyyyyyo++ooo+++/
````` +oo+++o\:
`oo++.
4.2.3 GPU工作情况
其实到这里,因为GPU就已经真正的使用起来,通过以下方法可以快速判断GPU有没有在工作:
cat /proc/interrupts查看jpu和job产生的中断数量,如果GPU在工作,会频繁产生中断;- 运行
top命令,观察cpu利用率,如果GPU没工作,所有的图像渲染靠CPU,CPU占用率会高;
再次在firefox浏览器打开视频测试,测试发现虽然GPU已经工作,频繁产生中断但是CPU的利用率还是很高。

后来查阅资料判定可能是以下原因:firefox浏览器并没有开启GPU加速。
4.2.4 glmark2测试
Glmark2是一款比较出名的GPU benchmark测试程序,支持OpenGL 2.0和OpenGL ES 2.0。在ubuntu系统上可以直接通过apt install命令安装,在debian系统上需要通过源码编译:
roott@rk3399:/opt# apt install glmark2
在桌面环境终端运行glmark2命令即可进行测试;
roott@rk3399:/opt# glmark2 # export DISPLAY=:0.0;glmark2
=======================================================
glmark2 2021.02
=======================================================
OpenGL Information
GL_VENDOR: Panfrost
GL_RENDERER: Mali T860 (Panfrost)
GL_VERSION: 3.1 mesa 21.2.6
=======================================================
[build] use-vbo=false: FPS: 557 FrameTime: 1.795 ms
[build] use-vbo=true: FPS: 612 FrameTime: 1.634 ms
[texture] texture-filter=nearest: FPS: 674 FrameTime: 1.484 ms
[texture] texture-filter=linear: FPS: 677 FrameTime: 1.477 ms
[texture] texture-filter=mipmap: FPS: 672 FrameTime: 1.488 ms
[shading] shading=gouraud: FPS: 518 FrameTime: 1.931 ms
[shading] shading=blinn-phong-inf: FPS: 511 FrameTime: 1.957 ms
[shading] shading=phong: FPS: 457 FrameTime: 2.188 ms
[shading] shading=cel: FPS: 457 FrameTime: 2.188 ms
[bump] bump-render=high-poly: FPS: 283 FrameTime: 3.534 ms
[bump] bump-render=normals: FPS: 652 FrameTime: 1.534 ms
[bump] bump-render=height: FPS: 634 FrameTime: 1.577 ms
[effect2d] kernel=0,1,0;1,-4,1;0,1,0;: FPS: 419 FrameTime: 2.387 ms
[effect2d] kernel=1,1,1,1,1;1,1,1,1,1;1,1,1,1,1;: FPS: 196 FrameTime: 5.102 ms
[pulsar] light=false:quads=5:texture=false: FPS: 677 FrameTime: 1.477 ms
[desktop] blur-radius=5:effect=blur:passes=1:separable=true:windows=4: FPS: 146 FrameTime: 6.849 ms
[desktop] effect=shadow:windows=4: FPS: 556 FrameTime: 1.799 ms
[buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=map: FPS: 122 FrameTime: 8.197 ms
[buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=subdata: FPS: 23 FrameTime: 43.478 ms
[buffer] columns=200:interleave=true:update-dispersion=0.9:update-fraction=0.5:update-method=map: FPS: 159 FrameTime: 6.289 ms
[ideas] speed=duration: FPS: 356 FrameTime: 2.809 ms
[jellyfish] <default>: FPS: 307 FrameTime: 3.257 ms
[terrain] <default>: FPS: 19 FrameTime: 52.632 ms
[shadow] <default>: FPS: 298 FrameTime: 3.356 ms
[refract] <default>: FPS: 62 FrameTime: 16.129 ms
[conditionals] fragment-steps=0:vertex-steps=0: FPS: 591 FrameTime: 1.692 ms
[conditionals] fragment-steps=5:vertex-steps=0: FPS: 419 FrameTime: 2.387 ms
[conditionals] fragment-steps=0:vertex-steps=5: FPS: 611 FrameTime: 1.637 ms
[function] fragment-complexity=low:fragment-steps=5: FPS: 492 FrameTime: 2.033 ms
[function] fragment-complexity=medium:fragment-steps=5: FPS: 368 FrameTime: 2.717 ms
[loop] fragment-loop=false:fragment-steps=5:vertex-steps=5: FPS: 490 FrameTime: 2.041 ms
[loop] fragment-steps=5:fragment-uniform=false:vertex-steps=5: FPS: 491 FrameTime: 2.037 ms
[loop] fragment-steps=5:fragment-uniform=true:vertex-steps=5: FPS: 399 FrameTime: 2.506 ms
=======================================================
glmark2 Score: 421
=======================================================
glmark2的测试并不依赖于前面安装的那些包,即便不安装也可以正常测试。
4.2.5 clinfo
clinfo是一个用于显示OpenCL平台和设备信息的实用程序,由于clinfo依赖ocl-icd-libopencl1,因此如果没安装ocl-icd-libopencl1的话,安装clinfo时会自动安装ocl-icd-libopencl1依赖。
通过clinfo命令可以查看安装的mesa gallium clover OpenCL驱动程序的版本信息;
root@rk3399:/opt# apt install clinfo
root@rk3399:/opt/mesa-22.0.0# clinfo
Number of platforms 1
Platform Name Clover
Platform Vendor Mesa
Platform Version OpenCL 1.1 Mesa 21.2.6
Platform Profile FULL_PROFILE
Platform Extensions cl_khr_icd
Platform Extensions function suffix MESA
Platform Name Clover
Number of devices 0
NULL platform behavior
clGetPlatformInfo(NULL, CL_PLATFORM_NAME, ...) Clover
clGetDeviceIDs(NULL, CL_DEVICE_TYPE_ALL, ...)
clCreateContext(NULL, ...) [default] No devices found in platform
clCreateContextFromType(NULL, CL_DEVICE_TYPE_DEFAULT) No devices found in platform
clCreateContextFromType(NULL, CL_DEVICE_TYPE_CPU) No devices found in platform
clCreateContextFromType(NULL, CL_DEVICE_TYPE_GPU) No devices found in platform
clCreateContextFromType(NULL, CL_DEVICE_TYPE_ACCELERATOR) No devices found in platform
clCreateContextFromType(NULL, CL_DEVICE_TYPE_CUSTOM) No devices found in platform
clCreateContextFromType(NULL, CL_DEVICE_TYPE_ALL) No devices found in platform
ICD loader properties
ICD loader Name OpenCL ICD Loader
ICD loader Vendor OCL Icd free software
ICD loader Version 2.2.11
ICD loader Profile OpenCL 2.1 0
可以看出系统中安装了mesa gallium clover OpenCL ICD驱动程序,但没有找到任何可用的设备,估计是mesa gallium clover平台并不支持ARM Mali T860 GPU设备。
在输出信息的最后,可以看到当前使用的ICD loader名称为OpenCL ICD Loader,厂家为 OCL Icd free software。
4.3 Chromium开启GPU
4.3.1 安装Chromium
运行以下命令以安装Chromium浏览器:
root@rk3399:/opt# apt install dialog
root@rk3399:/opt# apt install chromium-browser
这样,您就成功在ubuntu 20.04上安装了Chromium浏览器。可以在应用程序菜单中搜索并启动Chromium浏览器,或者在终端中运行chromium-browser命令来启动它。
root@rk3399:/opt# export DISPLAY=:0.0; chromium-browser --no-sandbox --user-data-dir
4.3.2 GPU支持情况
安装的Chromium浏览器默认启用硬件加速,支持WebGL,可以通过 输入网址chrome://gpu了解硬件加速情况,如下图所示:
硬件加速:
WebGL:Hardware accelerated;WebGL2:Hardware accelerated。
4.3.3 查看CPU利用率
在Chromium浏览器打开视频,再次查看CPU利用率;

可以看到CPU利用率已经从之前的70%+降低到40%+。
五、编译安装mesa 22.0.0
接下来我们介绍一下mesa的编译安装流程,如果不感兴趣忽略即可。
5.1 安装linux-headers
如果想在开发板上进行编译安装,必须首先安装linux-headers,具体参考:《Rockchip RK3399 - 移植uboot 2017.09 & linux 4.19(友善之家脚本方式)》。如果根文件系统已经安装linux-headers,忽略即可。
5.1.1 编译linux-headers
编译内核头文件:
root@zhengyang:/work/sambashare/rk3399/linux-6.3# make -j8 bindeb-pkg
make bindeb-pkg是一个用于构建debian包的命令,它通常用于编译linux内核并生成对应的debian软件包。
当执行make bindeb-pkg 命令时,它会读取当前目录下的linux内核源代码,并根据配置文件进行内核编译。
编译过程将包括编译内核、生成模块、创建initramfs等步骤。最后,它将生成一组二进制文件和相关的debian控制文件,用于创建 debian包。
linux 6.3执行完成会在内核源码debian目录生成以下文件;
root@zhengyang:/work/sambashare/rk3399/linux-6.3# ll debian/
-rw-r--r-- 1 root root 6 1月 30 23:06 arch
-rw-r--r-- 1 root root 137 1月 30 23:06 changelog
-rw-r--r-- 1 root root 1239 1月 30 23:06 control
-rw-r--r-- 1 root root 691 1月 30 23:06 copyright
-rw-r--r-- 1 root root 269 1月 30 23:12 files
drwxr-xr-x 5 root root 4096 1月 30 23:11 linux-headers/
drwxr-xr-x 7 root root 4096 1月 30 23:11 linux-image/
drwxr-xr-x 4 root root 4096 1月 30 23:11 linux-image-dbg/
drwxr-xr-x 4 root root 4096 1月 30 23:11 linux-libc-dev/
-rwxr-xr-x 1 root root 486 1月 30 23:06 rules*
同时会在内核上一级目录下生成如下deb包:
root@zhengyang:/work/sambashare/rk3399# ll | grep linux
-rw-r--r-- 1 root root 8407716 1月 30 23:11 linux-headers-6.3.0_6.3.0-17_arm64.deb
-rw-r--r-- 1 root root 25455204 1月 30 23:11 linux-image-6.3.0_6.3.0-17_arm64.deb
-rw-r--r-- 1 root root 69655120 1月 30 23:12 linux-image-6.3.0-dbg_6.3.0-17_arm64.deb
-rw-r--r-- 1 root root 1260012 1月 30 23:11 linux-libc-dev_6.3.0-17_arm64.deb
-rw-r--r-- 1 root root 7391 1月 30 23:12 linux-upstream_6.3.0-17_arm64.buildinfo
-rw-r--r-- 1 root root 2161 1月 30 23:12 linux-upstream_6.3.0-17_arm64.changes
其中:
linux-image-<version>.deb:内核镜像文件,用于安装和引导新的内核;linux-headers-<version>.deb:内核头文件,用于开发其他软件或编译内核模块;linux-libc-dev_<version>.deb:用于构建用户空间软件的头文件和静态库;
这些生成的debian包可以在 debian或基于debian的系统上安装和使用。
5.1.2 安装linux-headers
将我们编译的头文件拷贝到开发板/opt目录下;
root@rk3399:~# cd /opt
root@rk3399:/opt# scp root@192.168.0.200:/work/sambashare/rk3399/linux-headers-6.3.0_6.3.0-17_arm64.deb /opt/
root@rk3399:/opt# dpkg -i /opt/linux-headers-*.deb
安装完成后,我们可以看一下/usr/src目录下是否创建了linux-headers-$(uname-r)文件;
root@rk3399:/opt$ ll /usr/src/
drwxr-xr-x 5 root root 4096 Nov 13 00:35 linux-headers-6.3.0
root@rk3399:/opt# ll /usr/src/linux-headers-6.3.0/
-rw-r--r-- 1 root root 264166 Sep 23 20:58 .config
-rw-r--r-- 1 root root 71751 Jun 12 2023 Makefile
-rw-r--r-- 1 root root 1064676 Sep 23 20:58 Module.symvers
drwxr-xr-x 3 root root 4096 Nov 13 00:35 arch/
drwxr-xr-x 33 root root 4096 Nov 13 00:35 include/
drwxr-xr-x 17 root root 12288 Nov 13 00:35 scripts/
5.2 下载mesa
root@rk3399:/opt# wget https://archive.mesa3d.org/mesa-22.0.0.tar.xz
root@rk3399:/opt# tar -xvf mesa-22.0.0.tar.xz
root@rk3399:/opt# cd mesa-22.0.0
5.2.1 升级meson 0.63
root@rk3399:/opt# apt install python3-pip
root@rk3399:/opt# pip3 install meson==0.63
root@rk3399:/opt/mesa-22.0.0# cp /usr/local/bin/meson /usr/bin/
备注:ubuntu 20.04上 使用apt默认安装的版本可能是0.53.2,而meson编译,需要更高的 meson 版本, 大于0.60。
5.2.2 升级cmake 3.28.0
root@rk3399:/opt# apt remove cmake # 移除低版本cmake 3.16.3
root@rk3399:/opt# wget https://521github.com/extdomains/github.com/Kitware/CMake/releases/download/v3.28.0/cmake-3.28.0-linux-aarch64.tar.gz
root@rk3399:/opt# tar -xzvf cmake-3.28.0-linux-aarch64.tar.gz
root@rk3399:/opt# mv cmake-3.28.0-linux-aarch64 cmake-3.28.0
root@rk3399:/opt# ln -sf /opt/cmake-3.28.0/bin/* /usr/bin/
root@rk3399:/opt# cmake --version
cmake version 3.28.0
CMake suite maintained and supported by Kitware (kitware.com/cmake).
root@rk3399:/opt# vim /etc/profile
export PATH=$PATH:/opt/cmake-3.28.0/bin
root@rk3399:/opt# source /etc/profile
5.3 安装依赖
5.3.1 安装glslang 14.0.0
安装glslang:
root@rk3399:/opt# wget https://521github.com/extdomains/github.com/KhronosGroup/glslang/archive/refs/tags/14.0.0.tar.gz
root@rk3399:/opt# tar -xvf 14.0.0.tar.gz
root@rk3399:/opt# cd glslang-14.0.0
root@rk3399:/opt/glslang-14.0.0# ./update_glslang_sources.py # 如果下载慢,github修改镜像
root@rk3399:/opt/glslang-14.0.0# cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="$(pwd)/install" .
root@rk3399:/opt/glslang-14.0.0# make -j4 install
root@rk3399:/opt/glslang-14.0.0# mv install/bin/* /usr/local/bin/
root@rk3399:/opt/glslang-14.0.0# mv install/lib/* /usr/local/lib/
root@rk3399:/opt/glslang-14.0.0# mv install/include/* /usr/local/include/
root@rk3399:/opt/glslang-14.0.0# cd ..
root@rk3399:/opt# rm -rf glslang-14.0.0*
5.3.2 安装libdrm 2.4.118
下载源码:
root@rk3399:/opt# wget https://dri.freedesktop.org/libdrm/libdrm-2.4.118.tar.xz
root@rk3399:/opt# tar -xvf libdrm-2.4.118.tar.xz
root@rk3399:/opt# mv libdrm-2.4.118 drm
在编译和安装libdrm之前,你需要先安装一些依赖项:
root@rk3399:/opt# apt install autoconf libtool pkg-config libpciaccess-dev ninja-build
编译和安装:
root@rk3399:/opt# cd drm
root@rk3399:/opt/drm# meson build
root@rk3399:/opt/drm# ninja -C build install
ninja: Entering directory `build'
[0/1] Installing files.
Installing libdrm.so.2.4.0 to /usr/local/lib/aarch64-linux-gnu
Installing nouveau/libdrm_nouveau.so.2.0.0 to /usr/local/lib/aarch64-linux-gnu
Installing radeon/libdrm_radeon.so.1.0.1 to /usr/local/lib/aarch64-linux-gnu
Installing amdgpu/libdrm_amdgpu.so.1.0.0 to /usr/local/lib/aarch64-linux-gnu
Installing freedreno/libdrm_freedreno.so.1.0.0 to /usr/local/lib/aarch64-linux-gnu
Installing etnaviv/libdrm_etnaviv.so.1.0.0 to /usr/local/lib/aarch64-linux-gnu
Installing /opt/drm/libsync.h to /usr/local/include
Installing /opt/drm/xf86drm.h to /usr/local/include
Installing /opt/drm/xf86drmMode.h to /usr/local/include
Installing /opt/drm/include/drm/drm.h to /usr/local/include/libdrm
Installing /opt/drm/include/drm/drm_fourcc.h to /usr/local/include/libdrm
Installing /opt/drm/include/drm/drm_mode.h to /usr/local/include/libdrm
Installing /opt/drm/include/drm/drm_sarea.h to /usr/local/include/libdrm
Installing /opt/drm/include/drm/i915_drm.h to /usr/local/include/libdrm
Installing /opt/drm/include/drm/mach64_drm.h to /usr/local/include/libdrm
Installing /opt/drm/include/drm/mga_drm.h to /usr/local/include/libdrm
Installing /opt/drm/include/drm/msm_drm.h to /usr/local/include/libdrm
Installing /opt/drm/include/drm/nouveau_drm.h to /usr/local/include/libdrm
Installing /opt/drm/include/drm/qxl_drm.h to /usr/local/include/libdrm
Installing /opt/drm/include/drm/r128_drm.h to /usr/local/include/libdrm
......
root@rk3399:/opt/drm# cd ..
root@rk3399:/opt# rm -rf libdrm-2.4.118.tar.xz
root@rk3399:/opt# rm -rf drm
头文件安装到/usr/local/include/libdrm,库文件安装到/usr/local/lib/aarch64-linux-gnu,这里不要去改动默认路径。
可以使用ldconfig -p | grep libdrm命令来查看系统中是否存在正确的libdrm库;
root@rk3399:/opt/mesa-22.0.0# ldconfig -p | grep libdrm
libdrm_tegra.so.0 (libc6,AArch64) => /lib/aarch64-linux-gnu/libdrm_tegra.so.0
libdrm_tegra.so (libc6,AArch64) => /lib/aarch64-linux-gnu/libdrm_tegra.so
libdrm_radeon.so.1 (libc6,AArch64) => /usr/local/lib/aarch64-linux-gnu/libdrm_radeon.so.1
libdrm_radeon.so.1 (libc6,AArch64) => /lib/aarch64-linux-gnu/libdrm_radeon.so.1
libdrm_radeon.so (libc6,AArch64) => /usr/local/lib/aarch64-linux-gnu/libdrm_radeon.so
libdrm_radeon.so (libc6,AArch64) => /lib/aarch64-linux-gnu/libdrm_radeon.so
libdrm_nouveau.so.2 (libc6,AArch64) => /usr/local/lib/aarch64-linux-gnu/libdrm_nouveau.so.2
libdrm_nouveau.so.2 (libc6,AArch64) => /lib/aarch64-linux-gnu/libdrm_nouveau.so.2
libdrm_nouveau.so (libc6,AArch64) => /usr/local/lib/aarch64-linux-gnu/libdrm_nouveau.so
libdrm_nouveau.so (libc6,AArch64) => /lib/aarch64-linux-gnu/libdrm_nouveau.so
libdrm_freedreno.so.1 (libc6,AArch64) => /usr/local/lib/aarch64-linux-gnu/libdrm_freedreno.so.1
libdrm_freedreno.so.1 (libc6,AArch64) => /lib/aarch64-linux-gnu/libdrm_freedreno.so.1
libdrm_freedreno.so (libc6,AArch64) => /usr/local/lib/aarch64-linux-gnu/libdrm_freedreno.so
libdrm_freedreno.so (libc6,AArch64) => /lib/aarch64-linux-gnu/libdrm_freedreno.so
libdrm_etnaviv.so.1 (libc6,AArch64) => /lib/aarch64-linux-gnu/libdrm_etnaviv.so.1
libdrm_etnaviv.so (libc6,AArch64) => /lib/aarch64-linux-gnu/libdrm_etnaviv.so
libdrm_amdgpu.so.1 (libc6,AArch64) => /usr/local/lib/aarch64-linux-gnu/libdrm_amdgpu.so.1
libdrm_amdgpu.so.1 (libc6,AArch64) => /lib/aarch64-linux-gnu/libdrm_amdgpu.so.1
libdrm_amdgpu.so (libc6,AArch64) => /usr/local/lib/aarch64-linux-gnu/libdrm_amdgpu.so
libdrm_amdgpu.so (libc6,AArch64) => /lib/aarch64-linux-gnu/libdrm_amdgpu.so
libdrm.so.2 (libc6,AArch64) => /usr/local/lib/aarch64-linux-gnu/libdrm.so.2
libdrm.so.2 (libc6,AArch64) => /lib/aarch64-linux-gnu/libdrm.so.2
libdrm.so (libc6,AArch64) => /usr/local/lib/aarch64-linux-gnu/libdrm.so
libdrm.so (libc6,AArch64) => /lib/aarch64-linux-gnu/libdrm.so
5.3.3 安装llvm 11和clang 11
root@rk3399:/opt# apt install llvm-11 clang-11
root@rk3399:/opt# cd /usr/bin
root@rk3399:/usr/bin# rm -rf /usr/bin/llvm-config
root@rk3399:/usr/bin# ln -s ../lib/llvm-11/bin/llvm-config /usr/bin/llvm-config
root@rk3399:/usr/bin# ls -l /usr/bin/llvm-config*
lrwxrwxrwx 1 root root 30 Jan 20 17:24 /usr/bin/llvm-config -> ../lib/llvm-11/bin/llvm-config
lrwxrwxrwx 1 root root 30 Apr 20 2020 /usr/bin/llvm-config-10 -> ../lib/llvm-10/bin/llvm-config
lrwxrwxrwx 1 root root 30 Oct 30 2020 /usr/bin/llvm-config-11 -> ../lib/llvm-11/bin/llvm-config
lrwxrwxrwx 1 root root 29 Mar 19 2020 /usr/bin/llvm-config-8 -> ../lib/llvm-8/bin/llvm-config
root@rk3399:/usr/bin# llvm-config --version
11.0.0
root@rk3399:/usr/bin# llvm-config --libdir
/usr/lib/llvm-11/lib
5.3.4 安装其它依赖
如果后面在编译mesa过程中缺少其它依赖,自己补充:
root@rk3399:/opt# apt build-dep mesa
5.4 编译安装mesa
编译mesa流程来自官网:Compilation and Installation Using Meson。
5.4.1 配置
执行如下命令在builddir目录中进行meson初始化和配置。它将读取项目源代码,并生成构建文件;
root@rk3399:/opt/mesa-22.0.0# meson -Dplatforms=x11 -Dvulkan-drivers=panfrost -Dgallium-drivers=panfrost -Dgallium-opencl=icd -Dlibunwind=disabled -Dprefix=/usr builddir/
The Meson build system
Version: 0.63.0
Source dir: /opt/mesa-22.0.0
Build dir: /opt/mesa-22.0.0/builddir
Build type: native build
Program python3 found: YES (/usr/bin/python3)
Project name: mesa
Project version: 22.0.0
......
Message: Configuration summary:
prefix: /usr
libdir: lib/aarch64-linux-gnu
includedir: include
OpenGL: yes (ES1: yes ES2: yes)
OSMesa: no
DRI platform: drm
DRI drivers: no
DRI driver dir: /usr/lib/aarch64-linux-gnu/dri
GLX: DRI-based
EGL: yes
EGL drivers: builtin:egl_dri2 builtin:egl_dri3
EGL/Vulkan/VL platforms: x11 surfaceless drm xcb
GBM: yes
GBM backends path: /usr/lib/aarch64-linux-gnu/gbm
Vulkan drivers: panfrost
Vulkan ICD dir: share/vulkan/icd.d
llvm: yes
llvm-version: 11.0.0
Gallium drivers: panfrost
Gallium st: mesa gallium clover
HUD lmsensors: no
Shared-glapi: yes
Perfetto: no
Perfetto ds: auto
Build targets in project: 178
NOTICE: Future-deprecated features used:
* 0.55.0: {'ExternalProgram.path'}
* 0.56.0: {'meson.source_root'}
mesa 22.0.0
User defined options
prefix : /usr
gallium-drivers: panfrost
gallium-opencl : icd
libunwind : disabled
platforms : x11
vulkan-drivers : panfrost
其中:
-Dplatforms=x11:window systems to support. If this is set toauto, all platforms applicable will be enabled;-Dvulkan-drivers=panfrost:List of vulkan drivers to build. If this is set to auto all drivers applicable to the target OS/architecture will be built;-Dgallium-drivers=panfrost:List of gallium drivers to build. If this is set to auto all drivers applicable to the target OS/architecture will be built;-Dgallium-opencl=icd:build gallium "clover" OpenCL frontend;-Dlibunwind=false:禁用libunwind来获取堆栈跟踪信息;-Dprefix=/usr:指定安装目录;如果不指定,默认安装到/usr;
更多配置选项可以参考当前目录下meson_options.txt文件,或者通过meson configure builddir/查看选项配置值;
5.4.2 编译
编译项目,大概需要花费30分钟;
root@rk3399:/opt/mesa-22.0.0# ninja -C builddir/ -j6
5.4.3 安装
最后一步进行安装;
root@rk3399:/opt/mesa-22.0.0# ninja -C builddir/ install
ninja: Entering directory `builddir/'
[1/2] Installing files.
# OpenGL、OpenGL ES、OpenCL等库文件
Installing src/mapi/shared-glapi/libglapi.so.0.0.0 to /usr/lib/aarch64-linux-gnu
Installing src/mapi/es1api/libGLESv1_CM.so.1.1.0 to /usr/lib/aarch64-linux-gnu
Installing src/mapi/es2api/libGLESv2.so.2.0.0 to /usr/lib/aarch64-linux-gnu
Installing src/panfrost/vulkan/libvulkan_panfrost.so to /usr/lib/aarch64-linux-gnu
Installing src/panfrost/vulkan/panfrost_icd.aarch64.json to /usr/share/vulkan/icd.d
Installing src/gbm/libgbm.so.1.0.0 to /usr/lib/aarch64-linux-gnu
Installing src/gallium/targets/pipe-loader/pipe_kmsro.so to /usr/lib/aarch64-linux-gnu/gallium-pipe
Installing src/gallium/targets/opencl/libMesaOpenCL.so.1.0.0 to /usr/lib/aarch64-linux-gnu
Installing src/gallium/targets/dri/libgallium_dri.so to /usr/lib/aarch64-linux-gnu/dri
Installing src/glx/libGL.so.1.2.0 to /usr/lib/aarch64-linux-gnu
Installing src/egl/libEGL.so.1.0.0 to /usr/lib/aarch64-linux-gnu
# 头文件
Installing /opt/mesa-22.0.0/include/KHR/khrplatform.h to /usr/include/KHR
Installing /opt/mesa-22.0.0/include/GLES/egl.h to /usr/include/GLES
Installing /opt/mesa-22.0.0/include/GLES/gl.h to /usr/include/GLES
Installing /opt/mesa-22.0.0/include/GLES/glext.h to /usr/include/GLES
Installing /opt/mesa-22.0.0/include/GLES/glplatform.h to /usr/include/GLES
Installing /opt/mesa-22.0.0/include/GLES2/gl2.h to /usr/include/GLES2
Installing /opt/mesa-22.0.0/include/GLES2/gl2ext.h to /usr/include/GLES2
Installing /opt/mesa-22.0.0/include/GLES2/gl2platform.h to /usr/include/GLES2
Installing /opt/mesa-22.0.0/include/GLES3/gl3.h to /usr/include/GLES3
Installing /opt/mesa-22.0.0/include/GLES3/gl31.h to /usr/include/GLES3
Installing /opt/mesa-22.0.0/include/GLES3/gl32.h to /usr/include/GLES3
Installing /opt/mesa-22.0.0/include/GLES3/gl3ext.h to /usr/include/GLES3
Installing /opt/mesa-22.0.0/include/GLES3/gl3platform.h to /usr/include/GLES3
Installing /opt/mesa-22.0.0/include/GL/gl.h to /usr/include/GL
Installing /opt/mesa-22.0.0/include/GL/glcorearb.h to /usr/include/GL
Installing /opt/mesa-22.0.0/include/GL/glext.h to /usr/include/GL
Installing /opt/mesa-22.0.0/include/GL/glx.h to /usr/include/GL
Installing /opt/mesa-22.0.0/include/GL/glxext.h to /usr/include/GL
Installing /opt/mesa-22.0.0/include/EGL/egl.h to /usr/include/EGL
Installing /opt/mesa-22.0.0/include/EGL/eglext.h to /usr/include/EGL
Installing /opt/mesa-22.0.0/include/EGL/eglplatform.h to /usr/include/EGL
Installing /opt/mesa-22.0.0/include/EGL/eglmesaext.h to /usr/include/EGL/
Installing /opt/mesa-22.0.0/include/EGL/eglextchromium.h to /usr/include/EGL/
Installing /opt/mesa-22.0.0/include/GL/internal/dri_interface.h to /usr/include/GL/internal
Installing /opt/mesa-22.0.0/src/gbm/main/gbm.h to /usr/include/
Installing /opt/mesa-22.0.0/src/util/00-mesa-defaults.conf to /usr/share/drirc.d
Installing /opt/mesa-22.0.0/builddir/meson-private/glesv1_cm.pc to /usr/lib/aarch64-linux-gnu/pkgconfig
Installing /opt/mesa-22.0.0/builddir/meson-private/glesv2.pc to /usr/lib/aarch64-linux-gnu/pkgconfig
Installing /opt/mesa-22.0.0/builddir/meson-private/gbm.pc to /usr/lib/aarch64-linux-gnu/pkgconfig
# ICD定义文件
Installing /opt/mesa-22.0.0/builddir/src/gallium/targets/opencl/mesa.icd to /etc/OpenCL/vendors
Installing /opt/mesa-22.0.0/builddir/meson-private/dri.pc to /usr/lib/aarch64-linux-gnu/pkgconfig
Installing /opt/mesa-22.0.0/builddir/meson-private/egl.pc to /usr/lib/aarch64-linux-gnu/pkgconfig
Installing /opt/mesa-22.0.0/builddir/meson-private/gl.pc to /usr/lib/aarch64-linux-gnu/pkgconfig
# OpenGL、OpenGL ES、OpenCL等库文件链接文件创建
Installing symlink pointing to libglapi.so.0.0.0 to /usr/lib/aarch64-linux-gnu/libglapi.so.0
Installing symlink pointing to libglapi.so.0 to /usr/lib/aarch64-linux-gnu/libglapi.so
Installing symlink pointing to libGLESv1_CM.so.1.1.0 to /usr/lib/aarch64-linux-gnu/libGLESv1_CM.so.1
Installing symlink pointing to libGLESv1_CM.so.1 to /usr/lib/aarch64-linux-gnu/libGLESv1_CM.so
Installing symlink pointing to libGLESv2.so.2.0.0 to /usr/lib/aarch64-linux-gnu/libGLESv2.so.2
Installing symlink pointing to libGLESv2.so.2 to /usr/lib/aarch64-linux-gnu/libGLESv2.so
Installing symlink pointing to libgbm.so.1.0.0 to /usr/lib/aarch64-linux-gnu/libgbm.so.1
Installing symlink pointing to libgbm.so.1 to /usr/lib/aarch64-linux-gnu/libgbm.so
Installing symlink pointing to libMesaOpenCL.so.1.0.0 to /usr/lib/aarch64-linux-gnu/libMesaOpenCL.so.1
Installing symlink pointing to libMesaOpenCL.so.1 to /usr/lib/aarch64-linux-gnu/libMesaOpenCL.so
Installing symlink pointing to libGL.so.1.2.0 to /usr/lib/aarch64-linux-gnu/libGL.so.1
Installing symlink pointing to libGL.so.1 to /usr/lib/aarch64-linux-gnu/libGL.so
Installing symlink pointing to libEGL.so.1.0.0 to /usr/lib/aarch64-linux-gnu/libEGL.so.1
Installing symlink pointing to libEGL.so.1 to /usr/lib/aarch64-linux-gnu/libEGL.so
Running custom install script '/usr/bin/python3 /opt/mesa-22.0.0/bin/install_megadrivers.py /opt/mesa-22.0.0/builddir/src/gallium/targets/dri/libgallium_dri.so /usr/lib/aarch64-linux-gnu/dri armada-drm_dri.so exynos_dri.so hx8357d_dri.so ili9225_dri.so ili9341_dri.so imx-drm_dri.so imx-dcss_dri.so ingenic-drm_dri.so kirin_dri.so komeda_dri.so mali-dp_dri.so mcde_dri.so mediatek_dri.so meson_dri.so mi0283qt_dri.so mxsfb-drm_dri.so pl111_dri.so rcar-du_dri.so repaper_dri.so rockchip_dri.so st7586_dri.so st7735r_dri.so stm_dri.so sun4i-drm_dri.so panfrost_dri.so'
安装完成后,会将EGL、GL、GLES、GLES2、GLES3等头文件安装到/usr/include目录;
同时将OpenGL、EGL、OpenCL、OpenGL ES、dri等库安装到/usr/lib/aarch64-linux-gnu目录。
为了方便查看源码编译安装了哪些文件,我修改-Dprefix=/opt/mesa,重新完成之后,查看安装目录:
root@rk3399:/opt/mesa-22.0.0# meson configure builddir/ -Dprefix=/opt/mesa
root@rk3399:/opt/mesa-22.0.0# ninja -C builddir/ install
root@rk3399:/opt/mesa-22.0.0# ll /opt/mesa
drwxr-xr-x 3 root root 4096 Jan 20 20:29 etc/
drwxr-xr-x 8 root root 4096 Jan 20 20:29 include/
drwxr-xr-x 3 root root 4096 Jan 20 20:29 lib/
drwxr-xr-x 4 root root 4096 Jan 20 20:29 share/
root@rk3399:/opt/mesa-22.0.0# ll /opt/mesa/include # 头文件
├── EGL
│ ├── egl.h
│ ├── eglext.h
│ ├── eglextchromium.h
│ ├── eglmesaext.h
│ ├── eglplatform.h
├── GL
│ ├── gl.h
│ ├── glcorearb.h
│ ├── glext.h
│ ├── glx.h
│ ├── glxext.h
│ ├── internal
│ ├── dri_interface.h
├── GLES
│ ├── egl.h
│ ├── gl.h
│ ├── glext.h
│ ├── glplatform.h
├── GLES2
│ ├── gl2.h
│ ├── gl2ext.h
│ ├── gl2platform.h
├── GLES3
│ ├── gl3.h
│ ├── gl31.h
│ ├── gl32.h
│ ├── gl3ext.h
│ ├── gl3platform.h
├── KHR
│ ├── khrplatform.h
gbm.h
root@rk3399:/opt/mesa-22.0.0# ll /opt/mesa/lib # 库文件
drwxr-xr-x 5 root root 4096 Jan 20 20:29 aarch64-linux-gnu/
root@rk3399:/opt/mesa-22.0.0# ll /opt/mesa/lib/aarch64-linux-gnu
├── dri
│ ├── armada-drm_dri.so
│ ├── exynos_dri.so
│ ├── hx8357d_dri.so
│ ├── ili9225_dri.so
│ ├── ili9341_dri.so
│ ├── imx-dcss_dri.so
│ ├── imx-drm_dri.so
│ ├── ingenic-drm_dri.so
│ ├── kirin_dri.so
│ ├── komeda_dri.so
│ ├── mali-dp_dri.so
│ ├── mcde_dri.so
│ ├── mediatek_dri.so
│ ├── meson_dri.so
│ ├── mi0283qt_dri.so
│ ├── mxsfb-drm_dri.so
│ ├── panfrost_dri.so
│ ├── pl111_dri.so
│ ├── rcar-du_dri.so
│ ├── repaper_dri.so
│ ├── rockchip_dri.so
│ ├── st7586_dri.so
│ ├── st7735r_dri.so
│ ├── stm_dri.so
│ ├── sun4i-drm_dri.so
├── libEGL.so -> libEGL.so.1
├── libEGL.so.1 -> libEGL.so.1.0.0
├── libEGL.so.1.0.0
├── libGL.so -> libGL.so.1
├── libGL.so.1 -> libGL.so.1.2.0
├── libGL.so.1.2.0
├── libGLESv1_CM.so -> libGLESv1_CM.so.1
├── libGLESv1_CM.so.1 -> libGLESv1_CM.so.1.1.0
├── libGLESv1_CM.so.1.1.0
├── libGLESv2.so -> libGLESv2.so.2
├── libGLESv2.so.2 -> libGLESv2.so.2.0.0
├── libGLESv2.so.2.0.0
├── libMesaOpenCL.so -> libMesaOpenCL.so.1
├── libMesaOpenCL.so.1 -> libMesaOpenCL.so.1.0.0
├── libMesaOpenCL.so.1.0.0
├── libgbm.so -> libgbm.so.1
├── libgbm.so.1 -> libgbm.so.1.0.0
├── libgbm.so.1.0.0
├── libglapi.so -> libglapi.so.0
├── libglapi.so.0 -> libglapi.so.0.0.0
├── libglapi.so.0.0.0
├── libvulkan_panfrost.so
└── pkgconfig
这里dri目录下的内容是和平台相关的,比如:
ili9225是intel的;panfrost是mali的;
如果我们自己观察dri目录各个文件的大小,我们很容易发现,这些文件的大小是相同的,这主要是因为它们都是由/opt/mesa-22.0.0/builddir/src/gallium/targets/dri/libgallium_dri.so复制而来,具体实现位于install_megadrivers.py脚本中;
'/usr/bin/python3 /opt/mesa-22.0.0/bin/install_megadrivers.py /opt/mesa-22.0.0/builddir/src/gallium/targets/dri/libgallium_dri.so /opt/mesa/lib/aarch64-linux-gnu/dri armada-drm_dri.so exynos_dri.so hx8357d_dri.so ili9225_dri.so ili9341_dri.so imx-drm_dri.so imx-dcss_dri.so ingenic-drm_dri.so kirin_dri.so komeda_dri.so mali-dp_dri.so mcde_dri.so mediatek_dri.so meson_dri.so mi0283qt_dri.so mxsfb-drm_dri.so pl111_dri.so rcar-du_dri.so repaper_dri.so rockchip_dri.so st7586_dri.so st7735r_dri.so stm_dri.so sun4i-drm_dri.so panfrost_dri.so'
5.4.4 glxinfo
使用glxinfo测试:
root@rk3399:/opt# export DISPLAY=:0.0; glxinfo -B
name of display: :0.0
display: :0 screen: 0
direct rendering: Yes
Extended renderer info (GLX_MESA_query_renderer):
Vendor: Panfrost (0xffffffff)
Device: Mali-T860 (Panfrost) (0xffffffff)
Version: 22.0.0
Accelerated: yes
Video memory: 3851MB
Unified memory: yes
Preferred profile: core (0x1)
Max core profile version: 3.1
Max compat profile version: 3.1
Max GLES1 profile version: 1.1
Max GLES[23] profile version: 3.1
OpenGL vendor string: Panfrost
OpenGL renderer string: Mali-T860 (Panfrost)
OpenGL core profile version string: 3.1 Mesa 22.0.0
OpenGL core profile shading language version string: 1.40
OpenGL core profile context flags: (none)
OpenGL version string: 3.1 Mesa 22.0.0
OpenGL shading language version string: 1.40
OpenGL context flags: (none)
OpenGL ES profile version string: OpenGL ES 3.1 Mesa 22.0.0
OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.10
可以看到Device:Mali-T860 (Panfrost)、OpenGL version string: 3.1 Mesa 22.0.0。
六、编译安装OpenCL ICD Loader
在编译安装mesa小节,我们配置了:
-Dgallium-opencl=icd:build gallium "clover" OpenCL frontend;
因此在执行编译安装操作时,会将mesa gallium clover OpenCL ICD库(libMesaOpenCL.so相关库)安装到/usr/lib/aarch64-linux-gnu/目录下:
root@rk3399:/opt/mesa-22.0.0# ll /usr/lib/aarch64-linux-gnu/libMesaOpenCL.so*
lrwxrwxrwx 1 root root 18 Jan 24 21:44 /usr/lib/aarch64-linux-gnu/libMesaOpenCL.so -> libMesaOpenCL.so.1*
lrwxrwxrwx 1 root root 22 Jan 24 21:44 /usr/lib/aarch64-linux-gnu/libMesaOpenCL.so.1 -> libMesaOpenCL.so.1.0.0*
-rwxr-xr-x 1 root root 37367880 Jan 24 21:44 /usr/lib/aarch64-linux-gnu/libMesaOpenCL.so.1.0.0*
但是缺了OpenCL ICD Loader Library,不过我们可以通过编译Khronos Group的OpenCL SDK得到。
6.1 OpenCL SDK编译安装
6.1.1 源码下载
下载源码:
root@rk3399:/opt# git clone https://521github.com/KhronosGroup/OpenCL-SDK.git
root@rk3399:/opt# cd OpenCL-SDK/
对于子模块,可以先不要在git clone的时候加上--recursive,等主体部分下载完之后,该文件夹中有个隐藏文件称为:.gitmodules,把子项目中的url地址同样替换为:https://521github.com前缀;
root@rk3399:/opt/OpenCL-SDK# vim ./.gitmodules # 替换路径
然后利用git submodule sync更新子项目对应的url,最后再git submodule update --init --recursive,即可正常网速clone完所有子项目;
root@rk3399:/opt/OpenCL-SDK# git submodule sync
root@rk3399:/opt/OpenCL-SDK# git submodule update --init --recursive
接着重复上面操作:
root@rk3399:/opt/OpenCL-SDK# vim external/OpenCL-CLHPP/.gitmodules # 替换路径
root@rk3399:/opt/OpenCL-SDK# vim external/OpenCL-CLHPP/external/CMock/.gitmodules # 替换路径
或者尝试:
root@rk3399:/opt/OpenCL-SDK# find . -type f -exec sed -i 's/\/\/github/\/\/521github/g' {} +
root@rk3399:/opt/OpenCL-SDK# git submodule sync
root@rk3399:/opt/OpenCL-SDK# git submodule update --init --recursive
6.1.2 配置
运行以下命令来配置构建过程,并指定安装路径为/opt/OpenCL:
root@rk3399:/opt/OpenCL-SDK# cmake -S . -B build -DCMAKE_INSTALL_PREFIX=/usr
其中:
-S .:指定源代码目录的路径;-B build:指定构建目录的路径;-DCMAKE_INSTALL_PREFIX=/usr:指定cmake执行install目标时,安装的路径前缀;
我安装时遇到了GLU、doxygen、Freetype、X11_X11_LIB等找不到的错误,需要手动安装:
root@rk3399:/opt/OpenCL-SDK# apt install libglu1-mesa-dev libglew-dev doxygen libfreetype6-dev xorg-dev libudev-dev
6.1.3 编译安装
接着运行以下命令在./build目录下执行构建操作,只构建install目标,将生成的文件安装到指定的位置;
root@rk3399:/opt/OpenCL-SDK# cmake --build build --target install -j4
执行完成后在/usr/lib/aarch64-linux-gnu/目录下安装如下库:
root@rk3399:/opt/OpenCL-SDK# ls -l /usr/lib/aarch64-linux-gnu/libOpenCL*
lrwxrwxrwx 1 root root 14 Jan 24 22:15 /usr/lib/aarch64-linux-gnu/libOpenCL.so -> libOpenCL.so.1
lrwxrwxrwx 1 root root 16 Jan 24 22:15 /usr/lib/aarch64-linux-gnu/libOpenCL.so.1 -> libOpenCL.so.1.2
-rw-r--r-- 1 root root 74920 Jan 24 22:09 /usr/lib/aarch64-linux-gnu/libOpenCL.so.1.2
-rw-r--r-- 1 root root 99598 Jan 24 22:09 /usr/lib/aarch64-linux-gnu/libOpenCLExt.a
-rw-r--r-- 1 root root 213328 Jan 24 22:10 /usr/lib/aarch64-linux-gnu/libOpenCLSDK.so
-rw-r--r-- 1 root root 329440 Jan 24 22:12 /usr/lib/aarch64-linux-gnu/libOpenCLSDKCpp.so
-rw-r--r-- 1 root root 27296 Jan 24 22:09 /usr/lib/aarch64-linux-gnu/libOpenCLUtils.so
-rw-r--r-- 1 root root 61584 Jan 24 22:09 /usr/lib/aarch64-linux-gnu/libOpenCLUtilsCpp.so
同时在/usr/include/下安装头文件:
root@rk3399:/opt/OpenCL-SDK# ll /usr/include/CL
total 804
drwxr-xr-x 3 root root 4096 Jan 24 22:19 ./
drwxr-xr-x 71 root root 12288 Jan 24 22:19 ../
drwxr-xr-x 2 root root 4096 Jan 24 22:19 Utils/
-rw-r--r-- 1 root root 81631 Jan 18 00:42 cl.h
-rw-r--r-- 1 root root 786 Jan 18 00:42 cl2.hpp
-rw-r--r-- 1 root root 8057 Jan 18 00:42 cl_d3d10.h
-rw-r--r-- 1 root root 8095 Jan 18 00:42 cl_d3d11.h
-rw-r--r-- 1 root root 12246 Jan 18 00:42 cl_dx9_media_sharing.h
-rw-r--r-- 1 root root 959 Jan 18 00:42 cl_dx9_media_sharing_intel.h
-rw-r--r-- 1 root root 5672 Jan 18 00:42 cl_egl.h
-rw-r--r-- 1 root root 127490 Jan 18 00:42 cl_ext.h
-rw-r--r-- 1 root root 902 Jan 18 00:42 cl_ext_intel.h
-rw-r--r-- 1 root root 33387 Jan 18 00:42 cl_function_types.h
-rw-r--r-- 1 root root 12040 Jan 18 00:42 cl_gl.h
-rw-r--r-- 1 root root 905 Jan 18 00:42 cl_gl_ext.h
-rw-r--r-- 1 root root 10430 Jan 18 00:42 cl_half.h
-rw-r--r-- 1 root root 11505 Jan 18 00:42 cl_icd.h
-rw-r--r-- 1 root root 3544 Jan 18 00:42 cl_layer.h
-rw-r--r-- 1 root root 43430 Jan 18 00:42 cl_platform.h
-rw-r--r-- 1 root root 7090 Jan 18 00:42 cl_va_api_media_sharing_intel.h
-rw-r--r-- 1 root root 3125 Jan 18 00:42 cl_version.h
-rw-r--r-- 1 root root 970 Jan 18 00:42 opencl.h
-rw-r--r-- 1 root root 396735 Jan 18 00:42 opencl.hpp
为了方便查看源码编译安装了哪些文件,我修改-DCMAKE_INSTALL_PREFIX=/opt/OpenCL,编译完成之后,查看安装目录:
root@rk3399:/opt/OpenCL-SDK# ls /opt/OpenCL -l
drwxr-xr-x 2 root root 4096 1月 16 20:44 bin
drwxr-xr-x 5 root root 4096 1月 16 20:44 include # 头文件
drwxr-xr-x 4 root root 4096 1月 16 20:44 lib # 库文件
drwxr-xr-x 5 root root 4096 1月 16 20:44 share
root@rk3399:/opt/OpenCL-SDK# ls -l /opt/OpenCL/lib
drwxr-xr-x 3 root root 4096 Jan 18 01:02 cmake
lrwxrwxrwx 1 root root 14 Jan 18 01:02 libOpenCL.so -> libOpenCL.so.1
lrwxrwxrwx 1 root root 16 Jan 18 01:02 libOpenCL.so.1 -> libOpenCL.so.1.2
-rw-r--r-- 1 root root 74920 Jan 18 00:51 libOpenCL.so.1.2
-rw-r--r-- 1 root root 99598 Jan 18 00:58 libOpenCLExt.a
-rw-r--r-- 1 root root 213304 Jan 18 01:00 libOpenCLSDK.so
-rw-r--r-- 1 root root 329440 Jan 18 01:00 libOpenCLSDKCpp.so
-rw-r--r-- 1 root root 27296 Jan 18 00:57 libOpenCLUtils.so
-rw-r--r-- 1 root root 61584 Jan 18 00:57 libOpenCLUtilsCpp.so
-rw-r--r-- 1 root root 12920 Jan 18 00:52 libcargs.so
lrwxrwxrwx 1 root root 23 Jan 18 01:02 libsfml-graphics.so -> libsfml-graphics.so.2.5
lrwxrwxrwx 1 root root 25 Jan 18 01:02 libsfml-graphics.so.2.5 -> libsfml-graphics.so.2.5.1
-rw-r--r-- 1 root root 473960 Jan 18 00:57 libsfml-graphics.so.2.5.1
lrwxrwxrwx 1 root root 21 Jan 18 01:02 libsfml-system.so -> libsfml-system.so.2.5
lrwxrwxrwx 1 root root 23 Jan 18 01:02 libsfml-system.so.2.5 -> libsfml-system.so.2.5.1
-rw-r--r-- 1 root root 67440 Jan 18 00:53 libsfml-system.so.2.5.1
lrwxrwxrwx 1 root root 21 Jan 18 01:02 libsfml-window.so -> libsfml-window.so.2.5
lrwxrwxrwx 1 root root 23 Jan 18 01:02 libsfml-window.so.2.5 -> libsfml-window.so.2.5.1
-rw-r--r-- 1 root root 207536 Jan 18 00:55 libsfml-window.so.2.5.1
drwxr-xr-x 2 root root 4096 Jan 18 01:02 pkgconfig
root@rk3399:/opt/OpenCL-SDK# ls -l /opt/OpenCL/include/
drwxr-xr-x 3 root root 4096 Jan 18 01:02 CL
drwxr-xr-x 7 root root 4096 Jan 18 01:02 SFML
-rw-r--r-- 1 root root 4553 Jan 18 00:36 cargs.h
root@rk3399:/opt/OpenCL-SDK# ls -l /opt/OpenCL/include/CL/
drwxr-xr-x 2 root root 4096 Jan 18 01:02 Utils
-rw-r--r-- 1 root root 81631 Jan 18 00:42 cl.h
-rw-r--r-- 1 root root 786 Jan 18 00:42 cl2.hpp
-rw-r--r-- 1 root root 8057 Jan 18 00:42 cl_d3d10.h
-rw-r--r-- 1 root root 8095 Jan 18 00:42 cl_d3d11.h
-rw-r--r-- 1 root root 12246 Jan 18 00:42 cl_dx9_media_sharing.h
-rw-r--r-- 1 root root 959 Jan 18 00:42 cl_dx9_media_sharing_intel.h
-rw-r--r-- 1 root root 5672 Jan 18 00:42 cl_egl.h
-rw-r--r-- 1 root root 127490 Jan 18 00:42 cl_ext.h
-rw-r--r-- 1 root root 902 Jan 18 00:42 cl_ext_intel.h
-rw-r--r-- 1 root root 33387 Jan 18 00:42 cl_function_types.h
-rw-r--r-- 1 root root 12040 Jan 18 00:42 cl_gl.h
-rw-r--r-- 1 root root 905 Jan 18 00:42 cl_gl_ext.h
-rw-r--r-- 1 root root 10430 Jan 18 00:42 cl_half.h
-rw-r--r-- 1 root root 11505 Jan 18 00:42 cl_icd.h
-rw-r--r-- 1 root root 3544 Jan 18 00:42 cl_layer.h
-rw-r--r-- 1 root root 43430 Jan 18 00:42 cl_platform.h
-rw-r--r-- 1 root root 7090 Jan 18 00:42 cl_va_api_media_sharing_intel.h
-rw-r--r-- 1 root root 3125 Jan 18 00:42 cl_version.h
-rw-r--r-- 1 root root 970 Jan 18 00:42 opencl.h
-rw-r--r-- 1 root root 396735 Jan 18 00:42 opencl.hpp
6.1.4 clinfo
root@rk3399:/opt/OpenCL-SDK# apt install clinfo
root@rk3399:/opt/OpenCL-SDK# clinfo
Number of platforms 1
Platform Name Clover
Platform Vendor Mesa
Platform Version OpenCL 1.1 Mesa 22.0.0
Platform Profile FULL_PROFILE
Platform Extensions cl_khr_icd
Platform Extensions function suffix MESA
Platform Name Clover
Number of devices 0
NULL platform behavior
clGetPlatformInfo(NULL, CL_PLATFORM_NAME, ...) No platform
clGetDeviceIDs(NULL, CL_DEVICE_TYPE_ALL, ...) No platform
clCreateContext(NULL, ...) [default] No platform
clCreateContext(NULL, ...) [other] No platform
clCreateContextFromType(NULL, CL_DEVICE_TYPE_DEFAULT) No devices found in platform
clCreateContextFromType(NULL, CL_DEVICE_TYPE_CPU) No devices found in platform
clCreateContextFromType(NULL, CL_DEVICE_TYPE_GPU) No devices found in platform
clCreateContextFromType(NULL, CL_DEVICE_TYPE_ACCELERATOR) No devices found in platform
clCreateContextFromType(NULL, CL_DEVICE_TYPE_CUSTOM) No devices found in platform
clCreateContextFromType(NULL, CL_DEVICE_TYPE_ALL) No devices found in platform
ICD loader properties
ICD loader Name Khronos OpenCL ICD Loader
ICD loader Vendor Khronos Group
ICD loader Version 3.0.6
ICD loader Profile OpenCL 3.0
NOTE: your OpenCL library declares to support OpenCL 3.0,
but it seems to support up to OpenCL 2.2 only.
可以看出系统中安装了mesa gallium clover OpenCL ICD驱动程序,但没有找到任何可用的设备,估计是mesa gallium clover平台并不支持ARM Mali T860 GPU设备。
在输出信息的最后,可以看到当前使用的ICD loader名称为Khronos OpenCL ICD Loader,厂家为 Khronos Group。
6.2 OpenCL测试
此时已经有动态库和头文件,可以进行测试了。在/opt/目录下创建opencl-project文件夹;
root@rk3399:/opt# mkdir opencl-project
接着创建platform文件夹;
root@rk3399:/opt# cd opencl-project/
root@rk3399:/opt/opencl-project# mkdir platform
root@rk3399:/opt/opencl-project# cd platform
6.2.1 platform.cpp
在/opt/opencl-project/platform目录下编写测试代码platform.cpp;
#include <stdio.h>
#include <stdlib.h>
#include <CL/cl.h>
#define MAX_PLATFORMS 10
#define MAX_DEVICES 10
int main() {
cl_platform_id platforms[MAX_PLATFORMS];
cl_device_id devices[MAX_DEVICES];
cl_uint num_platforms, num_devices;
cl_context context;
cl_command_queue command_queue;
cl_program program;
cl_kernel kernel;
cl_int ret;
// 获取平台数量
ret = clGetPlatformIDs(MAX_PLATFORMS, platforms, &num_platforms);
if (ret != CL_SUCCESS) {
printf("Failed to get platform IDs\n");
return -1;
}
printf("Number of platforms: %u\n", num_platforms);
// 遍历打印平台信息
for (cl_uint i = 0; i < num_platforms; i++) {
char platform_name[128];
char platform_vendor[128];
ret = clGetPlatformInfo(platforms[i], CL_PLATFORM_NAME, sizeof(platform_name), platform_name, NULL);
if (ret != CL_SUCCESS) {
printf("Failed to get platform name for platform %u\n", i);
}
ret = clGetPlatformInfo(platforms[i], CL_PLATFORM_VENDOR, sizeof(platform_vendor), platform_vendor, NULL);
if (ret != CL_SUCCESS) {
printf("Failed to get platform vendor for platform %u\n", i);
}
printf("Platform %u:\n", i);
printf(" Name: %s\n", platform_name);
printf(" Vendor: %s\n", platform_vendor);
printf("\n");
}
// 获取设备数量
ret = clGetDeviceIDs(platforms[0], CL_DEVICE_TYPE_GPU, MAX_DEVICES, devices, &num_devices);
if (ret != CL_SUCCESS) {
printf("Failed to get device IDs\n");
return -1;
}
// 创建OpenCL上下文
context = clCreateContext(NULL, num_devices, devices, NULL, NULL, &ret);
if (ret != CL_SUCCESS) {
printf("Failed to create context\n");
return -1;
}
// 创建命令队列
command_queue = clCreateCommandQueue(context, devices[0], 0, &ret);
if (ret != CL_SUCCESS) {
printf("Failed to create command queue\n");
return -1;
}
// 定义和构建OpenCL内核
const char *kernel_source = "__kernel void hello_world() {\n"
" printf(\"Hello, World!\\n\");\n"
"}\n";
program = clCreateProgramWithSource(context, 1, &kernel_source, NULL, &ret);
if (ret != CL_SUCCESS) {
printf("Failed to create program\n");
return -1;
}
ret = clBuildProgram(program, num_devices, devices, NULL, NULL, NULL);
if (ret != CL_SUCCESS) {
printf("Failed to build program\n");
return -1;
}
// 创建OpenCL内核对象
kernel = clCreateKernel(program, "hello_world", &ret);
if (ret != CL_SUCCESS) {
printf("Failed to create kernel\n");
return -1;
}
// 执行内核函数
ret = clEnqueueTask(command_queue, kernel, 0, NULL, NULL);
if (ret != CL_SUCCESS) {
printf("Failed to enqueue task\n");
return -1;
}
// 等待执行完成
ret = clFinish(command_queue);
if (ret != CL_SUCCESS) {
printf("Failed to finish execution\n");
return -1;
}
printf("Kernel executed successfully\n");
// 清理资源
ret = clReleaseKernel(kernel);
ret = clReleaseProgram(program);
ret = clReleaseCommandQueue(command_queue);
ret = clReleaseContext(context);
return 0;
}
6.2.2 直接编译
执行如下编译命令:
root@rk3399:/opt/opencl-project/platform# g++ platform.cpp -o platform -lOpenCL
-lOpenCL用于链接libOpenCL.so库文件,-l选项指定要链接的库文件名,并在文件名前加上lib和.so的前缀和后缀。所以-lOpenCL告诉编译器要链接的库文件名为libOpenCL.so。
那么编译器如何知道libOpenCL.so在哪里的呢?
- 首先搜索预定义的默认路径,如
/usr/lib和/usr/local/lib等; - 如果共享库没有在这些路径中找到,则会搜索在
/etc/ld.so.conf和/etc/ld.so.conf.d目录中指定的路径。这些路径可以包含自定义共享库路径,比如:
root@rk3399:/opt/opencl-project/platform# ls -l /etc/ld.so.conf.d/
-rw-r--r-- 1 root root 103 Apr 15 2020 aarch64-linux-gnu.conf
-rw-r--r-- 1 root root 39 Sep 7 2019 fakeroot-aarch64-linux-gnu.conf
-rw-r--r-- 1 root root 44 Apr 15 2020 libc.conf
root@rk3399:/opt/opencl-project/platform# cat /etc/ld.so.conf.d/aarch64-linux-gnu.conf
# Multiarch support
/usr/local/lib/aarch64-linux-gnu
/lib/aarch64-linux-gnu
/usr/lib/aarch64-linux-gnu
6.2.3 cmake编译
当然也可以使用cmake进行编译platform.cpp,接下来我们介绍cmake编译配置。
在/opt/opencl-project/platform目录下创建CMakeLists.txt:
cmake_minimum_required(VERSION 3.0)
cmake_policy(VERSION 3.0...3.18.4)
project(proj)
add_executable(platform platform.cpp)
find_package(OpenCL REQUIRED)
#打印调试信息
MESSAGE(STATUS "Project: ${PROJECT_NAME}")
MESSAGE(STATUS "OpenCL library status:")
MESSAGE(STATUS " version: ${OpenCL_VERSION_STRING}")
MESSAGE(STATUS " libraries: ${OpenCL_LIBRARY}")
MESSAGE(STATUS " include path: ${OpenCL_INCLUDE_DIR}")
target_link_libraries(platform PRIVATE OpenCL::OpenCL)
配置构建过程:
root@rk3399:/opt/opencl-project/platform# cmake -S . -B build
CMake Deprecation Warning at CMakeLists.txt:1 (cmake_minimum_required):
Compatibility with CMake < 3.5 will be removed from a future version of
CMake.
Update the VERSION argument <min> value or use a ...<max> suffix to tell
CMake that the project does not need compatibility with older versions.
-- The C compiler identification is GNU 9.4.0
-- The CXX compiler identification is GNU 9.4.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Looking for CL_VERSION_3_0
-- Looking for CL_VERSION_3_0 - found
-- Found OpenCL: /usr/lib/aarch64-linux-gnu/libOpenCL.so (found version "3.0")
-- Project: proj
-- OpenCL library status:
-- version: 3.0
-- libraries: /usr/lib/aarch64-linux-gnu/libOpenCL.so # 库文件路径
-- include path: /usr/include # 头文件路径
-- Configuring done (2.8s)
-- Generating done (0.0s)
-- Build files have been written to: /opt/opencl-project/platform/build
其中:
-S .:选项指定源代码目录的路径,CMake将在该路径下查找CMakeLists.txt文件;-B build:选项指定构建目录的路径;
执行构建操作,生成可执行程序platform;
root@rk3399:/opt/OpenCL-Headers/exmaples# cmake --build build
6.2.4 运行
执行程序:
root@rk3399:/opt/opencl-project/platform# ls -l build/
-rw-r--r-- 1 root root 14792 Jan 24 22:28 CMakeCache.txt
drwxr-xr-x 6 root root 4096 Jan 24 22:29 CMakeFiles
-rw-r--r-- 1 root root 5276 Jan 24 22:28 Makefile
-rw-r--r-- 1 root root 1632 Jan 24 22:28 cmake_install.cmake
-rwxr-xr-x 1 root root 14272 Jan 24 22:29 platform
root@rk3399:/opt/opencl-project/platform# ./platform
Number of platforms: 1
Platform 0:
Name: Clover
Vendor: Mesa
Failed to get device IDs
可以看到这里输出的信息和clinfo命令看到的是一致的,只有一个Platform,名称为Clover,并且该平台下设备数为0。
6.3 mesa gallium clover源码分析
前面我们说过,mesa gallium clover OpenCL源码最终会编译生成libMesaOpenCL.so动态库。
这里我们简单介绍一下mesa gallium clover OpenCL的源码实现,比如clGetPlatformInfo函数为啥获取的信息如下:
Name: Clover
Vendor: Mesa
nesa colver源码位于mesa-22.0.0/src/gallium/frontends/clover目录下;

6.3.1 clGetPlatformInfo
我们可以在项目目录下直接搜索clGetPlatformInfo函数,找到具体实现位于api/platform.cpp文件:
CLOVER_ICD_API cl_int
clGetPlatformInfo(cl_platform_id d_platform, cl_platform_info param,
size_t size, void *r_buf, size_t *r_size) {
return GetPlatformInfo(d_platform, param, size, r_buf, r_size);
}
这里调用了GetPlatformInfo函数:
cl_int
clover::GetPlatformInfo(cl_platform_id d_platform, cl_platform_info param,
size_t size, void *r_buf, size_t *r_size) try {
property_buffer buf { r_buf, size, r_size };
auto &platform = find_platform(d_platform);
switch (param) {
case CL_PLATFORM_PROFILE:
buf.as_string() = "FULL_PROFILE";
break;
case CL_PLATFORM_VERSION: {
buf.as_string() = "OpenCL " + platform.platform_version_as_string() + " Mesa " PACKAGE_VERSION MESA_GIT_SHA1;
break;
}
case CL_PLATFORM_NAME:
buf.as_string() = "Clover";
break;
case CL_PLATFORM_VENDOR:
buf.as_string() = "Mesa";
break;
case CL_PLATFORM_EXTENSIONS:
buf.as_string() = platform.supported_extensions_as_string();
break;
case CL_PLATFORM_ICD_SUFFIX_KHR:
buf.as_string() = "MESA";
break;
case CL_PLATFORM_NUMERIC_VERSION: {
buf.as_scalar<cl_version>() = platform.platform_version();
break;
}
case CL_PLATFORM_EXTENSIONS_WITH_VERSION:
buf.as_vector<cl_name_version>() = platform.supported_extensions();
break;
case CL_PLATFORM_HOST_TIMER_RESOLUTION:
buf.as_scalar<cl_ulong>() = 0;
break;
default:
throw error(CL_INVALID_VALUE);
}
return CL_SUCCESS;
} catch (error &e) {
return e.get();
}
所以:
-
当
param传入CL_PLATFORM_NAME时,返回的是Clover; -
当
param传入CL_PLATFORM_VENDOR时,返回的是Mesa;
同理在源码中可以找到其它的OpenCL API接口的实现,这里就不一一介绍了,有兴趣自行研究。
6.3.2 clGetDeviceIDs
我们可以在项目目录下直接搜索clGetDeviceIDs函数,找到具体实现位于api/device.cpp文件:
CLOVER_API cl_int
clGetDeviceIDs(cl_platform_id d_platform, cl_device_type device_type, // type传入CL_DEVICE_TYPE_GPU
cl_uint num_entries, cl_device_id *rd_devices,
cl_uint *rnum_devices) try {
auto &platform = obj(d_platform);
std::vector<cl_device_id> d_devs;
if ((!num_entries && rd_devices) ||
(!rnum_devices && !rd_devices))
throw error(CL_INVALID_VALUE);
// Collect matching devices
for (device &dev : platform) {
if (((device_type & CL_DEVICE_TYPE_DEFAULT) &&
dev == platform.front()) ||
(device_type & dev.type()))
d_devs.push_back(desc(dev));
}
if (d_devs.empty())
throw error(CL_DEVICE_NOT_FOUND);
// ...and return the requested data.
if (rnum_devices)
*rnum_devices = d_devs.size();
if (rd_devices)
copy(range(d_devs.begin(),
std::min((unsigned)d_devs.size(), num_entries)),
rd_devices);
return CL_SUCCESS;
} catch (error &e) {
return e.get();
}
由于d_devs为空,因此会执行throw error(CL_DEVICE_NOT_FOUND),最终返回e.get(),值为-1。
七、编译安装mesa 24.0.0
我们在编译安装mesa 22.0.0中配置了mesa gallium clover OpenCL ,虽然mesa gallium clover OpenCL早已存在,但它的发展一直相当停滞。最简单的证明就是,其连ARM Mail-T860 GPU设备都无法支持。
因此在2022年,Red Hat的Karol Herbst开始编写Rusticl作为mesa的基于Rust的新OpenCL实现,并合并到meas 22.3.0版本。
下面以meas 24.0.0为例,进行编译安装,官网https://docs.mesa3d.org/rusticl.html给出构建Rusticl的最低版本要求如下:
-
rust: 1.66 -
meson: 1.3.1 -
bindgen: 0.62.0 -
llvm: 15.0.0:built with libclc and -DLLVM_ENABLE_DUMP=ON; -
clang: 15.0.0; -
SPIRV-Tools:any version (recommended: v2022.3); -
SPIRV-LLVM-Translatorfor a libLLVMSPIRVLib.so matching your version of LLVM, i.e. if you’re using LLVM 15 (libLLVM.so.15), then you need a libLLVMSPIRVLib.so.15;
由于编译所依赖的包版本较高,测试发现无法在ubuntu 20.04版本下安装llvm 15.0.0版本,因为llvm 15.0.0依赖的底层包同样需要升级,比如libc6、libstdc++6等。因此,这里我不得不去升级ubuntu到22.04。
需要注意的是:我测试的时候是先编译安装mesa 22.0.0,因此有些依赖在编译安装mesa 22.0.0时已经安装了。如果接下来你按照教程操作过程中缺少依赖,可以参考前面的内容。
7.1 安装ubuntu 22.04
这里为了制作一个干净的ubuntu系统,可以参考Rockchip RK3399 - 移植ubuntu 20.04.4根文件系统流程重新制作ubuntu 22.04版本的根文件系统。注意:
- 根据实际诉求来决定是否需要安装桌面环境以及
ubuntu-restricted-extras; - 配置软件源,需要将
focal替换为jammy;
当然也可以烧录前文中制作的ubuntu 20.04的根文件系统ubuntu_ext4_rootfs.img,然后在该系统的基础上升级到ubuntu 22.04。
7.1.1 烧写文件系统
NanoPC-T4开发板进入MASKROM升级模式,需要进入如下操作:
- 将开发板连接上电源,并且连接
Type-C数据线到PC; - 按住
BOOT键再长按Power键开机(保持按下BOOT键5秒以上),将强制进入MASKROM模式。
烧写根文件系统:
root@zhengyang:/work/sambashare/rk3399/rkdeveloptool# rkdeveloptool db rk3399_loader_v1.27.126.bin
Downloading bootloader succeeded.
root@zhengyang:/work/sambashare/rk3399/rkdeveloptool# rkdeveloptool wl 0x40000 ubuntu_ext4_rootfs.img
Write LBA from file (100%)
root@zhengyang:/work/sambashare/rk3399/rkdeveloptool# rkdeveloptool rd
Reset Device OK.
对于我个人而言,这里我是重新制作了ubuntu 22.04.3版本的根文件系统镜像文件ubuntu_jammy_ext4_rootfs.img,并进行系统配置。
如果烧录的ubuntu_ext4_rootfs.img为ubuntu 20.04版本,需要参考接下来的内容进行系统的升级(这种方式不推荐)。
7.1.2 ubuntu 20.04系统配置
重启系统,这里我们可以通过df -hT查看磁盘空间信息;
root@rk3399:/# df -hT
Filesystem Type Size Used Avail Use% Mounted on
/dev/root ext4 3.9G 3.7G 408K 100% /
devtmpfs devtmpfs 1.9G 0 1.9G 0% /dev
tmpfs tmpfs 1.9G 0 1.9G 0% /dev/shm
tmpfs tmpfs 386M 1.8M 384M 1% /run
tmpfs tmpfs 5.0M 4.0K 5.0M 1% /run/lock
tmpfs tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup
tmpfs tmpfs 386M 68K 386M 1% /run/user/0
tmpfs tmpfs 386M 8.0K 386M 1% /run/user/1000
(1) 通过resize2fs指令进行扩容;
root@rk3399:/# resize2fs /dev/mmcblk0p5
resize2fs 1.45.5 (07-Jan-2020)
Filesystem at /dev/mmcblk0p5 is mounted on /; on-line resizing required
old_desc_blocks = 1, new_desc_blocks = 2
The filesystem on /dev/mmcblk0p5 is now 3784187 (4k) blocks long.
root@rk3399:/# df -hT
Filesystem Type Size Used Avail Use% Mounted on
/dev/root ext4 15G 3.7G 9.9G 28% /
devtmpfs devtmpfs 1.9G 0 1.9G 0% /dev
tmpfs tmpfs 1.9G 0 1.9G 0% /dev/shm
tmpfs tmpfs 386M 1.8M 384M 1% /run
tmpfs tmpfs 5.0M 4.0K 5.0M 1% /run/lock
tmpfs tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup
tmpfs tmpfs 386M 68K 386M 1% /run/user/0
tmpfs tmpfs 386M 8.0K 386M 1% /run/user/1000
(2) 禁用系统休眠;
root@rk3399:/# systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target
root@rk3399:/# gsettings set org.gnome.desktop.screensaver lock-enabled false
root@rk3399:/# gsettings set org.gnome.desktop.session idle-delay 0
该设置可能无效,可以通过桌面系统设置,点击【右上角倒三角】-- 【Privacy】--【Screen Lock】;
(3) 卸载unattended-upgrades;
先kill掉运行的进程,然后卸载:
root@rk3399:/# apt remove unattended-upgrades
(4) 安装linux-headers,参考前面的教程;
root@rk3399:/# cd /opt
root@rk3399:/opt# scp root@192.168.0.200:/work/sambashare/rk3399/linux-headers-6.3.0_6.3.0-17_arm64.deb /opt/
root@rk3399:/# dpkg -i /opt/linux-headers-*.deb
如果在制作根文件系统时已经安装了linux-headers,直接跳过。
7.1.3 升级到ubuntu 20.04
进入ubuntu 20.04桌面系统,我们可以看到系统自动弹出升级到22.04.3的提示,我们直接升级即可;
当然也可以通过终端命令升级,具体流程如下:
(1) 更新所有可用系统更新;
root@rk3399:/# apt update && sudo apt upgrade
# 必须重启
root@rk3399:/# reboot
(2) 更新到最新版;
在桌面环境终端运行如下命令:
# 升级系统
root@rk3399:/# apt purge snapd
root@rk3399:/# do-release-upgrade # 一直y,如果出现对话框使用鼠标选择
更新需要花费大概一个小时,静静等待即可。
(3) 查看版本;
root@rk3399:/# lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 22.04.3 LTS
Release: 22.04
Codename: jammy
(4) 移除无用包;
root@rk3399:/# apt autoremove
root@rk3399:/# apt clean
此时查看桌面系统:

7.1.4 ubuntu 22.04系统配置
(1) 配置DNS解析,安装resolvconf:
root@rk3399:/opt# apt install resolvconf
修改/etc/resolvconf/resolv.conf.d/base,添加内容如下:
nameserver 8.8.8.8
nameserver 114.114.114.114
更新配置:
root@rk3399:/opt# resolvconf -u
(2) 解决vim编辑器中文乱码问题:
root@rk3399:/opt# vim /etc/vim/vimrc
在文件末尾添加如下代码:
set fileencodings=utf-8,gb2312,gbk,gb18030
set termencoding=utf-8
set fileformats=unix
set encoding=prc
7.2 查看系统
7.2.1 查看OpenGL支持
实际上,ubuntu系统已经默认支持了OpenGL、EGL、GLESv2,可以查看系统默认安装的依赖包;
root@rk3399:~# dpkg -l | grep GL
ii gir1.2-glib-2.0:arm64 1.72.0-1 arm64 Introspection data for GLib, GObject, Gio and GModule
ii gir1.2-json-1.0:arm64 1.6.6-1build1 arm64 GLib JSON manipulation library (introspection data)
ii gir1.2-packagekitglib-1.0 1.2.5-2ubuntu2 arm64 GObject introspection data for the PackageKit GLib library
ii glib-networking:arm64 2.72.0-1 arm64 network-related giomodules for GLib
ii glib-networking-common 2.72.0-1 all network-related giomodules for GLib - data files
ii glib-networking-services 2.72.0-1 arm64 network-related giomodules for GLib - D-Bus services
ii gstreamer1.0-gl:arm64 1.20.1-1ubuntu0.1 arm64 GStreamer plugins for GL
ii libavahi-glib1:arm64 0.8-5ubuntu5.1 arm64 Avahi GLib integration library
ii libclutter-1.0-0:arm64 1.26.4+dfsg-4build1 arm64 Open GL based interactive canvas library
ii libclutter-1.0-common 1.26.4+dfsg-4build1 all Open GL based interactive canvas library (common files)
ii libclutter-gst-3.0-0:arm64 3.0.27-2ubuntu1 arm64 Open GL based interactive canvas library GStreamer elements
ii libclutter-gtk-1.0-0:arm64 1.8.4-4build2 arm64 Open GL based interactive canvas library GTK+ widget
ii libcogl-common 1.22.8-3build1 all Object oriented GL/GLES Abstraction/Utility Layer (common files)
ii libcogl-pango20:arm64 1.22.8-3build1 arm64 Object oriented GL/GLES Abstraction/Utility Layer
ii libcogl-path20:arm64 1.22.8-3build1 arm64 Object oriented GL/GLES Abstraction/Utility Layer
ii libcogl20:arm64 1.22.8-3build1 arm64 Object oriented GL/GLES Abstraction/Utility Layer
ii libegl-mesa0:arm64 23.0.4-0ubuntu1~22.04.1 arm64 free implementation of the EGL API -- Mesa vendor library
ii libegl1:arm64 1.4.0-1 arm64 Vendor neutral GL dispatch library -- EGL support
ii libepoxy0:arm64 1.5.10-1 arm64 OpenGL function pointer management library
ii libgeocode-glib0:arm64 3.26.2-2build2 arm64 geocoding and reverse geocoding GLib library using Nominatim
ii libgl1:arm64 1.4.0-1 arm64 Vendor neutral GL dispatch library -- legacy GL support
ii libgl1-amber-dri:arm64 21.3.9-0ubuntu1~22.04.1 arm64 free implementation of the OpenGL API -- Amber DRI modules
ii libgl1-mesa-dri:arm64 23.0.4-0ubuntu1~22.04.1 arm64 free implementation of the OpenGL API -- DRI modules
ii libglapi-mesa:arm64 23.0.4-0ubuntu1~22.04.1 arm64 free implementation of the GL API -- shared library
ii libgles2:arm64 1.4.0-1 arm64 Vendor neutral GL dispatch library -- GLESv2 support
ii libglib-perl:arm64 3:1.329.3-2build1 arm64 interface to the GLib and GObject libraries
ii libglib2.0-0:arm64 2.72.4-0ubuntu2.2 arm64 GLib library of C routines
ii libglib2.0-bin 2.72.4-0ubuntu2.2 arm64 Programs for the GLib library
ii libglib2.0-data 2.72.4-0ubuntu2.2 all Common files for GLib library
ii libglibmm-2.4-1v5:arm64 2.66.2-2 arm64 C++ wrapper for the GLib toolkit (shared libraries)
ii libglu1-mesa:arm64 9.0.2-1 arm64 Mesa OpenGL utility library (GLU)
ii libglvnd0:arm64 1.4.0-1 arm64 Vendor neutral GL dispatch library
ii libglx-mesa0:arm64 23.0.4-0ubuntu1~22.04.1 arm64 free implementation of the OpenGL API -- GLX vendor library
ii libglx0:arm64 1.4.0-1 arm64 Vendor neutral GL dispatch library -- GLX support
ii libgstreamer-gl1.0-0:arm64 1.20.1-1ubuntu0.1 arm64 GStreamer GL libraries
ii libgusb2:arm64 0.3.10-1 arm64 GLib wrapper around libusb1
ii libjson-glib-1.0-0:arm64 1.6.6-1build1 arm64 GLib JSON manipulation library
ii libjson-glib-1.0-common 1.6.6-1build1 all GLib JSON manipulation library (common files)
ii libopengl0:arm64 1.4.0-1 arm64 Vendor neutral GL dispatch library -- OpenGL support
ii libpackagekit-glib2-18:arm64 1.2.5-2ubuntu2 arm64 Library for accessing PackageKit using GLib
ii libpoppler-glib8:arm64 22.02.0-2ubuntu0.2 arm64 PDF rendering library (GLib-based shared library)
ii libsnapd-glib1:arm64 1.60-0ubuntu1 arm64 GLib snapd library
ii libwayland-egl1:arm64 1.20.0-1ubuntu0.1 arm64 wayland compositor infrastructure - EGL library
其中,包括:
libegl-mesa0:安装/usr/lib/aarch64-linux-gnu/libEGL_mesa.so.0.0.0库文件;libgl1-mesa-dri:安装/usr/lib/aarch64-linux-gnu/dri/xxxx_dri.so若干库文件;libglapi-mesa:安装/usr/lib/aarch64-linux-gnu/libglapi.so.0.0.0库文件;libglu1-mesa:安装/usr/lib/aarch64-linux-gnu/libGLU.so.1.3.1库文件;libglx-mesa0:安装/usr/lib/aarch64-linux-gnu/libGLX_mesa.so.0.0.0库文件;mesa-va-drivers:安装/usr/lib/aarch64-linux-gnu/dri/xxxx_drv_video.so若干库文件;mesa-vdpau-drivers:安装/usr/lib/aarch64-linux-gnu/vdpau/libvdpau_xxxx.so.1.0.0若干库文件;mesa-vulkan-drivers:安装/usr/lib/aarch64-linux-gnu/libVkLayer_MESA_device_select.so、/usr/lib/aarch64-linux-gnu/libVkLayer_MESA_overlay.so、/usr/lib/aarch64-linux-gnu/libvulkan_xxxx.so若干库文件;libopengl0:安装/usr/lib/aarch64-linux-gnu/libOpenGL.so.0.0.0;libgl1:安装/usr/lib/aarch64-linux-gnu/libGL.so.1.7.0;libgles2:安装/usr/lib/aarch64-linux-gnu/libGLESv2.so.2.1.0;libegl1:安装/usr/lib/aarch64-linux-gnu/libEGL.so.1.1.0;libglx0:安装/usr/lib/aarch64-linux-gnu/libGLX.so.0.0.0;libglvnd0:安装/usr/lib/aarch64-linux-gnu/libGLdispatch.so.0.0.0;
注意:上面包安装时除了安装上面介绍的动态库外,还会进行创建链接文件等操作。
同时可以在/usr下查找到相关动态库:
root@rk3399:/opt# find /usr | grep lib.*GL.*.so | xargs ls -l | sort # 下面我手动分类排了一下序
# OpenGL
lrwxrwxrwx 1 root root 18 Jan 4 2022 /usr/lib/aarch64-linux-gnu/libOpenGL.so.0 -> libOpenGL.so.0.0.0
-rw-r--r-- 1 root root 370784 Jan 4 2022 /usr/lib/aarch64-linux-gnu/libOpenGL.so.0.0.0 # libopengl0安装
# GL
lrwxrwxrwx 1 root root 14 Jan 4 2022 /usr/lib/aarch64-linux-gnu/libGL.so.1 -> libGL.so.1.7.0 # libgl1安装
-rw-r--r-- 1 root root 936040 Jan 4 2022 /usr/lib/aarch64-linux-gnu/libGL.so.1.7.0
# EGL
lrwxrwxrwx 1 root root 15 Jan 4 2022 /usr/lib/aarch64-linux-gnu/libEGL.so.1 -> libEGL.so.1.1.0
-rw-r--r-- 1 root root 68040 Jan 4 2022 /usr/lib/aarch64-linux-gnu/libEGL.so.1.1.0 # libegl1安装
lrwxrwxrwx 1 root root 20 Jun 19 2023 /usr/lib/aarch64-linux-gnu/libEGL_mesa.so.0 -> libEGL_mesa.so.0.0.0
-rw-r--r-- 1 root root 283848 Jun 19 2023 /usr/lib/aarch64-linux-gnu/libEGL_mesa.so.0.0.0 # libegl-mesa0安装
# GLES2
lrwxrwxrwx 1 root root 18 Jan 4 2022 /usr/lib/aarch64-linux-gnu/libGLESv2.so.2 -> libGLESv2.so.2.1.0
-rw-r--r-- 1 root root 149600 Jan 4 2022 /usr/lib/aarch64-linux-gnu/libGLESv2.so.2.1.0 # libgles2安装
# GLX
lrwxrwxrwx 1 root root 15 Jan 4 2022 /usr/lib/aarch64-linux-gnu/libGLX.so.0 -> libGLX.so.0.0.0
-rw-r--r-- 1 root root 133480 Jan 4 2022 /usr/lib/aarch64-linux-gnu/libGLX.so.0.0.0 # libglx0安装
lrwxrwxrwx 1 root root 16 Jun 19 2023 /usr/lib/aarch64-linux-gnu/libGLX_indirect.so.0 -> libGLX_mesa.so.0
lrwxrwxrwx 1 root root 20 Jun 19 2023 /usr/lib/aarch64-linux-gnu/libGLX_mesa.so.0 -> libGLX_mesa.so.0.0.0
-rw-r--r-- 1 root root 504400 Jun 19 2023 /usr/lib/aarch64-linux-gnu/libGLX_mesa.so.0.0.0 # libglx-mesa0安装
# GLU
lrwxrwxrwx 1 root root 15 Mar 4 2022 /usr/lib/aarch64-linux-gnu/libGLU.so.1 -> libGLU.so.1.3.1
-rw-r--r-- 1 root root 301576 Mar 4 2022 /usr/lib/aarch64-linux-gnu/libGLU.so.1.3.1 # libglu1-mesa安装
# 其它
-rw-r--r-- 1 root root 265416 May 26 2023 /usr/lib/libreoffice/program/libOGLTranslo.so
lrwxrwxrwx 1 root root 22 Jan 4 2022 /usr/lib/aarch64-linux-gnu/libGLdispatch.so.0 -> libGLdispatch.so.0.0.0
-rw-r--r-- 1 root root 1517784 Jan 4 2022 /usr/lib/aarch64-linux-gnu/libGLdispatch.so.0.0.0 # libglvnd0安装
注:如果想知道哪个库是由哪个包安装,执行如下命令即可: dpkg-query -S library.so。
7.2.2 查看OpenCL支持
ubuntu系统默认并没有支持OpenGL;
root@rk3399:/opt# find /usr | grep lib.*CL.*.so | xargs ls -l | sort
-rw-r--r-- 1 root root 18440 Oct 4 20:38 /usr/lib/aarch64-linux-gnu/samba/libLIBWBCLIENT-OLD.so.0
# 以下均是ocl-icd-libopencl1包安装
-rw-r--r-- 1 root root 60856 Sep 30 2021 /usr/lib/aarch64-linux-gnu/libOpenCL.so.1.0.0
lrwxrwxrwx 1 root root 18 Sep 30 2021 /usr/lib/aarch64-linux-gnu/libOpenCL.so.1 -> libOpenCL.so.1.0.0
这里仅仅可以看到OpenCL ICD Loader相关的库,并没有OpenCL ICD驱动程序实现库;
root@rk3399:/opt# dpkg -l | grep OpenCL
ii ocl-icd-libopencl1:arm64 2.2.14-3 arm64 Generic OpenCL ICD Loader
7.2.3 glxinfo
使用glxinfo命令查看OpenGL版本、支持的扩展、渲染器信息等;
root@rk3399:/opt# apt install mesa-utils
root@rk3399:/opt# export DISPLAY=:0.0; glxinfo -B
name of display: :0.0
display: :0 screen: 0
direct rendering: Yes
Extended renderer info (GLX_MESA_query_renderer):
Vendor: Mesa (0xffffffff)
Device: Mali-T860 (Panfrost) (0xffffffff)
Version: 23.0.4
Accelerated: yes
Video memory: 3851MB
Unified memory: yes
Preferred profile: core (0x1)
Max core profile version: 3.1
Max compat profile version: 3.1
Max GLES1 profile version: 1.1
Max GLES[23] profile version: 3.1
OpenGL vendor string: Mesa
OpenGL renderer string: Mali-T860 (Panfrost)
OpenGL core profile version string: 3.1 Mesa 23.0.4-0ubuntu1~22.04.1
OpenGL core profile shading language version string: 1.40
OpenGL core profile context flags: (none)
OpenGL version string: 3.1 Mesa 23.0.4-0ubuntu1~22.04.1
OpenGL shading language version string: 1.40
OpenGL context flags: (none)
OpenGL ES profile version string: OpenGL ES 3.1 Mesa 23.0.4-0ubuntu1~22.04.1
OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.10
可以看到Device:Mali-T860 (Panfrost)、OpenGL version string: 3.1 Mesa 23.0.4-0ubuntu1~22.04.1。
7.2.4 clinfo
clinfo是一个用于显示OpenCL平台和设备信息的实用程序。
root@rk3399:/opt# apt install clinfo
root@rk3399:/opt# clinfo
Number of platforms 0
7.3 下载mesa和依赖
下载mesa包:
root@rk3399:/opt# wget https://archive.mesa3d.org/mesa-24.0.0.tar.xz
root@rk3399:/opt# tar -xvf mesa-24.0.0.tar.xz
下载通用依赖:
root@rk3399:/opt# apt install git pkg-config autoconf
7.3.1 安装rust 1.75.0
运行命令下载rustup工具并安装最新的稳定版rust:
# 用于更新 toolchain
root@rk3399:/opt# export RUSTUP_DIST_SERVER=https://mirrors.ustc.edu.cn/rust-static
# 用于更新 rustup
root@rk3399:/opt# export RUSTUP_UPDATE_ROOT=https://mirrors.ustc.edu.cn/rust-static/rustup
root@rk3399:/opt# wget https://cdn.jsdelivr.net/gh/rust-lang-nursery/rustup.rs/rustup-init.sh --no-check-certificate
root@rk3399:/opt# sh rustup-init.sh
系统会提示您选择安装类型:本教程使用默认选项1。
接下来,运行以下命令将rust工具链目录添加到PATH环境变量中:
root@rk3399:/opt# source $HOME/.cargo/env
通过请求版本验证rust安装:
root@rk3399:/opt# rustc --version
rustc 1.75.0 (82e1608df 2023-12-21)
root@rk3399:/opt# cargo -V
cargo 1.75.0 (1d8b05cdd 2023-11-20)
7.3.2 安装meson 1.3.1
root@rk3399:/opt# apt install python3-pip
root@rk3399:/opt# pip3 install meson==1.3.1
root@rk3399:/opt# meson --version
1.3.1
7.3.3 安装llvm 15.0.0和clang 15
查看已经安装的包:
root@rk3399:/# dpkg -l | grep llvm
ii libllvm15:arm64 1:15.0.7-0ubuntu0.22.04.3 arm64 Modular compiler and toolchain technologies, runtime library
开始安装:
root@rk3399:/opt# apt install llvm-15 clang-15 libclang-15-dev
root@rk3399:/opt# cd /usr/bin
root@rk3399:/usr/bin# rm -rf /usr/bin/llvm-config
root@rk3399:/usr/bin# ln -s ../lib/llvm-15/bin/llvm-config /usr/bin/llvm-config
root@rk3399:/usr/bin# ls -l /usr/bin/llvm-config*
lrwxrwxrwx 1 root root 30 Feb 3 15:58 /usr/bin/llvm-config -> ../lib/llvm-15/bin/llvm-config
lrwxrwxrwx 1 root root 30 Jul 14 2023 /usr/bin/llvm-config-15 -> ../lib/llvm-15/bin/llvm-config
root@rk3399:/usr/bin# llvm-config --version
15.0.7
root@rk3399:/usr/bin# llvm-config --libdir
/usr/lib/llvm-15/lib
查看安装的包:
root@rk3399:/usr/bin# dpkg -l | grep llvm
ii libllvm15:arm64 1:15.0.7-0ubuntu0.22.04.3 arm64 Modular compiler and toolchain technologies, runtime library
ii llvm-15 1:15.0.7-0ubuntu0.22.04.3 arm64 Modular compiler and toolchain technologies
ii llvm-15-dev 1:15.0.7-0ubuntu0.22.04.3 arm64 Modular compiler and toolchain technologies, libraries and headers
ii llvm-15-linker-tools 1:15.0.7-0ubuntu0.22.04.3 arm64 Modular compiler and toolchain technologies - Plugins
ii llvm-15-runtime 1:15.0.7-0ubuntu0.22.04.3 arm64 Modular compiler and toolchain technologies, IR interpreter
ii llvm-15-tools 1:15.0.7-0ubuntu0.22.04.3 arm64 Modular compiler and toolchain technologies, tools
此外,我们也可以到《https://ubuntu.pkgs.org/》下载deb包安装,同时在该网站可以看到每个包安装了哪些文件。
7.3.4 安装libllvmspirvlib 15
查看是否已经安装spirv-tools,这里并没有安装,直接通过apt安装;
root@rk3399:/opt# dpkg -l | grep spirv-tools
root@rk3399:/opt# apt install spirv-tools
该命令会安装/usr/include/spirv-tools头文件、以及若干/usr/lib/aarch64-linux-gnu/libSPIRV-Tools*.a库文件,同时安装若干可执行文件/usr/bin/spirv-*。
查看是否已经安装libllvmspirvlib-15-dev(依赖libllvmspirvlib15),这里并没有安装,直接通过apt安装;
root@rk3399:/opt# dpkg -l | grep libllvmspirvlib
root@rk3399:/opt# apt install libllvmspirvlib-15-dev
其中:
libllvmspirvlib-15-dev:bi-directional translator for LLVM/SPIRV -- development files,安装/usr/include/LLVMSPIRVLib头文件;libllvmspirvlib15:bi-directional translator for LLVM/SPIRV -- shared library,安装库文件/usr/lib/aarch64-linux-gnu/libLLVMSPIRVLib.so.15。
查看安装的libllvmspirvlib相关包:
root@rk3399:/opt# dpkg -l | grep libllvmspirvlib
ii libllvmspirvlib-15-dev:arm64 15.0.0-1~ubuntu0.22.04.2 arm64 bi-directional translator for LLVM/SPIRV -- development files
ii libllvmspirvlib15:arm64 15.0.0-1~ubuntu0.22.04.2 arm64 bi-directional translator for LLVM/SPIRV -- shared library
root@rk3399:/opt# dpkg -l | grep spirv-tools
ii spirv-tools 2022.1+1.3.204.0-2 arm64 API and commands for processing SPIR-V modules
7.3.5 安装bindgen 0.62.0
配置源:
root@rk3399:/opt# cd ~/.cargo
root@rk3399:~/.cargo# vim config # github配置的镜像地址
[source.crates-io]
registry = "https://521github.com/rust-lang/crates.io-index"
replace-with = 'tuna'
[source.tuna]
registry = "https://mirrors.tuna.tsinghua.edu.cn/git/crates.io-index.git"
#replace-with = 'ustc'
#[source.ustc]
#registry = "git://mirrors.ustc.edu.cn/crates.io-index"
[net]
git-fetch-with-cli = true
下载:
root@rk3399:~/.cargo# cargo install bindgen-cli --version 0.62.0 # 花费20分钟左右
root@rk3399:~/.cargo# bindgen --version
bindgen 0.62.0
root@rk3399:~/.cargo# ls bin
bindgen cargo-clippy cargo-miri rls rust-gdb rust-lldb rustdoc rustup
cargo cargo-fmt clippy-driver rust-analyzer rust-gdbgui rustc rustfmt
7.3.6 安装cmake 3.28.0
root@rk3399:/opt# wget https://521github.com/extdomains/github.com/Kitware/CMake/releases/download/v3.28.0/cmake-3.28.0-linux-aarch64.tar.gz
root@rk3399:/opt# tar -xzvf cmake-3.28.0-linux-aarch64.tar.gz
root@rk3399:/opt# mv cmake-3.28.0-linux-aarch64 cmake-3.28.0
root@rk3399:/opt# ln -sf /opt/cmake-3.28.0/bin/* /usr/bin/
root@rk3399:/opt# cmake --version
cmake version 3.28.0
CMake suite maintained and supported by Kitware (kitware.com/cmake).
7.3.7 安装其它依赖
如果后面在编译mesa过程中缺少其它依赖,自己补充:
root@rk3399:/opt# apt build-dep mesa
7.4 编译安装mesa
编译mesa流程来自官网:Compilation and Installation Using Meson。
7.4.1 配置
这里我们执行如下命令在builddir目录中进行meson初始化和配置,这里我们主要的目的是只编译gallium-opencl和gallium-rusticl。它将读取项目源代码,并生成构建文件;
root@rk3399:/opt/mesa-24.0.0# meson -Db_ndebug=true -Dopengl=false -Dshared-glapi=disabled -Dgles1=disabled -Dgles2=disabled -Degl=disabled -Dplatforms= -Dvulkan-drivers=panfrost -Dgallium-drivers=panfrost -Dgallium-opencl=icd -Dgallium-rusticl=true -Dprefix=/usr builddir/
The Meson build system
Version: 1.3.1
Source dir: /opt/mesa-24.0.0
Build dir: /opt/mesa-24.0.0/builddir
Build type: native build
Project name: mesa
Project version: 24.0.0
......
mesa 24.0.0
Directories
prefix : /usr/local
libdir : lib/aarch64-linux-gnu
includedir : include
Common C and C++ arguments
c_cpp_args :
OpenGL
OpenGL : NO
ES1 : NO
ES2 : NO
Shared glapi : NO
GLVND : NO
DRI
Platform : drm
Driver dir : /usr/local/lib/aarch64-linux-gnu/dri
GLX
Enabled : NO
Provider : None
EGL
Enabled : NO
GBM
Enabled : NO
Vulkan
Drivers : panfrost
Platforms :
ICD dir : share/vulkan/icd.d
Intel Ray tracing : NO
Video
Codecs : av1dec av1enc vp9dec
APIs : vulkan
LLVM
Enabled : YES
Version : 15.0.7
Gallium
Enabled : YES
Drivers : panfrost
Platforms :
Frontends : mesa rusticl
Off-screen rendering (OSMesa): NO
HUD lm-sensors : YES
Perfetto
Enabled : NO
User defined options
prefix : /usr
b_ndebug : true
egl : disabled
gallium-drivers : panfrost
gallium-opencl : icd
gallium-rusticl : true
gles1 : disabled
gles2 : disabled
opengl : false
platforms :
shared-glapi : disabled
vulkan-drivers : panfrost
Found ninja-1.10.1 at /usr/bin/ninja
其中:
-Dopengl=false:Build support for desktop OpenGL;如果配置了会编译安装libGL.so.1.2.0;-Dshared-glapi=disabled:Whether to build a shared or static glapi. Defaults to disabled on Windows, enabled elsewhere;如果配置了会编译安装libglapi.so.0.0.0;-Dgles1=disabled:Build support for OpenGL ES 1.x;如果配置了会编译安装libGLESv1_CM.so.1.1.0;-Dgles2=disabled:Build support for OpenGL ES 2.x and 3.x;如果配置了会编译安装libGLESv2.so.2.0.0;-Degl=disabled:Build support for EGL platform;如果配置了会编译安装libEGL.so.1.0.0;-Dplatforms=:window systems to support. If this is set to auto, all platforms applicable will be enabled;-Dvulkan-drivers=panfrost:List of vulkan drivers to build. If this is set to auto all drivers applicable to the target OS/architecture will be built;会编译安装libvulkan_panfrost.so;-Dgallium-drivers=panfrost:List of gallium drivers to build. If this is set to auto all drivers applicable to the target OS/architecture will be built;-Dgallium-opencl=icd:build gallium "clover" OpenCL frontend;会编译安装libMesaOpenCL.so.1.0.0;-Dgallium-rusticl=true:build gallium "rusticl" OpenCL frontend;会编译安装libRusticlOpenCL.so.1.0.0;-Dprefix=/usr:指定安装目录;如果不指定,默认安装到/usr;
更多配置选项可以参考当前目录下meson_options.txt文件,或者通过meson configure builddir/查看选项配置值。
由于ubuntu 22.04已经默认支持了OpenGL、EGL、GLESv2,那么我们就不用在编译安装这些了。如果编译安装了这些,可以会出现如下问题:
(1) 两个版本之间的兼容问题;
root@rk3399:/opt/opencl-project/opencv-ocl# export DISPLAY=:0.0; glxinfo -B
name of display: :0.0
libGL error: DRI driver not from this Mesa build ('24.0.0' vs '23.0.4-0ubuntu1~22.04.1')
libGL error: failed to load driver: rockchip
glxinfo: ../src/mapi/shared-glapi/glapi.c:62: _glapi_add_dispatch: Assertion `function_name[0] == 'g' && function_name[1] == 'l'' failed.
Aborted (core dumped)
ubuntu系统/apt命令默认安装的是23.0.4,编译安装的是24.0.0,出现如上问题重新安装如下包:
root@rk3399:/opt# apt install --reinstall libegl-mesa0 libgl1-mesa-dri libglapi-mesa libglu1-mesa libglx-mesa0 mesa-va-drivers mesa-vdpau-drivers mesa-vulkan-drivers libopengl0 libgl1 libgles2 libegl1 libglx0 libglvnd0
(2) 出现clinfo异常:
root@rk3399:/opt/mesa-24.0.0# RUSTICL_ENABLE=panfrost clinfo
.....
clinfo: ../src/panfrost/midgard/midgard_compile.c:1029: emit_ubo_read: Assertion `!"" "Invalid UBO read size"' failed.
Aborted (core dumped)
按照教程配置重新配置mesa,并编译安装。
(3) 点击桌面右上角Settings无法正常打开,此时可以执行如下命令解决:
root@rk3399:/opt# apt install unity-control-center
root@rk3399:/opt# apt install gnome-control-center
7.4.2 编译
编译项目,大概需要花费30分钟;
root@rk3399:/opt/mesa-24.0.0# ninja -C builddir/ -j6
需要注意的是:如果中间编译失败,不用删除builddir重新编译(避免浪费时间),解决掉错误重新运行该命令即可。
如果编译出现内存不足、卡死等问题,可以将-j6修改为-j4、或者去除该参数。
7.4.3 安装
最后一步进行安装;
root@rk3399:/opt/mesa-24.0.0# ninja -C builddir/ install
ninja: Entering directory `builddir/'
[1/2] Installing files.
# OpenCL等库文件
Installing src/panfrost/vulkan/libvulkan_panfrost.so to /usr/lib/aarch64-linux-gnu
Installing src/panfrost/vulkan/panfrost_icd.aarch64.json to /usr/share/vulkan/icd.d
Installing src/gallium/targets/pipe-loader/pipe_kmsro.so to /usr/lib/aarch64-linux-gnu/gallium-pipe
Installing src/gallium/targets/opencl/libMesaOpenCL.so.1.0.0 to /usr/lib/aarch64-linux-gnu
Installing src/gallium/targets/rusticl/libRusticlOpenCL.so.1.0.0 to /usr/lib/aarch64-linux-gnu
Installing /opt/mesa-24.0.0/src/util/00-mesa-defaults.conf to /usr/share/drirc.d
# ICD定义文件
Installing /opt/mesa-24.0.0/builddir/src/gallium/targets/opencl/mesa.icd to /etc/OpenCL/vendors
Installing /opt/mesa-24.0.0/builddir/src/gallium/targets/rusticl/rusticl.icd to /etc/OpenCL/vendors
# OpenCL库文件链接文件创建
Installing symlink pointing to libMesaOpenCL.so.1.0.0 to /usr/lib/aarch64-linux-gnu/libMesaOpenCL.so.1
Installing symlink pointing to libMesaOpenCL.so.1 to /usr/lib/aarch64-linux-gnu/libMesaOpenCL.so
Installing symlink pointing to libRusticlOpenCL.so.1.0.0 to /usr/lib/aarch64-linux-gnu/libRusticlOpenCL.so.1
Installing symlink pointing to libRusticlOpenCL.so.1 to /usr/lib/aarch64-linux-gnu/libRusticlOpenCL.so
会将OpenCL库安装到/usr/lib/aarch64-linux-gnu目录;
root@rk3399:/opt# find /usr | grep lib.*CL.*.so | xargs ls -l | sort
-rw-r--r-- 1 root root 18440 Oct 4 20:38 /usr/lib/aarch64-linux-gnu/samba/libLIBWBCLIENT-OLD.so.0
# OpenCL ICD Loader
lrwxrwxrwx 1 root root 18 Sep 30 2021 /usr/lib/aarch64-linux-gnu/libOpenCL.so.1 -> libOpenCL.so.1.0.0
-rw-r--r-- 1 root root 60856 Sep 30 2021 /usr/lib/aarch64-linux-gnu/libOpenCL.so.1.0.0
# 编译安装的 mesa gallium clover OpenCL
lrwxrwxrwx 1 root root 18 Feb 3 17:24 /usr/lib/aarch64-linux-gnu/libMesaOpenCL.so -> libMesaOpenCL.so.1
lrwxrwxrwx 1 root root 22 Feb 3 17:24 /usr/lib/aarch64-linux-gnu/libMesaOpenCL.so.1 -> libMesaOpenCL.so.1.0.0
-rwxr-xr-x 1 root root 49110544 Feb 3 17:24 /usr/lib/aarch64-linux-gnu/libMesaOpenCL.so.1.0.0
# 编译安装的mesa gallium rusticl OpenCL
lrwxrwxrwx 1 root root 21 Feb 3 17:24 /usr/lib/aarch64-linux-gnu/libRusticlOpenCL.so -> libRusticlOpenCL.so.1
lrwxrwxrwx 1 root root 25 Feb 3 17:24 /usr/lib/aarch64-linux-gnu/libRusticlOpenCL.so.1 -> libRusticlOpenCL.so.1.0.0
-rwxr-xr-x 1 root root 72303464 Feb 3 17:24 /usr/lib/aarch64-linux-gnu/libRusticlOpenCL.so.1.0.0
我们可以查看/etc/OpenCL/vendors/目录获取当前系统中可用的OpenCL平台;
root@rk3399:/opt# ls -l /etc/OpenCL/vendors/
-rw-r--r-- 1 root root 19 Feb 3 16:20 mesa.icd
-rw-r--r-- 1 root root 22 Feb 3 16:20 rusticl.icd
root@rk3399:/opt# cat /etc/OpenCL/vendors/mesa.icd
libMesaOpenCL.so.1
root@rk3399:/opt# cat /etc/OpenCL/vendors/rusticl.icd
libRusticlOpenCL.so.1
7.5 OpenGL测试
如果需要编写OpenGL程序,首先需要安装GL、EGL、GLES、GLES2、GLES3头文件;
root@rk3399:/opt# apt install libgl-dev libegl-dev libgles-dev x11proto-dev
root@rk3399:/opt# cd /usr/include
root@rk3399:/usr/include# ls GL EGL GLES GLES2 GLES3
EGL:
egl.h eglext.h eglplatform.h
GL:
gl.h glcorearb.h glext.h glx.h glxext.h glxint.h glxmd.h glxproto.h glxtokens.h internal
GLES:
egl.h gl.h glext.h glplatform.h
GLES2:
gl2.h gl2ext.h gl2platform.h
GLES3:
gl3.h gl31.h gl32.h gl3ext.h gl3platform.h
7.5.1 glxinfo
使用glxinfo测试:
root@rk3399:/opt# export DISPLAY=:0.0; glxinfo -B
name of display: :0.0
display: :0 screen: 0
direct rendering: Yes
Extended renderer info (GLX_MESA_query_renderer):
Vendor: Mesa (0xffffffff)
Device: Mali-T860 (Panfrost) (0xffffffff)
Version: 23.0.4
Accelerated: yes
Video memory: 3851MB
Unified memory: yes
Preferred profile: core (0x1)
Max core profile version: 3.1
Max compat profile version: 3.1
Max GLES1 profile version: 1.1
Max GLES[23] profile version: 3.1
OpenGL vendor string: Mesa
OpenGL renderer string: Mali-T860 (Panfrost)
OpenGL core profile version string: 3.1 Mesa 23.0.4-0ubuntu1~22.04.1
OpenGL core profile shading language version string: 1.40
OpenGL core profile context flags: (none)
OpenGL version string: 3.1 Mesa 23.0.4-0ubuntu1~22.04.1
OpenGL shading language version string: 1.40
OpenGL context flags: (none)
OpenGL ES profile version string: OpenGL ES 3.1 Mesa 23.0.4-0ubuntu1~22.04.1
OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.10
可以看到Device: Mali-T860 (Panfrost) 、OpenGL version string: 3.1 Mesa 23.0.4-0ubuntu1~22.04.1。
7.5.2 screenfetch
运行screenfetch命令,不过这里好像并没有识别到GPU;
root@rk3399:/opt# screenfetch
./+o+- root@rk3399
yyyyy- -yyyyyy+ OS: Ubuntu 22.04 jammy
://+//////-yyyyyyo Kernel: aarch64 Linux 6.3.0
.++ .:/++++++/-.+sss/` Uptime: 20d 9h 29m
.:++o: /++++++++/:--:/- Packages: 1908
o:+o+:++.`..```.-/oo+++++/ Shell: bash 5.1.16
.:+o:+o/. `+sssoo+/ Resolution: 2560x1440
.++/+:+oo+o:` /sssooo. DE: GNOME 41.7
/+++//+:`oo+o /::--:. WM: Not Found
\+/+o+++`o++o ++////. GTK Theme: Adwaita [GTK2/3]
.++.o+++oo+:` /dddhhh. Icon Theme: Adwaita
.+.o+oo:. `oddhhhh+ Font: Cantarell 11
\+.++o+o``-````.:ohdhhhhh+ Disk: 9.3G / 15G (69%)
`:o+++ `ohhhhhhhhyo++os: CPU: 6x ARM Cortex-A53 Cortex-A72
.o:`.syhhhhhhh/.oo++o` GPU:
/osyyyyyyo++ooo+++/ RAM: 2724MiB / 3851MiB
````` +oo+++o\:
`oo++.
7.5.3 glmark2
在桌面环境终端运行glmark2命令进行测试;
root@rk3399:/opt# glmark2
=======================================================
glmark2 2021.02
=======================================================
OpenGL Information
GL_VENDOR: Mesa
GL_RENDERER: Mali-T860 (Panfrost)
GL_VERSION: 3.1 Mesa 23.0.4-0ubuntu1~22.04.1
=======================================================
[build] use-vbo=false: FPS: 528 FrameTime: 1.894 ms
[build] use-vbo=true: FPS: 644 FrameTime: 1.553 ms
[texture] texture-filter=nearest: FPS: 703 FrameTime: 1.422 ms
[texture] texture-filter=linear: FPS: 714 FrameTime: 1.401 ms
[texture] texture-filter=mipmap: FPS: 703 FrameTime: 1.422 ms
[shading] shading=gouraud: FPS: 520 FrameTime: 1.923 ms
[shading] shading=blinn-phong-inf: FPS: 502 FrameTime: 1.992 ms
[shading] shading=phong: FPS: 450 FrameTime: 2.222 ms
[shading] shading=cel: FPS: 449 FrameTime: 2.227 ms
[bump] bump-render=high-poly: FPS: 288 FrameTime: 3.472 ms
[bump] bump-render=normals: FPS: 678 FrameTime: 1.475 ms
[bump] bump-render=height: FPS: 669 FrameTime: 1.495 ms
[effect2d] kernel=0,1,0;1,-4,1;0,1,0;: FPS: 411 FrameTime: 2.433 ms
[effect2d] kernel=1,1,1,1,1;1,1,1,1,1;1,1,1,1,1;: FPS: 192 FrameTime: 5.208 ms
[pulsar] light=false:quads=5:texture=false: FPS: 729 FrameTime: 1.372 ms
[desktop] blur-radius=5:effect=blur:passes=1:separable=true:windows=4: FPS: 141 FrameTime: 7.092 ms
[desktop] effect=shadow:windows=4: FPS: 577 FrameTime: 1.733 ms
[buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=map: FPS: 114 FrameTime: 8.772 ms
[buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=subdata: FPS: 114 FrameTime: 8.772 ms
[buffer] columns=200:interleave=true:update-dispersion=0.9:update-fraction=0.5:update-method=map: FPS: 144 FrameTime: 6.944 ms
[ideas] speed=duration: FPS: 413 FrameTime: 2.421 ms
[jellyfish] <default>: FPS: 322 FrameTime: 3.106 ms
[terrain] <default>: FPS: 20 FrameTime: 50.000 ms
[shadow] <default>: FPS: 302 FrameTime: 3.311 ms
[refract] <default>: FPS: 61 FrameTime: 16.393 ms
[conditionals] fragment-steps=0:vertex-steps=0: FPS: 692 FrameTime: 1.445 ms
[conditionals] fragment-steps=5:vertex-steps=0: FPS: 438 FrameTime: 2.283 ms
[conditionals] fragment-steps=0:vertex-steps=5: FPS: 681 FrameTime: 1.468 ms
[function] fragment-complexity=low:fragment-steps=5: FPS: 526 FrameTime: 1.901 ms
[function] fragment-complexity=medium:fragment-steps=5: FPS: 384 FrameTime: 2.604 ms
[loop] fragment-loop=false:fragment-steps=5:vertex-steps=5: FPS: 520 FrameTime: 1.923 ms
[loop] fragment-steps=5:fragment-uniform=false:vertex-steps=5: FPS: 522 FrameTime: 1.916 ms
[loop] fragment-steps=5:fragment-uniform=true:vertex-steps=5: FPS: 419 FrameTime: 2.387 ms
=======================================================
glmark2 Score: 441
=======================================================
7.5.4 demo
在/opt/目录下创建opengl-project文件夹;
root@rk3399:/opt# mkdir opengl-project
接着创建demo1文件夹;
root@rk3399:/opt# cd opengl-project/
root@rk3399:/opt/opengl-project# mkdir demo1
root@rk3399:/opt/opengl-project# cd demo1
在/opt/opengl-project/demo1目录下编写测试代码main.cpp;
#include <GL/glut.h>
void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glOrtho(-5, 5, -5, 5, 5, 15);
glMatrixMode(GL_MODELVIEW);
gluLookAt(0, 0, 10, 0, 0, 0, 0, 1, 0);
return;
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 0, 0);
glutWireTeapot(3);
glFlush();
return;
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(0, 0);
glutInitWindowSize(300, 300);
glutCreateWindow("OpenGL 3D View");
init();
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
此外,我们还需要安装libglu1-mesa-dev 、freeglut3-dev;
root@rk3399:/opt# apt install libglu1-mesa-dev freeglut3-dev
root@rk3399:/opt# ll /usr/lib/aarch64-linux-gnu/*glu*
-rw-r--r-- 1 root root 543942 May 9 2020 /usr/lib/aarch64-linux-gnu/libglut.a
lrwxrwxrwx 1 root root 16 May 9 2020 /usr/lib/aarch64-linux-gnu/libglut.so -> libglut.so.3.9.0
lrwxrwxrwx 1 root root 16 May 9 2020 /usr/lib/aarch64-linux-gnu/libglut.so.3 -> libglut.so.3.9.0
-rw-r--r-- 1 root root 282184 May 9 2020 /usr/lib/aarch64-linux-gnu/libglut.so.3.9.0
root@rk3399:/opt# ll /usr/lib/aarch64-linux-gnu/*GLU**
-rw-r--r-- 1 root root 874452 Mar 4 2022 /usr/lib/aarch64-linux-gnu/libGLU.a
lrwxrwxrwx 1 root root 11 Mar 4 2022 /usr/lib/aarch64-linux-gnu/libGLU.so -> libGLU.so.1
lrwxrwxrwx 1 root root 15 Mar 4 2022 /usr/lib/aarch64-linux-gnu/libGLU.so.1 -> libGLU.so.1.3.1
-rw-r--r-- 1 root root 301576 Mar 4 2022 /usr/lib/aarch64-linux-gnu/libGLU.so.1.3.1
其中:
libglu1-mesa-dev(依赖libgl-dev、libgl1-mesa-dev、libglu1-mesa):Mesa OpenGL utility library -- development files;安装/usr/include/GL/glu.h、/usr/include/GL/glu_mangle.h、/usr/lib/aarch64-linux-gnu/libGLU.a;libgl-dev:前面已经介绍过;libgl1-mesa-dev:前面已经介绍过libglu1-mesa:Mesa OpenGL utility library (GLU),安装/usr/lib/aarch64-linux-gnu/libGLU.so.1.3.1;
freeglut3-dev(依赖freeglut3、libgl-dev、libgl1-mesa-dev、libglu-dev、libglu1-mesa-dev等):OpenGL Utility Toolkit development files;在/usr/include/GL/下安装freeglut.h、freeglut_ext.h、freeglut_std.h、glut.h,以及在/usr/lib/aarch64-linux-gnu/安装库libglut.a;freeglut3:OpenGL Utility Toolkit,安装/usr/lib/aarch64-linux-gnu/libglut.so.3.9.0;libgl-dev:前面已经介绍过;libgl1-mesa-dev:前面已经介绍过;libglu-dev:等同libglu1-mesa-dev;libglu1-mesa-dev:前面已经介绍过;
注意:上面包安装时除了安装介绍的动态库外,还会进行创建链接文件等操作。执行完之后,我们会发现创建了:
lrwxrwxrwx 1 root root 14 Jan 4 2022 /usr/lib/aarch64-linux-gnu/libOpenGL.so -> libOpenGL.so.0
lrwxrwxrwx 1 root root 10 Jan 4 2022 /usr/lib/aarch64-linux-gnu/libGL.so -> libGL.so.1
lrwxrwxrwx 1 root root 11 Jan 4 2022 /usr/lib/aarch64-linux-gnu/libEGL.so -> libEGL.so.1
lrwxrwxrwx 1 root root 14 Jan 4 2022 /usr/lib/aarch64-linux-gnu/libGLESv2.so -> libGLESv2.so.2
lrwxrwxrwx 1 root root 11 Jan 4 2022 /usr/lib/aarch64-linux-gnu/libGLX.so -> libGLX.so.0
lrwxrwxrwx 1 root root 11 Mar 4 2022 /usr/lib/aarch64-linux-gnu/libGLU.so -> libGLU.so.1
lrwxrwxrwx 1 root root 18 Jan 4 2022 /usr/lib/aarch64-linux-gnu/libGLdispatch.so -> libGLdispatch.so.0
编译程序:
root@rk3399:/opt/opengl-project/demo1# g++ -o main main.cpp -lGL -lGLU -lglut
运行程序:
root@rk3399:/opt/opengl-project/demo1# export DISPLAY=:0.0;./main
结果如下:

7.6 OpenCL测试
如果需要编写OpenCL程序,首先需要安装OpenCL头文件;
root@rk3399:/opt# apt install opencl-headers
root@rk3399:/opt# ll /usr/include/CL
-rw-r--r-- 1 root root 81345 Dec 15 2021 cl.h
-rw-r--r-- 1 root root 786 Jun 22 2021 cl2.hpp
-rw-r--r-- 1 root root 5142 Dec 15 2021 cl_d3d10.h
-rw-r--r-- 1 root root 5174 Dec 15 2021 cl_d3d11.h
-rw-r--r-- 1 root root 9913 Dec 15 2021 cl_dx9_media_sharing.h
-rw-r--r-- 1 root root 959 Dec 15 2021 cl_dx9_media_sharing_intel.h
-rw-r--r-- 1 root root 4434 Dec 15 2021 cl_egl.h
-rw-r--r-- 1 root root 94055 Jan 8 2022 cl_ext.h
-rw-r--r-- 1 root root 902 Dec 15 2021 cl_ext_intel.h
-rw-r--r-- 1 root root 7510 Dec 15 2021 cl_gl.h
-rw-r--r-- 1 root root 905 Dec 15 2021 cl_gl_ext.h
-rw-r--r-- 1 root root 10430 Dec 15 2021 cl_half.h
-rw-r--r-- 1 root root 52277 Dec 15 2021 cl_icd.h
-rw-r--r-- 1 root root 2064 Dec 15 2021 cl_layer.h
-rw-r--r-- 1 root root 45028 Jan 8 2022 cl_platform.h
-rw-r--r-- 1 root root 6269 Dec 15 2021 cl_va_api_media_sharing_intel.h
-rw-r--r-- 1 root root 3125 Dec 15 2021 cl_version.h
-rw-r--r-- 1 root root 970 Dec 15 2021 opencl.h
-rw-r--r-- 1 root root 332101 Jun 22 2021 opencl.hpp
创建/usr/lib/aarch64-linux-gnu/libOpenCL.so 到libOpenCL.so.1的链接文件:
root@rk3399:/opt# cd /usr/lib/aarch64-linux-gnu/
root@rk3399:/usr/lib/aarch64-linux-gnu# ln -s libOpenCL.so.1 /usr/lib/aarch64-linux-gnu/libOpenCL.so
root@rk3399:/usr/lib/aarch64-linux-gnu# ll *OpenCL*
lrwxrwxrwx 1 root root 18 Feb 3 19:03 libMesaOpenCL.so -> libMesaOpenCL.so.1*
lrwxrwxrwx 1 root root 22 Feb 3 19:03 libMesaOpenCL.so.1 -> libMesaOpenCL.so.1.0.0*
-rwxr-xr-x 1 root root 54764552 Feb 3 19:03 libMesaOpenCL.so.1.0.0*
lrwxrwxrwx 1 root root 14 Feb 3 19:41 libOpenCL.so -> libOpenCL.so.1
lrwxrwxrwx 1 root root 18 Sep 30 2021 libOpenCL.so.1 -> libOpenCL.so.1.0.0
-rw-r--r-- 1 root root 60856 Sep 30 2021 libOpenCL.so.1.0.0
lrwxrwxrwx 1 root root 21 Feb 3 19:03 libRusticlOpenCL.so -> libRusticlOpenCL.so.1*
lrwxrwxrwx 1 root root 25 Feb 3 19:03 libRusticlOpenCL.so.1 -> libRusticlOpenCL.so.1.0.0*
-rwxr-xr-x 1 root root 78237424 Feb 3 19:03 libRusticlOpenCL.so.1.0.0*
7.6.1 clinfo
这里通过RUSTICL_ENABLE启动CL,具体可以参考https://docs.mesa3d.org/rusticl.html:
root@rk3399:/opt# RUSTICL_ENABLE=panfrost clinfo
Number of platforms 2
Platform Name rusticl
Platform Vendor Mesa/X.org
Platform Version OpenCL 3.0
Platform Profile FULL_PROFILE
Platform Extensions cl_khr_byte_addressable_store cl_khr_create_command_queue cl_khr_expect_assume cl_khr_extended_versioning cl_khr_icd cl_khr_il_program cl_khr_spirv_no_integer_wrap_decoration
Platform Extensions with Version cl_khr_byte_addressable_store 0x400000 (1.0.0)
cl_khr_create_command_queue 0x400000 (1.0.0)
cl_khr_expect_assume 0x400000 (1.0.0)
cl_khr_extended_versioning 0x400000 (1.0.0)
cl_khr_icd 0x400000 (1.0.0)
cl_khr_il_program 0x400000 (1.0.0)
cl_khr_spirv_no_integer_wrap_decoration 0x400000 (1.0.0)
Platform Numeric Version 0xc00000 (3.0.0)
Platform Extensions function suffix MESA
Platform Host timer resolution 1ns
Platform Name Clover
Platform Vendor Mesa
Platform Version OpenCL 1.1 Mesa 24.0.0
Platform Profile FULL_PROFILE
Platform Extensions cl_khr_icd
Platform Extensions function suffix MESA
Platform Name rusticl
Number of devices 1
Device Name Mali-T860 (Panfrost)
Device Vendor Arm
Device Vendor ID 0
Device Version OpenCL 3.0
Device Numeric Version 0xc00000 (3.0.0)
Driver Version 24.0.0
Device OpenCL C Version OpenCL C 1.2
Device OpenCL C all versions OpenCL C 0xc00000 (3.0.0)
OpenCL C 0x402000 (1.2.0)
OpenCL C 0x401000 (1.1.0)
OpenCL C 0x400000 (1.0.0)
Device OpenCL C features __opencl_c_integer_dot_product_input_4x8bit_packed 0x800000 (2.0.0)
__opencl_c_integer_dot_product_input_4x8bit 0x800000 (2.0.0)
__opencl_c_int64 0x400000 (1.0.0)
__opencl_c_images 0x400000 (1.0.0)
__opencl_c_3d_image_writes 0x400000 (1.0.0)
Latest comfornace test passed v0000-01-01-00
Device Type GPU
Device Profile EMBEDDED_PROFILE
Device Available Yes
Compiler Available Yes
Linker Available Yes
Max compute units 4
Max clock frequency 800MHz
Device Partition (core)
Max number of sub-devices 0
Supported partition types None
Supported affinity domains (n/a)
Max work item dimensions 3
Max work item sizes 128x128x128
Max work group size 128
Preferred work group size multiple (device) 1
Preferred work group size multiple (kernel) 1
Max sub-groups per work group 0
Preferred / native vector sizes
char 1 / 1
short 1 / 1
int 1 / 1
long 1 / 1
half 0 / 0 (n/a)
float 1 / 1
double 0 / 0 (n/a)
Half-precision Floating-point support (n/a)
Single-precision Floating-point support (core)
Denormals No
Infinity and NANs Yes
Round to nearest Yes
Round to zero No
Round to infinity No
IEEE754-2008 fused multiply-add No
Support is emulated in software No
Correctly-rounded divide and sqrt operations No
Double-precision Floating-point support (n/a)
Address bits 64, Little-Endian
Global memory size 536870912 (512MiB)
Error Correction support No
Max memory allocation 536870912 (512MiB)
Unified memory for Host and Device Yes
Shared Virtual Memory (SVM) capabilities (core)
Coarse-grained buffer sharing No
Fine-grained buffer sharing No
Fine-grained system sharing No
Atomics No
Minimum alignment for any data type 128 bytes
Alignment of base address 4096 bits (512 bytes)
Preferred alignment for atomics
SVM 0 bytes
Global 0 bytes
Local 0 bytes
Atomic memory capabilities relaxed, work-group scope
Atomic fence capabilities relaxed, acquire/release, work-group scope
Max size for global variable 0
Preferred total size of global vars 0
Global Memory cache type None
Image support Yes
Max number of samplers per kernel 32
Max size for 1D images from buffer 65536 pixels
Max 1D or 2D image array size 2048 images
Max 2D image size 8192x8192 pixels
Max 3D image size 8192x8192x8192 pixels
Max number of read image args 128
Max number of write image args 64
Max number of read/write image args 0
Pipe support No
Max number of pipe args 0
Max active pipe reservations 0
Max pipe packet size 0
Local memory type Global
Local memory size 32768 (32KiB)
Max number of constant args 16
Max constant buffer size 67108864 (64MiB)
Generic address space support No
Max size of kernel argument 4096 (4KiB)
Queue properties (on host)
Out-of-order execution No
Profiling Yes
Device enqueue capabilities (n/a)
Queue properties (on device)
Out-of-order execution No
Profiling No
Preferred size 0
Max size 0
Max queues on device 0
Max events on device 0
Prefer user sync for interop Yes
Profiling timer resolution 0ns
Execution capabilities
Run OpenCL kernels Yes
Run native kernels No
Non-uniform work-groups No
Work-group collective functions No
Sub-group independent forward progress No
IL version SPIR-V_1.0 SPIR-V_1.1 SPIR-V_1.2 SPIR-V_1.3 SPIR-V_1.4
ILs with version SPIR-V 0x400000 (1.0.0)
SPIR-V 0x401000 (1.1.0)
SPIR-V 0x402000 (1.2.0)
SPIR-V 0x403000 (1.3.0)
SPIR-V 0x404000 (1.4.0)
printf() buffer size 1048576 (1024KiB)
Built-in kernels (n/a)
Built-in kernels with version (n/a)
Device Extensions cl_khr_byte_addressable_store cl_khr_create_command_queue cl_khr_expect_assume cl_khr_extended_versioning cl_khr_icd cl_khr_il_program cl_khr_spirv_no_integer_wrap_decoration cl_khr_global_int32_base_atomics cl_khr_global_int32_extended_atomics cl_khr_integer_dot_product cl_khr_local_int32_base_atomics cl_khr_local_int32_extended_atomics cles_khr_int64 cl_khr_3d_image_writes
Device Extensions with Version cl_khr_byte_addressable_store 0x400000 (1.0.0)
cl_khr_create_command_queue 0x400000 (1.0.0)
cl_khr_expect_assume 0x400000 (1.0.0)
cl_khr_extended_versioning 0x400000 (1.0.0)
cl_khr_icd 0x400000 (1.0.0)
cl_khr_il_program 0x400000 (1.0.0)
cl_khr_spirv_no_integer_wrap_decoration 0x400000 (1.0.0)
cl_khr_global_int32_base_atomics 0x400000 (1.0.0)
cl_khr_global_int32_extended_atomics 0x400000 (1.0.0)
cl_khr_integer_dot_product 0x800000 (2.0.0)
cl_khr_local_int32_base_atomics 0x400000 (1.0.0)
cl_khr_local_int32_extended_atomics 0x400000 (1.0.0)
cles_khr_int64 0x400000 (1.0.0)
cl_khr_3d_image_writes 0x400000 (1.0.0)
Platform Name Clover
Number of devices 0
NULL platform behavior
clGetPlatformInfo(NULL, CL_PLATFORM_NAME, ...) rusticl
clGetDeviceIDs(NULL, CL_DEVICE_TYPE_ALL, ...) Success [MESA]
clCreateContext(NULL, ...) [default] Success [MESA]
clCreateContext(NULL, ...) [other]
clCreateContextFromType(NULL, CL_DEVICE_TYPE_DEFAULT) Success (1)
Platform Name rusticl
Device Name Mali-T860 (Panfrost)
clCreateContextFromType(NULL, CL_DEVICE_TYPE_CPU) No devices found in platform
clCreateContextFromType(NULL, CL_DEVICE_TYPE_GPU) Success (1)
Platform Name rusticl
Device Name Mali-T860 (Panfrost)
clCreateContextFromType(NULL, CL_DEVICE_TYPE_ACCELERATOR) No devices found in platform
clCreateContextFromType(NULL, CL_DEVICE_TYPE_CUSTOM) No devices found in platform
clCreateContextFromType(NULL, CL_DEVICE_TYPE_ALL) Success (1)
Platform Name rusticl
Device Name Mali-T860 (Panfrost)
ICD loader properties
ICD loader Name OpenCL ICD Loader
ICD loader Vendor OCL Icd free software
ICD loader Version 2.2.14
ICD loader Profile OpenCL 3.0
可以看出系统中同时安装了:
mesa gallium clover OpenCL ICD驱动程序;mesa gallium rusticl OpenCL ICD驱动程序;
这里最后可以看到mesa gallium rusticl OpenCL ICD驱动程序识别到了GPU Mali-T860设备。
7.6.2 platform程序
这里测试第六节中编写的platform.c程序,编译程序:
root@rk3399:/opt/opencl-project/platform# g++ platform.cpp -o platform -lOpenCL
运行程序:
root@rk3399:/opt/opencl-project/platform# RUSTICL_ENABLE=panfrost ./platform
Number of platforms: 2
Platform 0:
Name: rusticl
Vendor: Mesa/X.org
Platform 1:
Name: Clover
Vendor: Mesa
Hello, World!
Kernel executed successfully
7.6.3 clpeak测试
clpeak用于测量OpenCL设备峰值能力的合成基准测试工具。它只测量使用矢量操作可以实现的峰值指标,并不代表真实世界的使用情况。
下载clpeak源码,并编译:
root@rk3399:/opt/opencl-project# git clone https://github.com/krrishnarraj/clpeak.git
root@rk3399:/opt/opencl-project# cd clpeak
root@rk3399:/opt/opencl-project/clpeak# git submodule update --init --recursive --remote
root@rk3399:/opt/opencl-project/clpeak# cmake -S . -B build
root@rk3399:/opt/opencl-project/clpeak# cmake --build build
运行程序:
root@rk3399:/opt/opencl-project/clpeak# RUSTICL_ENABLE=panfrost RUSTICL_FEATURES=fp16 ./build/clpeak --enable-xml-dump
Platform: rusticl
Device: Mali-T860 (Panfrost)
Driver version : 24.0.0 (Linux ARM64)
Compute units : 4
Clock frequency : 800 MHz
__build
__build
__before
clCreateCommandQueue (-35)
需要修改源码src/clpeck.cpp文件,替换如下代码:
// cl::CommandQueue queue = cl::CommandQueue(ctx, devices[d], CL_QUEUE_PROFILING_ENABLE);
cl::CommandQueue queue = cl::CommandQueue(ctx, devices[d], 0, NULL);
重新编译运行:
root@rk3399:/opt/opencl-project/clpeak# RUSTICL_ENABLE=panfrost RUSTICL_FEATURES=fp16 ./build/clpeak --enable-xml-dump
Platform: rusticl
Device: Mali-T860 (Panfrost)
Driver version : 24.0.0 (Linux ARM64)
Compute units : 4
Clock frequency : 800 MHz
Global memory bandwidth (GBPS)
float : 2.53
float2 : 4.45
float4 : 5.34
float8 : 5.71
float16 : 5.63
Single-precision compute (GFLOPS)
float : 7.77
float2 : 14.85
float4 : 29.28
float8 : 45.51
float16 : 113.65
Half-precision compute (GFLOPS)
half : 7.77
half2 : 14.83
half4 : 29.28
half8 : 46.48
half16 : 112.84
No double precision support! Skipped
Integer compute (GIOPS)
int : 7.43
int2 : 14.73
int4 : 21.55
int8 : 58.78
int16 : 109.08
Integer compute Fast 24bit (GIOPS)
int : 7.43
int2 : 14.73
int4 : 21.56
int8 : 58.68
int16 : 108.96
Transfer bandwidth (GBPS)
enqueueWriteBuffer : 1.61
enqueueReadBuffer : 0.38
enqueueWriteBuffer non-blocking : 1.65
enqueueReadBuffer non-blocking : 0.38
enqueueMapBuffer(for read) : 1109.93
memcpy from mapped ptr : 0.38
enqueueUnmap(after write) : 1125.99
memcpy to mapped ptr : 1.71
Kernel launch latency : 0.00 us
Platform: Clover
clCreateContextFromType (-1)
7.6.4 其它
更多OpenCL测试示例请参考:
这里以opencv-ocl项目为例,安装OpenCV环境,并编译程序。在开发板其中一个USB接口上接入USB摄像头,在桌面系统执行如下命令:
root@rk3399:/opt/opencl-project/opencv-ocl# RUSTICL_ENABLE=panfrost ./main -c
运行结果如下:
参考文章
[1] 在 RK3399 上运行开源的 Mali GPU 驱动
[2] mainline 的 u-boot 和 linux kernel
[3] MaliGraphics
[4] ARM Mali GPU
[6] [Linux RK Debian 10] chrome浏览器开启GPU硬件加速
[8] how to install Drivers to make OpenGL Programs
[9] Compiliing and Installiing mesa
[10] The mesa 3D Graphics Library
[11] mesa gitlab源码
[12] Enable OpenCL support on Debian/hikey960
[13] OpenCL安装过程记录
[14] http://developer.t-firefly.com/forum.php?mod=viewthread&tid=798
[15] http://bbs.t-firefly.com/forum.php?mod=viewthread&tid=321&extra=page%3D2

浙公网安备 33010602011771号