[BUG] start_preview() throws "ValueError: drmModeAddFB2 failed: Invalid argument" on DRM SPI cards
Using Raspbery Pi Camera Module 3, Raspberry Pi OS bookworm 64 bit lite with latest update on 21/3/2025 on raspberry pi zero 2w and (generic) elecrow 3.5in SPI 480x320 LCD screen.
With the following changes in config.txt:
dtoverlay=vc4-kms-v3d,nohdmi
dtoverlay=piscreen,speed=16000000,rotate=180,drm
Installed picamera2 using:
sudo apt install -y python3-picamera2 --no-install-recommends
Code:
from picamera2 import Picamera2, Preview
picam2 = Picamera2()
picam2.start_preview(Preview.DRM, x=0, y=0, width=480, height=320)
preview_config = picam2.create_preview_configuration({"size": (480, 320)})
picam2.configure(preview_config)
picam2.start()
Then the following occurs:
>>> picam2.start_preview(Preview.DRM, x=0, y=0, width=480, height=320)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3/dist-packages/picamera2/picamera2.py", line 582, in start_preview
preview = preview_table[preview](**kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/picamera2/previews/drm_preview.py", line 66, in __init__
self.fb = pykms.DumbFramebuffer(self.card, width, height, "XB24")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: drmModeAddFB2 failed: Invalid argument
Note that kmtest works. Also:
$ fbset
mode "480x320"
geometry 480 320 480 320 32
timings 0 0 0 0 0 0 0
rgba 8/16,8/8,8/0,0/0
endmode
$ kmsprint
Connector 0 (31) SPI-1 (connected)
Encoder 0 (35) NONE
Crtc 0 (34) [email protected] 0.001 480/0/0/0/? 320/0/0/0/? 0 (0.01) P|D
Plane 0 (32) fb-id: 36 (crtcs: 0) 0,0 480x320 -> 0,0 480x320 (RG16 XR24)
FB 36 480x320 XR24
Note that also get the same error but kmstest and kmsprint also works with dtoverlay=vc4-kms-v3d,nohdmi removed, where there is no console on the screen and produces just a single /dev/dri/card0 instead of /dev/dri/card1 as well.
Actually managed to make it work by hacking: /usr/lib/python3/dist-packages/picamera2/previews/drm_preview.py and changing self.fb = pykms.DumbFramebuffer(self.card, width, height, "XB24") to self.fb = pykms.DumbFramebuffer(self.card, width, height, "XR24")
so should be same as #1231
Already covered by #1231