@@ -5,6 +5,15 @@ use core::mem::MaybeUninit;
5
5
6
6
use ash:: { ext, khr, vk} ;
7
7
8
+ macro_rules! to_u64 {
9
+ ( $expr: expr) => { {
10
+ #[ allow( trivial_numeric_casts) ]
11
+ let expr = $expr as u64 ;
12
+ assert!( size_of_val( & expr) <= size_of:: <u64 >( ) ) ;
13
+ expr
14
+ } } ;
15
+ }
16
+
8
17
impl super :: Instance {
9
18
/// Creates a new surface from the given drm configuration.
10
19
///
@@ -77,12 +86,18 @@ impl super::Instance {
77
86
let render_devid =
78
87
libc:: makedev ( drm_props. render_major as _ , drm_props. render_minor as _ ) ;
79
88
80
- // Various platforms use different widths between `dev_t` and `c_int`, so just
81
- // force-convert to `u64` to keep things portable.
89
+ // On most platforms, both `*_devid`s and `st_rdev` are `dev_t`s (which is generally
90
+ // observed to be an unsigned integral type no greater than 64 bits). However, on some
91
+ // platforms, there divergences from this pattern:
92
+ //
93
+ // - `armv7-linux-androideabi`: `dev_t` is `c_ulong`, and `*_devid`s are `dev_t`, but
94
+ // `st_rdev` is `c_ulonglong`. So, we can't just do a `==` comparison.
95
+ // - OpenBSD has `dev_t` on both sides, but is `i32` (N.B., unsigned). Therefore, we
96
+ // can't just use `u64::from`.
82
97
#[ allow( clippy:: useless_conversion) ]
83
98
if [ primary_devid, render_devid]
84
- . map ( u64 :: from )
85
- . contains ( & drm_stat. st_rdev )
99
+ . map ( |devid| to_u64 ! ( devid ) )
100
+ . contains ( & to_u64 ! ( drm_stat. st_rdev) )
86
101
{
87
102
physical_device = Some ( device)
88
103
}
0 commit comments