[SOLVED] drmModeSetCrtc and framebuffer upscaling
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:
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:
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!
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
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
Thanks!
Last edited by oleg11 on Sat Feb 15, 2025 7:39 pm, edited 1 time in total.
Re: drmModeSetCrtc and framebuffer upscaling
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);
Re: drmModeSetCrtc and framebuffer upscaling
I found all answers :) I can do what I need using atomic API.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?
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);
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);
Return to "Graphics programming"
Jump to
- Community
- General discussion
- Announcements
- Other languages
- Deutsch
- Español
- Français
- Italiano
- Nederlands
- 日本語
- Polski
- Português
- Русский
- Türkçe
- User groups and events
- Raspberry Pi Official Magazine
- Using the Raspberry Pi
- Beginners
- Troubleshooting
- Advanced users
- Assistive technology and accessibility
- Education
- Picademy
- Teaching and learning resources
- Staffroom, classroom and projects
- Astro Pi
- Mathematica
- High Altitude Balloon
- Weather station
- Programming
- C/C++
- Java
- Python
- Scratch
- Other programming languages
- Windows 10 for IoT
- Wolfram Language
- Bare metal, Assembly language
- Graphics programming
- OpenGLES
- OpenVG
- OpenMAX
- General programming discussion
- Projects
- Networking and servers
- Automation, sensing and robotics
- Graphics, sound and multimedia
- Other projects
- Media centres
- Gaming
- AIY Projects
- Hardware and peripherals
- Camera board
- Compute Module
- Official Display
- HATs and other add-ons
- Device Tree
- Interfacing (DSI, CSI, I2C, etc.)
- Keyboard computers (400, 500, 500+)
- Raspberry Pi Pico
- General
- SDK
- MicroPython
- Other RP2040 boards
- Zephyr
- Rust
- AI Accelerator
- AI Camera - IMX500
- Hailo
- Software
- Raspberry Pi OS
- Raspberry Pi Connect
- Raspberry Pi Desktop for PC and Mac
- Beta testing
- Other
- Android
- Debian
- FreeBSD
- Gentoo
- Linux Kernel
- NetBSD
- openSUSE
- Plan 9
- Puppy
- Arch
- Pidora / Fedora
- RISCOS
- Ubuntu
- Ye Olde Pi Shoppe
- For sale
- Wanted
- Off topic
- Off topic discussion