We use some essential cookies to make our website work.

We use optional cookies, as detailed in our cookie policy, to remember your settings and understand how you use our website.

3 posts • Page 1 of 1
oleg11
Posts: 25
Joined: Sun Feb 23, 2020 12:03 pm

[SOLVED] drmModeSetCrtc and framebuffer upscaling

Sat Feb 15, 2025 9:37 am

Hi, All!

I want to display 1280x800 framebuffer on 1920x1200 HDMI display. I can do it if HDMI display was initialized (in 1920x1200 mode) before my program starts. My program configures the following graphics output structure:

Code: Select all

root@raspberrypi:~# kmsprint
Connector 0 (33) HDMI-A-1 (connected)
 Encoder 0 (32) TMDS
 Crtc 3 (98) [email protected] 154.000 1920/48/32/80/+ 1200/3/6/26/- 60 (59.95) P|D
 Plane 3 (87) fb-id: 672 (crtcs: 3) 0,0 1280x800 -> 0,0 1920x1200 (XR24 AR24 AB24 XB24 RG16 BG16 AR15 XR15 RG24 BG24 YU16 YV16 YU24 YV24 YU12 YV12 NV12 NV21 NV16 NV61 RGB8 BGR8 XR12 AR12 XB12 AB12 BX12 BA12 RX12 RA12)
 FB 672 1280x800 XR24
Connector 1 (42) DPI-1 (connected)
 Encoder 1 (41) DPI
 Crtc 1 (74) [email protected] 71.107 1280/70/10/80/+ 800/10/3/10/+ 60 (60.00) P|D
 Plane 1 (63) fb-id: 672 (crtcs: 1) 0,0 1280x800 -> 0,0 1280x800 (XR24 AR24 AB24 XB24 RG16 BG16 AR15 XR15 RG24 BG24 YU16 YV16 YU24 YV24 YU12 YV12 NV12 NV21 NV16 NV61 RGB8 BGR8 XR12 AR12 XB12 AB12 BX12 BA12 RX12 RA12)
 FB 672 1280x800 XR24
So, both displays show the same framebuffer.

But, if I need to set CRTC mode using drmModeSetCrtc, it requires framebuffer parameter and passing my 1280x800 framebuffer results in ENOSPC error. If I allocate dummy FB with 1920x1200 size and pass it to drmModeSetCrtc everything works as expected. But I do not need that framebuffer for anything except mode set. I tried to set primary plane parameters before calling drmModeSetCrtc with the same result (I thought that plane scales data from the framebuffer and feeds it to the CRTC).

So, the questions are:
1. Are there any possibility (in the above scenario with FB upscaling) to change mode without allocation of the 1920x1200 FB for drmModeSetCrtc?
2. If not, when it is safe to deallocate that dummy FB (after plane primary parameters were set or only at the program finish/display removal)?

Also, if the HDMI display is disconnected (while my program is running) I see the following kmsprint output:

Code: Select all

root@raspberrypi:~# kmsprint
Connector 0 (33) HDMI-A-1 (disconnected)
 Encoder 0 (32) TMDS
 Crtc 3 (98) [email protected] 154.000 1920/48/32/80/+ 1200/3/6/26/- 60 (59.95) P|D
 Plane 3 (87) fb-id: 672 (crtcs: 3) 0,0 1280x800 -> 0,0 1920x1200 (XR24 AR24 AB24 XB24 RG16 BG16 AR15 XR15 RG24 BG24 YU16 YV16 YU24 YV24 YU12 YV12 NV12 NV21 NV16 NV61 RGB8 BGR8 XR12 AR12 XB12 AB12 BX12 BA12 RX12 RA12)
 FB 672 1280x800 XR24
Connector 1 (42) DPI-1 (connected)
 Encoder 1 (41) DPI
 Crtc 1 (74) [email protected] 71.107 1280/70/10/80/+ 800/10/3/10/+ 60 (60.00) P|D
 Plane 1 (63) fb-id: 672 (crtcs: 1) 0,0 1280x800 -> 0,0 1280x800 (XR24 AR24 AB24 XB24 RG16 BG16 AR15 XR15 RG24 BG24 YU16 YV16 YU24 YV24 YU12 YV12 NV12 NV21 NV16 NV61 RGB8 BGR8 XR12 AR12 XB12 AB12 BX12 BA12 RX12 RA12)
 FB 672 1280x800 XR24
