RK3588 linux RGA初探
ansondroider 2024-08-11 16:37:01 阅读 90
概述
RGA (Raster Graphic Acceleration Unit)是一个独立的2D硬件加速器,可用于加速点/线绘制,执行图像缩放、旋转、bitBlt、alpha混合等常见的2D图形操作。
本文基于以下版本编写:
commit fb5f019ea0191ec1c34f49ac8be447ac8921aadd (HEAD -> main, origin/main, origin/HEAD)
Author: Yu Qiaowei cerf.yu@rock-chips.com
Date: Wed Apr 3 18:24:42 2024 +0800
fix network disk link cannot be opened
Signed-off-by: Yu Qiaowei cerf.yu@rock-chips.com
Change-Id: I7dae60823917713bb1a5e64bb47c894db5c44cc8
CHANGELOG.md
COPYING
docs/ 文档
include/ 头文件
libs/ so库
README.md*
samples/ 参考例子
toolchains/ 交叉编译链
tools/
基本使用
参考文档: docs/Rockchip_Developer_Guide_RGA_CN.md
软件支持库提供以下API,异步模式仅支持C++实现。
querystring: 查询获取当前芯片平台RGA硬件版本与功能支持信息,以字符串的形式返回。imcheckHeader: 校验当前使用头文件版本与librga版本差异。importbuffer_T: 将外部内存(dma_fd、虚拟地址、物理地址)导入RGA驱动内部,实现硬件快速访问物理连续/非物理连续的内存。releasebuffer_handle: 将外部buffer从RGA驱动内部解除引用与映射。wrapbuffer_handle: 快速封装图像缓冲区结构(rga_buffer_t)。imbeginJob:创建RGA图像处理任务。imendJob: 提交并执行RGA图像处理任务。imcancelJob: 取消并删除RGA图像处理任务。imcopy: 调用RGA实现快速图像拷贝操作。imcopyTask: 向RGA图像任务中添加快速图像拷贝操作。imresize: 调用RGA实现快速图像缩放操作。imresizeTask: 向RGA图像任务中添加快速图像缩放操作。impyramind: 调用RGA实现快速图像金字塔操作。imcrop: 调用RGA实现快速图像裁剪操作。imcropTask: 向RGA图像任务中添加快速图像裁剪操作。imtranslate: 调用RGA实现快速图像平移操作。imtranslateTask: 向RGA图像任务中添加快速图像平移操作。imcvtcolor: 调用RGA实现快速图像格式转换。imcvtcolorTask: 向RGA图像任务中添加快速图像格式转换。imrotate: 调用RGA实现快速图像旋转操作。imrotateTask: 向RGA图像任务中添加快速图像旋转操作。imflip: 调用RGA实现快速图像翻转操作。imflipTask: 向RGA图像任务中添加快速图像翻转操作。imblend: 调用RGA实现双通道快速图像合成操作。imblendTask: 向RGA图像任务中添加双通道快速图像合成操作。imcomposite: 调用RGA实现三通道快速图像合成操作。imcompositeTask: 向RGA图像任务中添加三通道快速图像合成操作。imcolorkey: 调用RGA实现快速图像颜色键操作。imcolorkeyTask: 向RGA图像任务中添加快速图像颜色键操作。imosd:调用RGA实现快速图像OSD字幕叠加。imosdTask:向RGA图像任务中添加快速图像OSD字幕叠加。imquantize: 调用RGA实现快速图像运算点前处理(量化)操作。imquantizeTask: 向RGA图像任务中添加快速图像运算点前处理(量化)操作。imrop: 调用RGA实现快速图像光栅操作。imropTask: 向RGA图像任务中添加快速图像光栅操作。imfill: 调用RGA实现快速图像填充操作。imfillArray: 调用RGA实现多组快速图像填充操作。imfillTask: 向RGA图像任务中添加快速图像填充操作。imfillTaskArray: 向RGA图像任务中添加多组快速图像填充操作。imrectangle: 调用RGA实现等距矩形边框快速绘制操作。imrectangleArray: 调用RGA实现多组等距矩形边框快速绘制操作。imrectangleTask: 向RGA图像任务中添加等距矩形边框快速绘制操作。imrectangleTaskArray: 向RGA图像任务中添加多组等距矩形边框快速绘制操作。immakeBorder: 调用RGA实现矩形边框快速绘制操作。immosaic:调用RGA实现快速图像马赛克遮盖。immosaicArray:调用RGA实现快速图像马赛克遮盖。immosaicTask:向RGA图像任务中添加快速图像马赛克遮盖。immosaicTaskArray:向RGA图像任务中添加快速图像马赛克遮盖。improcess: 调用RGA实现快速图像复合处理操作。improcessTask: 向RGA图像任务中添加快速图像复合处理操作。imcheck: 校验参数是否合法,以及当前硬件是否支持该操作。imsync: 用于异步模式时,同步任务完成状态。imconfig: 向当前线程上下文添加默认配置。
直接上手demo
图片缩放
samples/resize_demo/
├── cmake-android.sh
├── cmake-linux.sh
├── CMakeLists.txt
└── src
├── CMakeLists.txt
├── rga_resize_config_interpolation_demo.cpp
├── rga_resize_demo.cpp
├── rga_resize_rect_demo.cpp
└── rga_resize_uv_downsampling_demo.cpp
samples/resize_demo$ ./cmake-linux.sh
/work/devEnv/librga/samples/resize_demo/build/build_linux /work/devEnv/librga/samples/resize_demo
load /work/devEnv/librga/samples/resize_demo/../../toolchains/toolchain_linux.cmake
load /work/devEnv/librga/samples/resize_demo/../../libs/Linux/gcc-aarch64/librga.so
-- The C compiler identification is unknown
-- The CXX compiler identification is unknown
CMake Error at CMakeLists.txt:16 (project):
The CMAKE_C_COMPILER:
/home/yqw/workspace/linux/common/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-rockchip1031-linux-gnu-gcc
is not a full path to an existing compiler tool.
Tell CMake where to find the compiler by setting either the environment
variable "CC" or the CMake cache entry CMAKE_C_COMPILER to the full path to
the compiler, or to the compiler name if it is in the PATH.
CMake Error at CMakeLists.txt:16 (project):
The CMAKE_CXX_COMPILER:
/home/yqw/workspace/linux/common/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-rockchip1031-linux-gnu-g++
is not a full path to an existing compiler tool.
Tell CMake where to find the compiler by setting either the environment
variable "CXX" or the CMake cache entry CMAKE_CXX_COMPILER to the full path
to the compiler, or to the compiler name if it is in the PATH.
-- Configuring incomplete, errors occurred!
See also "/work/devEnv/librga/samples/resize_demo/build/build_linux/CMakeFiles/CMakeOutput.log".
See also "/work/devEnv/librga/samples/resize_demo/build/build_linux/CMakeFiles/CMakeError.log".
make: *** No targets specified and no makefile found. Stop.
make: *** No rule to make target 'install'. Stop.
原始的代码编译不过… 真坎坷! /home/yqw/workspace/ 这个路径应该是写这个demo的工程师的
修改下交叉编译链
git diff ../../toolchains/
diff --git a/toolchains/toolchain_linux.cmake b/toolchains/toolchain_linux.cmake
index f446557..aa5f9b3 100644
--- a/toolchains/toolchain_linux.cmake
+++ b/toolchains/toolchain_linux.cmake
@@ -1,5 +1,5 @@
-SET(TOOLCHAIN_HOME "/home/yqw/workspace/linux/common/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu")
-SET(TOOLCHAIN_NAME "aarch64-rockchip1031-linux-gnu")
+SET(TOOLCHAIN_HOME "/usr")
+SET(TOOLCHAIN_NAME "aarch64-linux-gnu")
# this is required
#SET(CMAKE_SYSTEM_NAME Linux)
samples/resize_demo$ ./cmake-linux.sh
[ 81%] Linking CXX executable rga_resize_rect_demo
/usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/ld: cannot find -lrga
collect2: error: ld returned 1 exit status
[ 90%] Linking CXX executable rga_resize_uv_downsampling_demo
make[2]: *** [src/CMakeFiles/rga_resize_demo.dir/build.make:90: src/rga_resize_demo] Error 1
make[1]: *** [CMakeFiles/Makefile2:210: src/CMakeFiles/rga_resize_demo.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....
[100%] Linking CXX executable rga_resize_config_interpolation_demo
/usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/ld: cannot find -lrga
collect2: error: ld returned 1 exit status
make[2]: *** [src/CMakeFiles/rga_resize_rect_demo.dir/build.make:90: src/rga_resize_rect_demo] Error 1
make[1]: *** [CMakeFiles/Makefile2:183: src/CMakeFiles/rga_resize_rect_demo.dir/all] Error 2
/usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/ld: cannot find -lrga
collect2: error: ld returned 1 exit status
make[2]: *** [src/CMakeFiles/rga_resize_uv_downsampling_demo.dir/build.make:90: src/rga_resize_uv_downsampling_demo] Error 1
make[1]: *** [CMakeFiles/Makefile2:156: src/CMakeFiles/rga_resize_uv_downsampling_demo.dir/all] Error 2
/usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/ld: cannot find -lrga
collect2: error: ld returned 1 exit status
make[2]: *** [src/CMakeFiles/rga_resize_config_interpolation_demo.dir/build.make:90: src/rga_resize_config_interpolation_demo] Error 1
make[1]: *** [CMakeFiles/Makefile2:129: src/CMakeFiles/rga_resize_config_interpolation_demo.dir/all] Error 2
make: *** [Makefile:130: all] Error 2
[ 27%] Built target utils_obj
[ 36%] Linking CXX executable rga_resize_config_interpolation_demo
/usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/ld: cannot find -lrga
collect2: error: ld returned 1 exit status
make[2]: *** [src/CMakeFiles/rga_resize_config_interpolation_demo.dir/build.make:90: src/rga_resize_config_interpolation_demo] Error 1
make[1]: *** [CMakeFiles/Makefile2:129: src/CMakeFiles/rga_resize_config_interpolation_demo.dir/all] Error 2
make: *** [Makefile:130: all] Error 2
找不到librga库, 项目的目录结构更新了, 代码还没改过来
git diff cmake-linux.sh
diff --git a/samples/resize_demo/cmake-linux.sh b/samples/resize_demo/cmake-linux.sh
index 3604521..a3f2f42 100755
--- a/samples/resize_demo/cmake-linux.sh
+++ b/samples/resize_demo/cmake-linux.sh
@@ -5,7 +5,7 @@ SAMPLES_DIR=${SCRIPT_DIR}/..
# The following options require configuration
TOOLCHAIN_PATH=${SAMPLES_DIR}/../toolchains/toolchain_linux.cmake
-LIBRGA_PATH=${SAMPLES_DIR}/../build/build_linux/install/lib
+LIBRGA_PATH=${SAMPLES_DIR}/../libs/Linux/gcc-aarch64
BUILD_DIR=build/build_linux
BUILD_TYPE=Release
编译成功后:
build/build_linux/install/bin/
├── rga_resize_config_interpolation_demo
├── rga_resize_demo
├── rga_resize_rect_demo
└── rga_resize_uv_downsampling_demo
丢板子里测试:
代码实现了 1280x720 缩放到 1920x1080 的RGBA 格式转化, 测试文件路径: librga/samples/sample_file/in0w1280-h720-rgba8888.bin
#测试程序
adb push build/build_linux/install/bin/rga_resize_demo /rga/
#测试文件
adb push ../sample_file/in0w1280-h720-rgba8888.bin /data/
进入到主板执行
root@rk3588:/rga# ./rga_resize_demo
rga_api version 1.10.1_[0]
rga_resize_demo running success!
open /data/out0w1920-h1080-rgba8888.bin and write ok
root@rk3588:/rga# ll /data/*bin
-rwxrwxrwx 1 root root 3.6M Jul 1 2024 /data/in0w1280-h720-rgba8888.bin
-rw-r--r-- 1 root root 8.0M Jan 1 00:13 /data/out0w1920-h1080-rgba8888.bin
RGBA 转换为 BMP:
# pull 输出图片
adb pull /data/out0w1920-h1080-rgba8888.bin out0w1920-h1080-rgba8888.rgba
# 使用convert 转换
# 注意: 确保你已经安装了ImageMagick
# sudo apt-get install imagemagick
convert -depth 8 -size 1920x1080 -colors 256 -colorspace sRGB out0w1920-h1080-rgba8888.rgba -alpha off out.bmp
注意事项
Q1.9:为什么当搭载8G DDR时,RGA效率较于4G时性能下降严重?
由于部分RGA1/RGA2的IOMMU仅支持最大32位的物理地址,而RGA Device Driver、RGA2 Device Driver中对于不满足硬件内存要求的调用申请,默认是通过swiotlb机制进行访问访问受限制的内存(原理上相当于通过CPU将高位内存拷贝至复合硬件要求的低位内存中,再交由硬件进行处理,处理完毕后再通过CPU将低位内存搬运回目标的高位内存上。)因此效率十分低下,通常在正常耗时的3-4倍之间浮动,并且引入受CPU负载影响。
“RGA_MMU unsupported Memory larger than 4G!”报错该如何解决?
该报错通常对应HAL层报错:
RgaBlit(1483) RGA_BLIT fail: Invalid argument
Failed to call RockChipRga interface, please use ‘dmesg’ command to view driver error log.
该报错标识当前配置的图像任务配置的内存无法满足当前匹配到的硬件核心对内存的要求,由于不同的硬件版本的RGA的IOMMU对内存位数的要求不同,当分配的内存超过对应硬件的限制时,则会出现该该报错,详细的不同硬件版本RGA的限制可见《Rockchip_Developer_Guide_RGA_CN》中的概述——设计指标小节。
当出现该报错时,通常有以下几种场景以及对应的解决方案:
在搭载多种RGA的芯片平台(例如RK3588搭载有2颗RGA3核心、1颗RGA2核心)上,没有使用importbuffer_xx接口获取handle,而是直接使用wrapbuffer_xx接口调用im2d api时:
由于没有使用importbuffer_xx来提前映射外部内存到RGA驱动内存,因此在实际任务匹配中无法提前获知内存是否不满足对应核心的限制,因此在高负载场景下可能会出现该报错,建议使用importbuffer_xx提前将外部内存导入到RGA驱动内部,避免该问题。
在搭载多种RGA的芯片平台(例如RK3588搭载有2颗RGA3核心、1颗RGA2核心)上,使用了importbuffer_xx接口获取handle,但是依旧存在该问题:
可以检查一下配置的图像任务的参数,确认是否配置了仅有RGA2核心(内存访问受限制的核心)支持的功能或格式,以RK3588为例,color fill功能和YUV422/420 planar格式均是RGA2核心特有的功能和格式,因此该场景下必须分配4G以内内存空间的内存调用RGA。
常见的分配4G内存方式可以查看以下示例代码:
<librga_souce_path>/samples/allocator_demo/src/rga_allocator_dma32_demo.cpp
<librga_souce_path>/samples/allocator_demo/src/rga_allocator_graphicbuffer_demo.cpp
如果使用的其他分配器,例如mpp_buffer、v4l2_buffer、drm_buffer等,请查询对应分配器是否支持限制分配4G以内内存空间内存,并按照对应方式申请复合RGA硬件要求的内存。
仅搭载一种RGA的芯片平台(例如仅搭载RGA2的RK3399、RK3568、Rk3566)上:
当芯片平台上仅搭载内存访问受限制的核心时,则调用RGA时必须申请符合搭载核心对内存要求的内存,解决方案同上场景2。
当使用DRM、malloc、new等不支持指定分配4G以内内存空间的内存的内存分配器时,也可以通过修改uboot的内存映射范围来解决。
uboot相关修改可以参考SDK文档中 uboot开发文档->Chapter-8 调试手段->修改DDR容量 ,将内存映射范围全局限制在0~4G内存空间以内即可。
参考
librga github
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。