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

Fails to detect DRM nodes on FreeBSD #209

Open
jbeich opened this issue Nov 1, 2024 · 2 comments · May be fixed by #210
Open

Fails to detect DRM nodes on FreeBSD #209

jbeich opened this issue Nov 1, 2024 · 2 comments · May be fixed by #210

Comments

@jbeich
Copy link

jbeich commented Nov 1, 2024

Related to #202. Sorry, I don't know Rust to debug more.

$ su root -c "rm /usr/local/lib/dri/swrast_dri.so" # prevent silent fallback
$ vidcontrol -s 2 </dev/ttyv0 # same as Ctrl+Alt+F2
$ cosmic-comp
[...]
ERROR cosmic_comp::backend::kms Failed to initialize software EGL renderer. err=no EGL device found with `EGL_MESA_device_software`
[...]

$ COSMIC_RENDER_DEVICE=/dev/dri/renderD128 cosmic-comp
<works fine>

Reverting to Smithay version appears to help:

--- a/src/node/mod.rs
+++ b/src/node/mod.rs
@@ -330,8 +330,18 @@ pub fn dev_path(dev: dev_t, ty: NodeType) -> io::Result<PathBuf> {
     if let Some(dev_name) = devname(dev) {
         let suffix = dev_name.trim_start_matches(|c: char| !c.is_numeric());
         if let Ok(old_id) = suffix.parse::<u32>() {
-            let id_mask = 0b11_1111;
-            let id = old_id & id_mask + ty.minor_base();
+            let old_ty = match old_id >> 6 {
+                0 => NodeType::Primary,
+                1 => NodeType::Control,
+                2 => NodeType::Render,
+                _ => {
+                    return Err(io::Error::new(
+                        ErrorKind::NotFound,
+                        format!("{}:{} is no DRM device", major(dev), minor(dev)),
+                    ));
+                }
+            };
+            let id = old_id - old_ty.minor_base() + ty.minor_base();
             let path = PathBuf::from(format!("/dev/dri/{}{}", ty.minor_name_prefix(), id));
             if path.exists() {
                 return Ok(path);
@MarijnS95
Copy link
Contributor

@jbeich thanks for pointing this out. I think this is caused by #202 (comment), followed by repeated submitter complaints about review and me no longer caring to respond.

The submitter forgot to think about operator predence when outsmarting | with a +, which causes the expression to effectively be:

let id = old_id & (id_mask + ty.minor_base());

Instead of the end-result that we want:

let id = (old_id & id_mask) + ty.minor_base();

This wouldn't have been a problem if | was used, which already has lower precedence than & (while + has _higher precedence than &).

Could you test if this single line works for you?

const ID_MASK: u32 = 0b11_1111;
let id = old_id & ID_MASK | ty.minor_base();

(I still would have preferred a shift over hardcoding the numbers, but 🤷)

@jbeich
Copy link
Author

jbeich commented Nov 1, 2024

const ID_MASK: u32 = 0b11_1111;
let id = old_id & ID_MASK | ty.minor_base();

I confirm, this also helps.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants