video: prefer non-nvidia devices when selecting render device
This commit is contained in:
parent
141997d9d6
commit
79ee6900fa
6 changed files with 107 additions and 11 deletions
|
|
@ -4,7 +4,7 @@ use {
|
|||
fixed::Fixed,
|
||||
ifs::wl_seat::wl_pointer::{CONTINUOUS, FINGER, HORIZONTAL_SCROLL, VERTICAL_SCROLL, WHEEL},
|
||||
render::Framebuffer,
|
||||
video::drm::ConnectorType,
|
||||
video::drm::{ConnectorType, DrmError, DrmVersion},
|
||||
},
|
||||
std::{
|
||||
any::Any,
|
||||
|
|
@ -222,4 +222,5 @@ pub trait BackendDrmDevice {
|
|||
fn on_change(&self, cb: Rc<dyn Fn()>);
|
||||
fn dev_t(&self) -> c::dev_t;
|
||||
fn make_render_device(self: Rc<Self>);
|
||||
fn version(&self) -> Result<DrmVersion, DrmError>;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@ use {
|
|||
drm::{
|
||||
drm_mode_modeinfo, Change, ConnectorStatus, ConnectorType, DrmBlob, DrmConnector,
|
||||
DrmCrtc, DrmEncoder, DrmError, DrmEvent, DrmFramebuffer, DrmMaster, DrmModeInfo,
|
||||
DrmObject, DrmPlane, DrmProperty, DrmPropertyDefinition, DrmPropertyType, PropBlob,
|
||||
DRM_CLIENT_CAP_ATOMIC, DRM_MODE_ATOMIC_ALLOW_MODESET, DRM_MODE_ATOMIC_NONBLOCK,
|
||||
DRM_MODE_PAGE_FLIP_EVENT,
|
||||
DrmObject, DrmPlane, DrmProperty, DrmPropertyDefinition, DrmPropertyType,
|
||||
DrmVersion, PropBlob, DRM_CLIENT_CAP_ATOMIC, DRM_MODE_ATOMIC_ALLOW_MODESET,
|
||||
DRM_MODE_ATOMIC_NONBLOCK, DRM_MODE_PAGE_FLIP_EVENT,
|
||||
},
|
||||
gbm::{GbmDevice, GBM_BO_USE_LINEAR, GBM_BO_USE_RENDERING, GBM_BO_USE_SCANOUT},
|
||||
ModifiedFormat, INVALID_MODIFIER,
|
||||
|
|
@ -93,6 +93,10 @@ impl BackendDrmDevice for MetalDrmDevice {
|
|||
fn make_render_device(self: Rc<Self>) {
|
||||
self.backend.make_render_device(&self, true);
|
||||
}
|
||||
|
||||
fn version(&self) -> Result<DrmVersion, DrmError> {
|
||||
self.gbm.drm.version()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct HandleEvents {
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ use {
|
|||
queue::AsyncQueue, syncqueue::SyncQueue,
|
||||
},
|
||||
video::{
|
||||
drm::{ConnectorType, Drm, DrmError},
|
||||
drm::{ConnectorType, Drm, DrmError, DrmVersion},
|
||||
gbm::{GbmDevice, GbmError, GBM_BO_USE_RENDERING},
|
||||
ModifiedFormat, INVALID_MODIFIER,
|
||||
},
|
||||
|
|
@ -291,7 +291,7 @@ impl XBackend {
|
|||
self.state
|
||||
.backend_events
|
||||
.push(BackendEvent::NewDrmDevice(Rc::new(XDrmDevice {
|
||||
_backend: self.clone(),
|
||||
backend: self.clone(),
|
||||
id: self.drm_device_id,
|
||||
dev: self.drm_dev,
|
||||
})));
|
||||
|
|
@ -939,7 +939,7 @@ impl XBackend {
|
|||
}
|
||||
|
||||
struct XDrmDevice {
|
||||
_backend: Rc<XBackend>,
|
||||
backend: Rc<XBackend>,
|
||||
id: DrmDeviceId,
|
||||
dev: dev_t,
|
||||
}
|
||||
|
|
@ -965,6 +965,10 @@ impl BackendDrmDevice for XDrmDevice {
|
|||
log::warn!("make_render_device is not supported by the X backend");
|
||||
// nothing
|
||||
}
|
||||
|
||||
fn version(&self) -> Result<DrmVersion, DrmError> {
|
||||
self.backend.gbm.drm.version()
|
||||
}
|
||||
}
|
||||
|
||||
struct XOutput {
|
||||
|
|
|
|||
16
src/state.rs
16
src/state.rs
|
|
@ -49,6 +49,7 @@ use {
|
|||
xwayland::{self, XWaylandEvent},
|
||||
},
|
||||
ahash::AHashMap,
|
||||
bstr::ByteSlice,
|
||||
jay_config::PciId,
|
||||
std::{
|
||||
cell::{Cell, RefCell},
|
||||
|
|
@ -284,8 +285,21 @@ impl State {
|
|||
config.devices_enumerated()
|
||||
}
|
||||
if self.render_ctx.get().is_none() {
|
||||
if let Some(dev) = self.drm_devs.lock().values().next() {
|
||||
for dev in self.drm_devs.lock().values() {
|
||||
if let Ok(version) = dev.dev.version() {
|
||||
if version.name.contains_str("nvidia") {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
dev.make_render_device();
|
||||
if self.render_ctx.get().is_some() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if self.render_ctx.get().is_none() {
|
||||
if let Some(dev) = self.drm_devs.lock().values().next() {
|
||||
dev.make_render_device();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ use crate::{
|
|||
utils::{errorfmt::ErrorFmt, stack::Stack, syncqueue::SyncQueue, vec_ext::VecExt},
|
||||
video::{
|
||||
dmabuf::DmaBuf,
|
||||
drm::sys::{DRM_CAP_CURSOR_HEIGHT, DRM_CAP_CURSOR_WIDTH},
|
||||
drm::sys::{get_version, DRM_CAP_CURSOR_HEIGHT, DRM_CAP_CURSOR_WIDTH},
|
||||
INVALID_MODIFIER,
|
||||
},
|
||||
};
|
||||
|
|
@ -103,6 +103,8 @@ pub enum DrmError {
|
|||
ReadEvents(#[source] OsError),
|
||||
#[error("Read invalid data from drm device")]
|
||||
InvalidRead,
|
||||
#[error("Could not determine the drm version")]
|
||||
Version(#[source] OsError),
|
||||
}
|
||||
|
||||
fn render_node_name(fd: c::c_int) -> Result<Ustring, DrmError> {
|
||||
|
|
@ -165,6 +167,10 @@ impl Drm {
|
|||
pub fn get_nodes(&self) -> Result<AHashMap<NodeType, CString>, DrmError> {
|
||||
get_nodes(self.fd.raw()).map_err(DrmError::GetNodes)
|
||||
}
|
||||
|
||||
pub fn version(&self) -> Result<DrmVersion, DrmError> {
|
||||
get_version(self.fd.raw()).map_err(DrmError::Version)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DrmMaster {
|
||||
|
|
@ -590,6 +596,16 @@ pub struct DrmModeInfo {
|
|||
pub name: BString,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub struct DrmVersion {
|
||||
pub version_major: i32,
|
||||
pub version_minor: i32,
|
||||
pub version_patchlevel: i32,
|
||||
pub name: BString,
|
||||
pub date: BString,
|
||||
pub desc: BString,
|
||||
}
|
||||
|
||||
impl DrmModeInfo {
|
||||
pub fn create_blob(&self, master: &Rc<DrmMaster>) -> Result<PropBlob, DrmError> {
|
||||
let raw = self.to_raw();
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use {
|
|||
DrmBlob, DrmCardResources, DrmConnector, DrmConnectorInfo, DrmCrtc, DrmEncoder,
|
||||
DrmEncoderInfo, DrmError, DrmFb, DrmModeInfo, DrmPlane, DrmPlaneInfo, DrmProperty,
|
||||
DrmPropertyDefinition, DrmPropertyEnumValue, DrmPropertyType, DrmPropertyValue,
|
||||
NodeType,
|
||||
DrmVersion, NodeType,
|
||||
},
|
||||
},
|
||||
ahash::AHashMap,
|
||||
|
|
@ -18,7 +18,7 @@ use {
|
|||
io::{BufRead, BufReader},
|
||||
mem,
|
||||
},
|
||||
uapi::{c, OwnedFd, Pod, Ustring},
|
||||
uapi::{c, pod_zeroed, OwnedFd, Pod, Ustring},
|
||||
};
|
||||
|
||||
pub unsafe fn ioctl<T>(fd: c::c_int, request: c::c_ulong, t: &mut T) -> Result<c::c_int, OsError> {
|
||||
|
|
@ -1075,3 +1075,60 @@ pub fn mode_getprobblob<T: Pod + ?Sized>(
|
|||
}
|
||||
Ok(res.length as _)
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
struct drm_version {
|
||||
version_major: c::c_int,
|
||||
version_minor: c::c_int,
|
||||
version_patchlevel: c::c_int,
|
||||
name_len: usize, // actually __kernel_size_t but nobody cares about x32
|
||||
name: *mut u8,
|
||||
date_len: usize,
|
||||
date: *mut u8,
|
||||
desc_len: usize,
|
||||
desc: *mut u8,
|
||||
}
|
||||
|
||||
unsafe impl Pod for drm_version {}
|
||||
|
||||
const DRM_IOCTL_VERSION: u64 = drm_iowr::<drm_version>(0x00);
|
||||
|
||||
pub fn get_version(fd: c::c_int) -> Result<DrmVersion, OsError> {
|
||||
let mut name = Vec::<u8>::new();
|
||||
let mut date = Vec::<u8>::new();
|
||||
let mut desc = Vec::<u8>::new();
|
||||
let mut res: drm_version = pod_zeroed();
|
||||
loop {
|
||||
res.name_len = name.capacity();
|
||||
res.name = name.as_mut_ptr();
|
||||
res.date_len = date.capacity();
|
||||
res.date = date.as_mut_ptr();
|
||||
res.desc_len = desc.capacity();
|
||||
res.desc = desc.as_mut_ptr();
|
||||
unsafe {
|
||||
ioctl(fd, DRM_IOCTL_VERSION, &mut res)?;
|
||||
}
|
||||
if res.name_len <= name.capacity()
|
||||
&& res.date_len <= date.capacity()
|
||||
&& res.desc_len <= desc.capacity()
|
||||
{
|
||||
break;
|
||||
}
|
||||
name.reserve_exact(res.name_len);
|
||||
date.reserve_exact(res.date_len);
|
||||
desc.reserve_exact(res.desc_len);
|
||||
}
|
||||
unsafe {
|
||||
name.set_len(res.name_len);
|
||||
date.set_len(res.date_len);
|
||||
desc.set_len(res.desc_len);
|
||||
}
|
||||
Ok(DrmVersion {
|
||||
version_major: res.version_major,
|
||||
version_minor: res.version_minor,
|
||||
version_patchlevel: res.version_patchlevel,
|
||||
name: name.into(),
|
||||
date: date.into(),
|
||||
desc: desc.into(),
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue