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。
 
参考连接:
相关文章
相关标签/搜索