OpenHarmony富設(shè)備移植指南(6.3)GPU調(diào)試經(jīng)驗(yàn)分享
??想了解更多關(guān)于開(kāi)源的內(nèi)容,請(qǐng)?jiān)L問(wèn):??
??51CTO 開(kāi)源基礎(chǔ)軟件社區(qū)??
本人使用樹(shù)莓派4和小米6進(jìn)行OpenHarmony適配GPU時(shí)產(chǎn)生過(guò)許多問(wèn)題,這里回顧一下我移植GPU的過(guò)程,同時(shí)也做一些總結(jié)和經(jīng)驗(yàn)分享,希望大家看過(guò)之后能少走一些彎路。
1、樹(shù)莓派4GPU移植
樹(shù)莓派4的GPU驅(qū)動(dòng)組成比較復(fù)雜,在Linux的gpu驅(qū)動(dòng)目錄中drm目錄下存放著vc4和v3d兩個(gè)目錄,vc4既包含Display驅(qū)動(dòng)也包含GPU驅(qū)動(dòng),主要用于樹(shù)莓派3及之前的SoC;而v3d則只包含gpu驅(qū)動(dòng),專用于樹(shù)莓派4。由于vc4和v3d的Display硬件差異不大,為了讓樹(shù)莓派4最大化利用vc4現(xiàn)有的Display驅(qū)動(dòng),樹(shù)莓派驅(qū)動(dòng)的開(kāi)發(fā)者并沒(méi)有分離代碼,所以樹(shù)莓派的GPU驅(qū)動(dòng)需要同時(shí)啟用vc4和v3d。同時(shí),我在查閱mesa3d的文檔中有關(guān)v3d的描述中也有類似的說(shuō)明,原文如下:
The V3D Mesa drivers communicate directly with the V3D kernel DRM driver for scheduling GPU commands. Additionally, on the Raspberry Pi 4, the kernel uses the VC4 DRM driver for display support, so Mesa exposes a vc4_dri.so using the kmsro helpers to do behind-the-scenes buffer management between the two kernel drivers, while executing rendering on the V3D kernel module.
查資料時(shí)我看到樹(shù)莓派的mesa3d驅(qū)動(dòng)還需要kmsro,當(dāng)時(shí)我不太理解,經(jīng)過(guò)好幾天的網(wǎng)上搜索,最終抱著不確定的心態(tài),使用了以下的參數(shù)編譯mesa:
在復(fù)制編譯好的lib文件加入編譯框架,并在config.json中設(shè)置啟用gpu。
編譯燒錄之后運(yùn)行黑屏,受到SIG-OpenGfxDrv群里的大神指導(dǎo),調(diào)試gpu可以先設(shè)置cpu合成,gpu渲染的模式,即保持config.json中設(shè)置啟用gpu,同時(shí)修改foundation/graphic/graphic_2d/rosen/modules/render_service/core/pipeline/rs_base_render_engine.cpp中的NeedForceCPU函數(shù),強(qiáng)制使用cpu合成。
再次編譯,燒錄運(yùn)行,發(fā)現(xiàn)屏幕能點(diǎn)亮,但是顯示異常,經(jīng)過(guò)各種探索,仍然無(wú)法解決,第一次移植失敗。
經(jīng)過(guò)斷斷續(xù)續(xù)的查找資料,對(duì)比驗(yàn)證,找到了驗(yàn)證gpu工作的方法,就是通過(guò)opengl的api調(diào)用一個(gè)簡(jiǎn)單的gpu繪圖程序,結(jié)果仍然撕裂,這時(shí)我基本確定問(wèn)題不在編譯參數(shù)了。
接口能調(diào)用成功,但是顯示異常,這種bug不會(huì)報(bào)錯(cuò),沒(méi)有圖形相關(guān)經(jīng)驗(yàn)的我根本定位不到原因,最終我想到樹(shù)莓派4有安卓的移植項(xiàng)目,隨后查到安卓也是用mesa3d,然后我找到了兩個(gè)樹(shù)莓派4移植項(xiàng)目, 【lineage-rpi】和【 android-rpi】,對(duì)比了兩個(gè)倉(cāng)中的mesa3d代碼之后,終于給我在【 android-rpi】中發(fā)現(xiàn)了關(guān)鍵代碼,樹(shù)莓派4適配安卓?jī)H僅修改了下面這些地方:
然后再看OpenHarmony的mesa3d的代碼,之前我對(duì)比過(guò)platform_ohos.c跟platform_android.c的區(qū)別,差異是有,但是總體比較類似,同時(shí)我也發(fā)現(xiàn)了注釋中有說(shuō)明platform_ohos是基于platform_android修改。
經(jīng)過(guò)對(duì)比,我把a(bǔ)ndroid-rpi對(duì)mesa的修改手動(dòng)同步到了OpenHarmony的mesa中,修改如下。
經(jīng)過(guò)重新編譯,燒錄,測(cè)試?yán)咏K于能夠正常顯示,前后歷時(shí)四個(gè)多月,從3.2beta3跨到了3.2beta4。
cpu合成+cpu渲染組合下,調(diào)用OpenGLApi進(jìn)行三角形的繪制:
啟用GPU渲染后,能夠感知到幀率有提升,打個(gè)比方,cpu合成+cpu渲染在豎屏旋轉(zhuǎn)下只有7幀/秒,cpu合成+gpu渲染下能達(dá)到14幀/秒,有提升但是仍然卡頓嚴(yán)重,經(jīng)過(guò)多方求教仍未解決問(wèn)題。
在初步打通gpu調(diào)用之后,夜里腦子仍在思考著問(wèn)題的解決辦法,不斷排列組合,最終想到了3.2beta4的一個(gè)公告內(nèi)容,RS側(cè)支持GPU合成,然后又聯(lián)系到了幾個(gè)月前我看到過(guò)的一個(gè)關(guān)于gpu的issue,描述到了【graphic_standard_feature_rs_enable_eglimage】這個(gè)參數(shù),最后爬起來(lái)把這個(gè)參數(shù)設(shè)置成了true,編譯燒錄一套走起,最后居然給干成了,流暢度可感知的達(dá)到了60fps那種流暢。
通過(guò)樹(shù)莓派4適配GPU的經(jīng)歷,我總結(jié)出GPU適配的思路如下:
1.不啟用GPU功能,在CPU合成+CPU渲染的環(huán)境下,確認(rèn)GPU驅(qū)動(dòng)正常工作。
2.啟用部分GPU功能,在CPU合成+GPU渲染的環(huán)境下,確認(rèn)GPU能正確渲染。
3.啟用GPU合成+GPU渲染,加速OpenHarmony圖形顯示。
同時(shí)OpenHarmony開(kāi)源的GPU移植也可以參考安卓方面的移植。
2、小米6GPU移植
小米6的gpu是Adreno 540,經(jīng)過(guò)網(wǎng)上搜索資料mesa驅(qū)動(dòng)對(duì)應(yīng)的名字是freedreno,所以編譯參數(shù)對(duì)應(yīng)為:
但是編譯燒錄之后運(yùn)行簡(jiǎn)單的測(cè)試gpu程序始終無(wú)法運(yùn)行,signal 11程序崩潰了。
通過(guò)/data/log/faultlog/temp下崩潰日志確認(rèn)build_id_find_nhdr_callback存在問(wèn)題。
通過(guò)在函數(shù)內(nèi)部加print打印的方式,對(duì)比分析之后確認(rèn)是offset計(jì)算不正確,最后我意外發(fā)現(xiàn)了OpenHarmony的【third_party_libunwind】有修改過(guò)build-id,經(jīng)過(guò)查看pr提交發(fā)現(xiàn)了以下關(guān)鍵代碼,原來(lái)是oh的編譯框架在編譯出的elf文件頭增加了一個(gè)非標(biāo)準(zhǔn)的note段,mesa使用標(biāo)準(zhǔn)的方式去解析note內(nèi)容導(dǎo)致偏移量計(jì)算出錯(cuò),需要處理一下偏移量問(wèn)題,然而mesa3d這個(gè)開(kāi)源gpu驅(qū)動(dòng)長(zhǎng)久沒(méi)人維護(hù)了,這個(gè)問(wèn)題一直沒(méi)有暴露出來(lái),這給我碰到了。。。同步修改之后解決調(diào)用崩潰問(wèn)題。
同時(shí)接口調(diào)用也能正常顯示了。
但是當(dāng)我進(jìn)行移植第二步,CPU合成+GPU渲染時(shí)黑屏,無(wú)法顯示內(nèi)容,又是一番折騰,加打印然后調(diào)試,最后發(fā)現(xiàn)關(guān)鍵代碼,freedreno中有強(qiáng)制設(shè)置對(duì)齊。
在hilog中發(fā)現(xiàn)Assertion failed。
查看源碼發(fā)現(xiàn)a5xx系的頭文件中有pitch的驗(yàn)證,【&0x3f】相當(dāng)于判斷能否被64整除。
然后我往前找到buffer設(shè)置的某個(gè)地方嘗試著把pich強(qiáng)制64對(duì)齊,終于能顯示出圖像。
不黑屏了,但是仍然顯示不正常,很明顯能感知到是長(zhǎng)度沒(méi)有對(duì)齊導(dǎo)致錯(cuò)位了。
最終在SIG-OpenGfxDrv群里的lhl大神指導(dǎo)下,修改display適配層中的WIDTH_ALIGN參數(shù)為64,成功解決顯示問(wèn)題。
確認(rèn)CPU合成+GPU渲染顯示能正常工作之后,啟用GPU合成+GPU渲染,成功運(yùn)行,小米6終于適配GPU成功。
樹(shù)莓派4和小米6的GPU適配,從代碼量來(lái)說(shuō),適配代碼真的很少,但是又異常困難,在此記錄一下我走過(guò)的坑,希望我走過(guò)的坑,后來(lái)者不用再掉下去。
??想了解更多關(guān)于開(kāi)源的內(nèi)容,請(qǐng)?jiān)L問(wèn):??