runcommand: add new 'kms' videomode utility
Replaced the mesa-drm scriptmodule and the modetest utility with a new program, based on the kmsxx project.
- Added a new scriptmodule to install the new modesetting utilities:
- kmsblank - blank screen(s)
- kmstest - set modes and planes and show test pattern on crtcs/planes, and test page flips
- kmsprint(-rp) - print information about DRM objects (connectors, encoders, video modes, crtcs)
- fbtest - show info about the console framebuffer
It's based on https://github.com/tomba/kmsxx, forked to add a custom kmsprint-rp utility which we can use in runcommand instead of modetest.
Advantages over modetest:
- it's based on a simpler standalone project and not part of Mesa, less code.
- it's has a modularized C++ API for working with Cards/Encoders/Connectors/CRTCs/etc, modeled after the DRM API entities
- works with any DRM/KMS card and doesn't have any card specific code like
modetest - it's faster than modetest (both when KMS is enabled or disabled)
- can print the analog video modes when the 'composite' output is enabled for RPI. I think
modetestcan be modified to support it, but withkmsxxis working without any special handling.
Note that a Debian package of the kmsxx upstream project is packaged in Rasberry PI OS (as kms++-utils), but it's not part of Debian. Packaging it as part of RetroPie helps with:
- integration with
runcommand, since we can run our own custom query utility - resolution switching on other KMS platforms
- Changes to
runcommand:
- replaced
modetestwithkmsprint-rp. The format for the modeline printing has changed a bit, to make it easier to parse and integrate the result inruncommand. In addition to the rounded/integral refresh rate, there's a new column to show a decimal refresh rate; the [p|n][h|v]sync flags have been reformatted as [h|v]sync[-|+]. - simplified the modeline parsing for KMS, taking advantage of the new format
- refresh rate (from KMS modeline) is now be a decimal number (.2f), supported by RetroArch
NOTE: set to draft to do more testing for now. Functionally it should work fine, I think some improvements can be made to:
- parsing the video modes (
get_all_kms_..) callsreadtwice on the same data, I think we can remove one of them. kmsxxinstallation - maybe we can ship thekms++shared library with the module, instead of statically linking it with every executable.
Thank you - looks good.
OK, improvements done for now. I've done a few more tests and it seems to be working fine. Used a Pi3/Buster, Pi4/Bullseye.
While testing, I noticed 2 things:
-
RetroArch's DRM code lists fewer video modes than
kmsprint(-rp)does, because it's not setting theDRM_CLIENT_CAP_ASPECT_RATIOclient capability (see here and previously here for our utilities). This is entirely up to the display (most likely on TVs with CEA/DMT modes). That's not something new, sincemodetestdid the same thing and we've added the same capability in our SDL fork aswell (to have matching MODE_ID s). In practice I don't think that's a problem, since the missing modes are just duplicates of existing modes but with aspect ratio info added in the DRM videomode's flags (and printed by our utility). Since we set only thevideo_parameters for width, height and refresh rate, this should be fine - that video mode should be valid in RetroArch's DRM list of video modes. -
When listing the
compositevideo modes (enabled withdtoverlay=vc4-kms-v3d,composite=1on newer firmware/kernels), the refresh rate is different in the video modes detected by RetroArch from the ones listed bykmsprint. This is a new thing and needs a bit more testing (need to connect an actual composite display on the Pi4). As mentioned in the initial message,modetestwhouldn't prin anything in this situation.
OK, so I had the opportunity to - finally - test the setup with a Composite cable on a Pi4, with a PAL TV.
Some notes so far :
- in addition to adding
compositeto the KMS overlay inconfig.txt(dtoverlay=vc4-kms-v3d,composite), to boot a PAL video mode there needs to be an additional option added tocmdline.txt. Eithervideo=Composite-1:PAL' orvideo=Composite-1:720x576@50i/video=Composite-1:720x288@50are ok. Usingkmsprint -p` will display the current video mode and encoding (NTSC/PAL). - PAL-60 is obtained by specifying an NTSC video mode and PAL as
tv-modein the options forvideo:Composite-1:720x480@60ie,tv_mode=PAL. Verifying withkmsprint -pshows the NTSC video mode and i kmsprintandkmsprint-rpwill list both NTSC/PAL video modes with 4 video modes in total to switch to/from (2 interlaces + 2 progressive).- SDL/RetroArch will succesfully initialize the video and also neither the DRM Connector does not appear as 'connected', but for Composite (since there's no EDID/DDC present) the state of the connector appears as 'unknown'. In order to for the DRM connector to show up as 'connected', the
evideo mode parameter needs to be set (see [1]). So something like:video=Composite-1:720x576@50ieto force PAL interlaced orvideo=Composite-1:720x480@60iefor NTSC. It seems that on Pi5 the 'force' option is not needed, but Pi4 (and possibly the lower models which rely on the VC4 VEC for Composite) does need it. - overscan can be added with the 'margin_' parameters (see again [1]) and as far as I tested all 4 margins need to be set. In addition to the
evideo mode parameter, themone needs also added, so thecmdline.txtaddition is more likely to show as:video=Composite-1:720x480@60ime,margin_top=10,margin_bottom=20,margin_left=5,margin_right=30
NB: margin values are TV dependant, the values above are just examples.
So far resolution switching is not 100% there and needs futher investigation:
- SDL can't switch to 2 of the 4 video modes - i.e. booting on PAL60 and trying to switch to 240p throws an error.
- RetroArch also seems to be unable to switch to 2 of the 4 modes - i.e. boot with PAL60, but again trying to switch to (NTSC) 480i will throw a KMS initialization error.
Swiching to 240p doesn't crash, but the image is scaled down horizontally to almost 50%, which is not correct. Using
kmstestto test the same video mode (NTSC, 240P) doesn't exhibit the same stretching, so I suspect something may be up with the KMS video mode selection in RetroArch.
[1] https://docs.kernel.org/fb/modedb.html
Some more testing, RetroArch only.
- RetroArch's image stretching happens only on 240p/288p. The stretching is done due to the lower vertical resolution and RetroArch defaulting to 'core aspect ratio' (close to 4:3), hence reducing the image (width) on the horizontal. Tests were run with PAL's interlaced mode, so we get the 'hightest' vertical resolution, and setting the resolution with
runcommandseems to work without any crashes so far. FWIW, the 4 composite video modes exposed by DRM/KMS on the Pi4 are:Mode 0: (720x480i) 720 x 480, 59.940060 Hz (NTSC 480i) Mode 1: (720x576i) 720 x 576, 50.000000 Hz (PAL 576i) Mode 2: (720x288) 720 x 288, 50.080128 Hz (PAL 288p) Mode 3: (720x240) 720 x 240, 60.054451 Hz (PAL 240p)
As far as resolution switching and mode detection, there's no issue with the new kmsxx based utility.
OK, for now there's no need for more testing as far as resolution switching is concerned, so I'll remove the draft status. I'll re-test again an upgrade scenario (Pi4 KMS/Pi3 tvservice) to see if we may have to add some additional checks or a fallback (?) for issues after the upgrade. Or maybe add the package to the base install first and trigger the update later on ?
Thanks for this. I will build a binaries for buster/bullseye before I merge the PR.
Binaries should now be available for buster/bullseye.
OK, I tested a the 'update' (via _update_hook and also install_bin) and it seems to update fine.
Thank you!