概述
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 +0800fix network disk link cannot be opened
Signed-off-by: Yu Qiaowei cerf.yu@rock-chips.com
Change-Id: I7dae60823917713bb1a5e64bb47c894db5c44cc8
librga/CHANGELOG.mdCOPYINGdocs/ 文檔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-gccis not a full path to an existing compiler tool.Tell CMake where to find the compiler by setting either the environmentvariable "CC" or the CMake cache entry CMAKE_C_COMPILER to the full path tothe 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 environmentvariable "CXX" or the CMake cache entry CMAKE_CXX_COMPILER to the full pathto 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 configurationTOOLCHAIN_PATH=${SAMPLES_DIR}/../toolchains/toolchain_linux.cmake
-LIBRGA_PATH=${SAMPLES_DIR}/../build/build_linux/install/lib
+LIBRGA_PATH=${SAMPLES_DIR}/../libs/Linux/gcc-aarch64BUILD_DIR=build/build_linuxBUILD_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 okroot@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