So, the whole structure of the HDMI display data processing seems to be still active. Does it really continue supplying data to HDMI connector? If so, what should I do to stop it (I tried to set ACTIVE CRTC property to 0 as well as set connector CRTC_ID property to 0 with no kmsprint output change).

Thanks!
Last edited by oleg11 on Sat Feb 15, 2025 7:39 pm, edited 1 time in total.

oleg11
Posts: 25
Joined: Sun Feb 23, 2020 12:03 pm

Re: drmModeSetCrtc and framebuffer upscaling

Sat Feb 15, 2025 10:14 am

oleg11 wrote:
Sat Feb 15, 2025 9:37 am
Does it really continue supplying data to HDMI connector?
I found an answer to this question. The HDMI display has 59.9Hz VSync rate and DPI one 60Hz, so I was able to check the framerate changes (DRM synchronizes by the slower display when doing atomic FB switch on two displays). It looks like it is active even after HDMI connector was unplugged.

Also I found how to disable it:

Code: Select all

drmModeSetCrtc(drm_fd, crtc_id, 0, 0, 0, NULL, 0, NULL);

oleg11
Posts: 25
Joined: Sun Feb 23, 2020 12:03 pm

Re: drmModeSetCrtc and framebuffer upscaling

Sat Feb 15, 2025 5:28 pm

oleg11 wrote:1. Are there any possibility (in the above scenario with FB upscaling) to change mode without allocation of the 1920x1200 FB for drmModeSetCrtc?
I found all answers :) I can do what I need using atomic API.

So, the following code will configure HDMI connector/CRTC/plane to display 1280x800 framebuffer fb upscaled to 1920x1200:

Code: Select all

 uint32_t mode_blob_id;
 drmModeCreatePropertyBlob(gc->drm_fd, &connector->modes[0], sizeof(connector->modes[0]), &mode_blob_id);
 drmModeAtomicReq* req = drmModeAtomicAlloc();
 drmModeAtomicAddProperty(req, 33, 20, 98); //Connector.CRTC_ID
 drmModeAtomicAddProperty(req, 98, 23, mode_blob_id); //CRTC.MODE_ID
 drmModeAtomicAddProperty(req, 98, 22, 1); //CRTC.ACTIVE
 drmModeAtomicAddProperty(req, 87, 17, fb); //Plane.FB_ID
 drmModeAtomicAddProperty(req, 87, 20, 98); //Plane.CRTC_ID
 drmModeAtomicAddProperty(req, 87, 9, 0); //Plane.SRC_X
 drmModeAtomicAddProperty(req, 87, 10, 0); //Plane.SRC_Y
 drmModeAtomicAddProperty(req, 87, 11, 1280 << 16); //Plane.SRC_W
 drmModeAtomicAddProperty(req, 87, 12, 800 << 16); //Plane.SRC_H
 drmModeAtomicAddProperty(req, 87, 13, 0); //Plane.CRTC_X
 drmModeAtomicAddProperty(req, 87, 14, 0); //Plane.CRTC_Y
 drmModeAtomicAddProperty(req, 87, 15, 1920); //Plane.CRTC_W
 drmModeAtomicAddProperty(req, 87, 16, 1200); //Plane.CRTC_H
 drmModeAtomicCommit(gc->drm_fd, req, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
 drmModeAtomicFree(req); 
 drmModeDestroyPropertyBlob(gc->drm_fd, mode_blob_id);
The second piece will turn everything off:

Code: Select all

 drmModeAtomicReq* req = drmModeAtomicAlloc();
 drmModeAtomicAddProperty(req, 33, 20, 0); //Connector.CRTC_ID
 drmModeAtomicAddProperty(req, 98, 23, 0); //CRTC.MODE_ID
 drmModeAtomicAddProperty(req, 98, 22, 0); //CRTC.ACTIVE
 drmModeAtomicAddProperty(req, 87, 17, 0); //Plane.FB_ID
 drmModeAtomicAddProperty(req, 87, 20, 0); //Plane.CRTC_ID
 drmModeAtomicCommit(gc->drm_fd, req, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
 drmModeAtomicFree(req); 
Of cause "magic numbers" (currently get from the kmsprint -p) should be replaced by the IDs found with the help of the corresponding libdrm API calls and error checking should be added. But it should be already clear what to do.

3 posts • Page 1 of 1

Return to "Graphics programming"

AltStyle によって変換されたページ (->オリジナル) /