linux DRM/KMS 測試工具 modetest、kmscude、igt-gpu-tools (一)

這裏整理幾個在學習Linux DRM/KMS中用到的幾個工具,modetest、kmscude、igt-gpu-tools。

簡介:
modetest
是由libdrm提供的測試程序,能夠查詢顯示設備的支持情況,進行基本的顯示測試,以及設置顯示的模式。
 
kmscube
是由mesa3d提供和維護,這是一個基於 KMS/GBM/EGL/OPENGL ES2.0 測試用例。
kmscube is a little demonstration program for how to drive bare metal graphics without a compositor like X11, wayland or similar, using DRM/KMS (kernel mode setting), GBM (graphics buffer manager) and EGL for rendering content using OpenGL or OpenGL ES.
 
igt-gpu-tools
是一個測試DRM drivers的測試工具集
IGT GPU Tools is a collection of tools for development and testing of the DRM drivers.
 

 
測試環境和編譯環境:
如未特別註明,全部的程序編譯和測試均是在以下環境中進行的:
硬件環境:raspberry Pi 3 Model B
仍將環境:Linux alarm 5.6.13-1-ARCH #1 SMP Sat May 16 21:58:40 MDT 2020 aarch64 GNU/Linux

 
modetest
 
代碼編譯:
解壓代碼後,進入目錄執行:
 
# ./configure
# Make -j4
編譯完成後會在目錄libdrm-2.4.100/tests/modetest下生成 modetest 執行文件。
 

 
modetest示例
modetest的運行須要root權限。
 
首先這裏給出一組顯示示例,命令參數以下:
 
./modetest -M vc4 -D 0 -a -s 32@140:1920x1080  -P 173@140:1920x1080 -Ftiles
 
命令執行的console輸出:
@alarm /h/a/w/l/l/t/mocdetest# ./modetest -M vc4 -D root -a setting mode 192øx1Ø8Ø-6ØHz on connectors 32, crtc 140 testing 192øx1Ø8Ø@XR24 on plane 173, crtc 140 -Ftiles
 
 
程序運行效果以下,經過HDM鏈接的顯示器整屏的顯示了漸變的斜條紋:
 
若是你運氣不錯,那麼你能看到與我相同的顯示效果,可是若是(likely())運氣差了點,不要緊,接下來會詳細介紹modetest這些參數的由來。
 

 
首先經過--help參數能夠查看modetest支持的所有選項,以下:
 
./modetest --help
usage: /home/alarm/workspace/linux/libdrm-2.4.100/tests/modetest/.libs/lt-modetest [-acDdefMPpsCvw]
 
 
Query options:
 
 
    -c    list connectors
    -e    list encoders
    -f    list framebuffers
    -p    list CRTCs and planes (pipes)
 
 
Test options:
 
 
    -P <plane_id>@<crtc_id>:<w>x<h>[+<x>+<y>][*<scale>][@<format>]    set a plane
    -s <connector_id>[,<connector_id>][@<crtc_id>]:<mode>[-<vrefresh>][@<format>]    set a mode
    -C    test hw cursor
    -v    test vsynced page flipping
    -w <obj_id>:<prop_name>:<value>    set property
    -a     use atomic API
    -F pattern1,pattern2    specify fill patterns
 
 
Generic options:
 
 
    -d    drop master after mode set
    -M module    use the given driver
    -D device    use the given device
 
 
    Default is to dump all info.
 
能夠看到參數一共分爲3類。
Query options:提供查詢操做,用於列舉出connectorsencodersframebuffersCRTCs and planes,未指定參數時默認輸出全部信息。
Test options:設定顯示測試的參數。
Generic options: 指定打開設備節點,DRM/KMS對用戶層來講是一個標準的linux字符設備,其設備節點路徑爲/dev/dri/cardX/dev/dri/renderX(之全部有兩個設備節點這,涉及到DRM-Master 和 client相關的內容,這裏能夠簡單的認爲它們表明用一個設備
 
如今咱們來看看如何實現一個這樣的需求:經過HDMI鏈接的顯示器輸出一副分辨率爲1920X1080pattern圖像。
這個需求很明確,經過HDMI輸出分辨率爲1920X1080的圖像,Linux DRM/KMS 內核中和顯示組件以下圖所示:
 
Userspace-Created drm framebuffer 2 drm framebuffer I Static Objects drm_plane B drm crtc drm encoder A drm_plane A drm encoder B Hotpluggable drm connector A drm connector B
咱們要作的就是找出一組connectorsencodersframebuffersCRTCs planes的一個組合,使其能完成咱們的需求,步驟以下:
 
1. 找出與HDMI 相鏈接的connector
2在找到connectors後,要找出可與connector匹配的encoder
3. 找到connectorencoder可用的CRTC
4. CRTC配置合適plane
5. plane建立framebuffers,指定framebuffer大小,並填充pattern圖像,framebuffer是惟一有用戶層建立的內核對象,其他4個對象均是在DRM driver加載時註冊的。
 
這裏所謂的「找到」,就是獲取各個組件在內核中的id號,即handle值。
handle有點像文件描述符,是一個32bits的整數,某個linux DRM/KMS內核對象經過handle導出,並在接收到用戶的handle後找到該內核對象
 
首先來找出與HDMI相關的connector,前面提到modetest具備查詢功能,而參數-c  list connectors能列舉出因此的connector,查詢結果以下:
 
sudo ./modetest -M vc4 -c
Connectors:
id    encoder    status        name        size (mm)    modes    encoders
32    31    connected    HDMI-A-1           550x310        39    31
modes:
    name refresh (Hz) hdisp hss hse htot vdisp vss vse vtot)
  1920x1080 60 1920 2008 2052 2200 1080 1084 1089 1125 148500 flags: phsync, pvsync; type: preferred, driver
...
props:
    20 CRTC_ID:
        flags: object
        value: 140
...
47    0    unknown    composite-1        0x0        1    46
...
 
輸出了兩組connector的詳細(原始log較長,這裏只截取關鍵部分),從log中的關鍵字可知,id=32connector是與HDMI相鏈接的,而該connector是與id=31encoder相連的,而且經過後面的props列表能夠當前鏈接的CRTC_ID=140. modes列表這列出了connector支持的所有參數配置,即:
 
CRCT(ID=140) --> ENCODER(ID=31) --> CONNECTED(ID=32) --> HDMI
讓咱們來回顧一下以前的測試命令:
 
./modetest -M vc4 -D 0 -a -s 32@140:1920x1080  -P 173@140:1920x1080 -Ftiles
 
對照一下modetest的參數項: -s  <connector_id>[,<connector_id>][@<crtc_id>]:<mode>[-<vrefresh>][@<format>]
connector_id = 32crtc_id =140mode = 1920x1080encoderconnector一般是一一對應的,在內核中這二者通常也是一同註冊的,並經過函數drm_connector_attach_encoder()關聯在一塊兒。
mode咱們選擇了  1920x1080。
因此 connector_id、crtc_id、mode就是這樣來的。
 
列出 encoder
./modetest -M vc4 -e
Encoders:
id        crtc        type        possible crtcs        possible clones        
31        140        TMDS        0x00000004        0x00000000
46        0          TVDAC        0x00000004        0x00000000
52        0           Virtual        0x00000002        0x00000000
 

 
接下里咱們分析-P這個參數的設定,前面已經知道connector_id=32是與crtc_id=140組合的,接下來咱們須要爲crtc_id=140匹配一個可用的plane id
列舉CRCTPLANE的命令以下(這裏省略了不少內容,由於raspberry Pi 3vc4 driver支持3CRCT,每一個CRTC又支持10plane,因此輸出內容較多):
 
./modetest -M vc4 -D 0 -p
CRTCs:
id        fb        pos        size
58        0        (0,0)        (0x0)
99        0        (0,0)        (0x0)
140        178        (0,0)        (1920x1080)
1920x1080 60 1920 2008 2052 2200 1080 1084 1089 1125 148500 flags: phsync, pvsync; type: preferred, driver
Planes:
id        crtc        fb        CRTC x,y        x,y        gamma size         possible crtcs
173        0           0        0,0             0,0        0                    0x00000004
 
這裏我選擇了planes_id=173,選擇的依據是possible crtcs = 0x00000004,即bit2=1,表示該plane可用於第3crcts
如何理解這裏的第3個呢?前面說了CRCT都是經過id來標識的,第3個與crtc=140是關聯不上的。
簡單的理解是按照上述命令輸出的CRCT信息順序編號,好比第3crctid=140
深層次的緣由是kernel中,每成功註冊成功一個CRCT後,會把它加入到mode_config->crtc_list中,加入的同時它會得到一個index,而這個index基本上就是按CRCT註冊的前後順序來分配的了(crtc->index = config->num_crtc++)。
最後回到咱們下面這個命令:
 
./modetest -M vc4 -D 0 -a -s 32@140:1920x1080  -P 173@140:1920x1080 -Ftiles
 
-P選項的命令格式:-P <plane_id>@<crtc_id>:<w>x<h>[+<x>+<y>][*<scale>][@<format>]
plane_id=173, crct_id=140
<w>x<h>=1920x1080設置分辨率。
設置後咱們的鏈接情況以下:
 
PLANE(ID=173, W=1920, H=1080)
      |
    \ | /
CRCT(ID=140) --> ENCODER(ID=31) --> CONNECTED(ID=32) --> HDMI
 
 
buffer的建立是經過函數完成的,大小是從plane相匹配。
framebuffer是在modetest內部分配的,會根據設定的分辨率經過ioctl向驅動程序分配。
 
剩下的-a -Ftiles兩項,
-a use atomic API「
-F是指填充一種pattern,後面的值須要在modetest的源碼裏找,其餘可用的值 tiles、smpte、plain、gradient。
 
參考連接:
相關文章
相關標籤/搜索