drm-rs icon indicating copy to clipboard operation
drm-rs copied to clipboard

Fails to detect DRM nodes on FreeBSD

Open jbeich opened this issue 1 year ago • 2 comments

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);

jbeich avatar Nov 01 '24 16:11 jbeich

@jbeich thanks for pointing this out. I think this is caused by https://github.com/Smithay/drm-rs/pull/202#discussion_r1746653350, 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 🤷)

MarijnS95 avatar Nov 01 '24 16:11 MarijnS95

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

I confirm, this also helps.

jbeich avatar Nov 01 '24 16:11 jbeich