Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a DRM/KMS backend #135

Merged
merged 15 commits into from
Aug 12, 2023
Merged

Add a DRM/KMS backend #135

merged 15 commits into from
Aug 12, 2023

Conversation

notgull
Copy link
Member

@notgull notgull commented Jul 15, 2023

This adds a DRM/KMS based backend to the system, as per #42. This system finds a CRTC and a connector, then uses that to create a frame buffer and a DUMB buffer that it can render to.

All of this is untested, hence the draft status.

I'm not going to be the maintainer for this backend, as I'm self-imposing a limit of two backends on myself. If anyone else with DRM/KMS experience or a motivating use case wants to maintain this backend, let me know. Otherwise I've marked it as unmaintained.

Closes #42

notgull and others added 5 commits July 14, 2023 20:17
This backend uses DUMB buffers to render to the CRTC.

cc #42
Signed-off-by: John Nunley <[email protected]>
Signed-off-by: John Nunley <[email protected]>
@notgull
Copy link
Member Author

notgull commented Aug 8, 2023

I've tested this on my computer and it seems to work for my use case, so I think it's ready.

@notgull notgull marked this pull request as ready for review August 8, 2023 21:41
@notgull notgull requested a review from john01dav as a code owner August 8, 2023 21:41
@notgull notgull requested review from ids1024 and removed request for john01dav August 8, 2023 21:41
Copy link
Contributor

@tronical tronical left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome stuff, btw! Two small comments inside.

src/kms.rs Outdated Show resolved Hide resolved
src/kms.rs Outdated Show resolved Hide resolved
src/kms.rs Outdated Show resolved Hide resolved
#[inline]
pub fn pixels(&self) -> &[u32] {
// drm-rs doesn't let us have the immutable reference... so just use a bunch of zeroes.
// TODO: There has to be a better way of doing this!
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, the BorrowStack hack would work here.

But it looks like DumbMapping is already just a wrapper around a &'a mut [u8], so could just open a PR for drm-rs to implement AsRef<[u8]> in addition to the AsMut<[u8]> implementation.

src/kms.rs Show resolved Hide resolved
Signed-off-by: John Nunley <[email protected]>
I was previously using the wrong framebuffer to page flip. This also
adds an implementation of buffer aging.

Signed-off-by: John Nunley <[email protected]>
@notgull
Copy link
Member Author

notgull commented Aug 11, 2023

drm_example

Tested on my laptop

Apparently I was setting up the connectors wrong.

Signed-off-by: John Nunley <[email protected]>
@notgull notgull requested a review from ids1024 August 11, 2023 01:25
@ids1024
Copy link
Member

ids1024 commented Aug 11, 2023

page_flip only queues a page flip. If an application were presenting buffers repeatedly without waiting, I believe it could overwrite a buffer while/before it appears on screen.

So I believe like on Wayland, buffer_mut should wait for buffer release. I guess it would have to poll the device fd, and use drm::control::device::receive_events to see if it's gotten Event::PageFlip yet.

...but would Winit or another "windowing" backend using DRM also poll the same fd? Is there any way to manage this?

@ids1024
Copy link
Member

ids1024 commented Aug 11, 2023

The example currently fails on the laptop I'm using since it has an Nvidia card, which for some reason is card0, while the only connected connector is on the iGPU, card1.

There isn't a good way to determine the right output, and the display probably shouldn't try to deal with setting all connected outputs, but maybe it should iterate over cards and chose the first one it finds a connector on?

@notgull
Copy link
Member Author

notgull commented Aug 11, 2023

page_flip only queues a page flip. If an application were presenting buffers repeatedly without waiting, I believe it could overwrite a buffer while/before it appears on screen.

So I believe like on Wayland, buffer_mut should wait for buffer release. I guess it would have to poll the device fd, and use drm::control::device::receive_events to see if it's gotten Event::PageFlip yet.

...but would Winit or another "windowing" backend using DRM also poll the same fd? Is there any way to manage this?

I'm not sure if there is a way to do this on DRM. Please tell me if I'm wrong, but I think the current way of doing things is the only way.

- Add a mechanism that uses udev to find a card
- Poll the fd before receiving events

Signed-off-by: John Nunley <[email protected]>
notgull added a commit to forkgull/drm-rs that referenced this pull request Aug 12, 2023
In softbuffer's DRM implementation, we need to have a way to get a [u8]
slice for our Deref implementation. Right now, we just create an entire
buffer of zeroes and read from that. As that is unidiomatic, this PR
adds an AsRef impl to DumbMapping to get a reference to the underlying
memory.

See:
rust-windowing/softbuffer#135 (comment)
Signed-off-by: John Nunley <[email protected]>
@ids1024
Copy link
Member

ids1024 commented Aug 12, 2023

I guess buffer_mut could have a comment noting it blocks for buffer release on Wayland, and on DRM, should not be called until after waiting for pageflip?

Looking at https://gitlab.freedesktop.org/mesa/mesa/-/blob/main/src/egl/drivers/dri2/platform_drm.c and https://github.com/libsdl-org/SDL/blob/main/src/video/kmsdrm/SDL_kmsdrmopengles.c, it seems like EGL manages this in some way with functions called gbm_surface_lock_front_buffer and gbm_surface_lock_front_buffer, but I don't entirely follow the logic there and it's not clear that anything like that could make sense in softbuffer. I guess that's something Glutin would have to deal with for DRM support.

Signed-off-by: John Nunley <[email protected]>
@notgull notgull requested a review from ids1024 August 12, 2023 17:21
@notgull
Copy link
Member Author

notgull commented Aug 12, 2023

I guess buffer_mut could have a comment noting it blocks for buffer release on Wayland, and on DRM, should not be called until after waiting for pageflip?

Done.

I was mostly following rust-windowing/glutin#1403, which appears to use fencing in a way that I don't know how to accommodate in softbuffer with DUMB buffers. As far as I know there's not a real way to say "fence a DUMB buffer off" like there is in GBM.

Signed-off-by: John Nunley <[email protected]>
@ids1024
Copy link
Member

ids1024 commented Aug 12, 2023

Seems like DIRTYFB is returning ENOSYS. Removing that call makes the example work.

I guess that's expected with some drivers? Don't know if simply ignoring ENOSYS and doing nothing else is correct here. DRM isn't the best documented thing in the world...

@notgull notgull requested a review from ids1024 August 12, 2023 18:55
@notgull notgull merged commit ac0b7f5 into master Aug 12, 2023
45 checks passed
@notgull notgull deleted the notgull/drm branch August 12, 2023 20:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

GBM/KMS platform
3 participants