RetroPie-Setup icon indicating copy to clipboard operation
RetroPie-Setup copied to clipboard

runcommand: add new 'kms' videomode utility

Open cmitu opened this issue 1 year ago • 3 comments

Replaced the mesa-drm scriptmodule and the modetest utility with a new program, based on the kmsxx project.

  1. 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 modetest can be modified to support it, but with kmsxx is 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
  1. Changes to runcommand:
  • replaced modetest with kmsprint-rp. The format for the modeline printing has changed a bit, to make it easier to parse and integrate the result in runcommand. 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

cmitu avatar Jan 23 '24 07:01 cmitu

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_..) calls read twice on the same data, I think we can remove one of them.
  • kmsxx installation - maybe we can ship the kms++ shared library with the module, instead of statically linking it with every executable.

cmitu avatar Jan 23 '24 07:01 cmitu

Thank you - looks good.

joolswills avatar Jan 23 '24 17:01 joolswills

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:

  1. RetroArch's DRM code lists fewer video modes than kmsprint(-rp) does, because it's not setting the DRM_CLIENT_CAP_ASPECT_RATIO client 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, since modetest did 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 the video_ 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.

  2. When listing the composite video modes (enabled with dtoverlay=vc4-kms-v3d,composite=1 on newer firmware/kernels), the refresh rate is different in the video modes detected by RetroArch from the ones listed by kmsprint. 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, modetest whouldn't prin anything in this situation.

cmitu avatar Jan 23 '24 17:01 cmitu

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 composite to the KMS overlay in config.txt (dtoverlay=vc4-kms-v3d,composite), to boot a PAL video mode there needs to be an additional option added to cmdline.txt. Either video=Composite-1:PAL' or video=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-mode in the options for video: Composite-1:720x480@60ie,tv_mode=PAL. Verifying with kmsprint -p shows the NTSC video mode and i
  • kmsprint and kmsprint-rp will 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 e video mode parameter needs to be set (see [1]). So something like: video=Composite-1:720x576@50ie to force PAL interlaced or video=Composite-1:720x480@60ie for 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 e video mode parameter, the m one needs also added, so the cmdline.txt addition 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 kmstest to 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

cmitu avatar Mar 19 '24 13:03 cmitu

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 runcommand seems 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.

cmitu avatar Mar 21 '24 14:03 cmitu

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 ?

cmitu avatar Apr 24 '24 12:04 cmitu

Thanks for this. I will build a binaries for buster/bullseye before I merge the PR.

joolswills avatar Apr 24 '24 16:04 joolswills

Binaries should now be available for buster/bullseye.

joolswills avatar Apr 24 '24 18:04 joolswills

OK, I tested a the 'update' (via _update_hook and also install_bin) and it seems to update fine.

cmitu avatar Apr 25 '24 17:04 cmitu

Thank you!

joolswills avatar Apr 25 '24 17:04 joolswills