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,
|
fixed::Fixed,
|
||||||
ifs::wl_seat::wl_pointer::{CONTINUOUS, FINGER, HORIZONTAL_SCROLL, VERTICAL_SCROLL, WHEEL},
|
ifs::wl_seat::wl_pointer::{CONTINUOUS, FINGER, HORIZONTAL_SCROLL, VERTICAL_SCROLL, WHEEL},
|
||||||
render::Framebuffer,
|
render::Framebuffer,
|
||||||
video::drm::ConnectorType,
|
video::drm::{ConnectorType, DrmError, DrmVersion},
|
||||||
},
|
},
|
||||||
std::{
|
std::{
|
||||||
any::Any,
|
any::Any,
|
||||||
|
|
@ -222,4 +222,5 @@ pub trait BackendDrmDevice {
|
||||||
fn on_change(&self, cb: Rc<dyn Fn()>);
|
fn on_change(&self, cb: Rc<dyn Fn()>);
|
||||||
fn dev_t(&self) -> c::dev_t;
|
fn dev_t(&self) -> c::dev_t;
|
||||||
fn make_render_device(self: Rc<Self>);
|
fn make_render_device(self: Rc<Self>);
|
||||||
|
fn version(&self) -> Result<DrmVersion, DrmError>;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,9 @@ use {
|
||||||
drm::{
|
drm::{
|
||||||
drm_mode_modeinfo, Change, ConnectorStatus, ConnectorType, DrmBlob, DrmConnector,
|
drm_mode_modeinfo, Change, ConnectorStatus, ConnectorType, DrmBlob, DrmConnector,
|
||||||
DrmCrtc, DrmEncoder, DrmError, DrmEvent, DrmFramebuffer, DrmMaster, DrmModeInfo,
|
DrmCrtc, DrmEncoder, DrmError, DrmEvent, DrmFramebuffer, DrmMaster, DrmModeInfo,
|
||||||
DrmObject, DrmPlane, DrmProperty, DrmPropertyDefinition, DrmPropertyType, PropBlob,
|
DrmObject, DrmPlane, DrmProperty, DrmPropertyDefinition, DrmPropertyType,
|
||||||
DRM_CLIENT_CAP_ATOMIC, DRM_MODE_ATOMIC_ALLOW_MODESET, DRM_MODE_ATOMIC_NONBLOCK,
|
DrmVersion, PropBlob, DRM_CLIENT_CAP_ATOMIC, DRM_MODE_ATOMIC_ALLOW_MODESET,
|
||||||
DRM_MODE_PAGE_FLIP_EVENT,
|
DRM_MODE_ATOMIC_NONBLOCK, DRM_MODE_PAGE_FLIP_EVENT,
|
||||||
},
|
},
|
||||||
gbm::{GbmDevice, GBM_BO_USE_LINEAR, GBM_BO_USE_RENDERING, GBM_BO_USE_SCANOUT},
|
gbm::{GbmDevice, GBM_BO_USE_LINEAR, GBM_BO_USE_RENDERING, GBM_BO_USE_SCANOUT},
|
||||||
ModifiedFormat, INVALID_MODIFIER,
|
ModifiedFormat, INVALID_MODIFIER,
|
||||||
|
|
@ -93,6 +93,10 @@ impl BackendDrmDevice for MetalDrmDevice {
|
||||||
fn make_render_device(self: Rc<Self>) {
|
fn make_render_device(self: Rc<Self>) {
|
||||||
self.backend.make_render_device(&self, true);
|
self.backend.make_render_device(&self, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn version(&self) -> Result<DrmVersion, DrmError> {
|
||||||
|
self.gbm.drm.version()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct HandleEvents {
|
pub struct HandleEvents {
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ use {
|
||||||
queue::AsyncQueue, syncqueue::SyncQueue,
|
queue::AsyncQueue, syncqueue::SyncQueue,
|
||||||
},
|
},
|
||||||
video::{
|
video::{
|
||||||
drm::{ConnectorType, Drm, DrmError},
|
drm::{ConnectorType, Drm, DrmError, DrmVersion},
|
||||||
gbm::{GbmDevice, GbmError, GBM_BO_USE_RENDERING},
|
gbm::{GbmDevice, GbmError, GBM_BO_USE_RENDERING},
|
||||||
ModifiedFormat, INVALID_MODIFIER,
|
ModifiedFormat, INVALID_MODIFIER,
|
||||||
},
|
},
|
||||||
|
|
@ -291,7 +291,7 @@ impl XBackend {
|
||||||
self.state
|
self.state
|
||||||
.backend_events
|
.backend_events
|
||||||
.push(BackendEvent::NewDrmDevice(Rc::new(XDrmDevice {
|
.push(BackendEvent::NewDrmDevice(Rc::new(XDrmDevice {
|
||||||
_backend: self.clone(),
|
backend: self.clone(),
|
||||||
id: self.drm_device_id,
|
id: self.drm_device_id,
|
||||||
dev: self.drm_dev,
|
dev: self.drm_dev,
|
||||||
})));
|
})));
|
||||||
|
|
@ -939,7 +939,7 @@ impl XBackend {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct XDrmDevice {
|
struct XDrmDevice {
|
||||||
_backend: Rc<XBackend>,
|
backend: Rc<XBackend>,
|
||||||
id: DrmDeviceId,
|
id: DrmDeviceId,
|
||||||
dev: dev_t,
|
dev: dev_t,
|
||||||
}
|
}
|
||||||
|
|
@ -965,6 +965,10 @@ impl BackendDrmDevice for XDrmDevice {
|
||||||
log::warn!("make_render_device is not supported by the X backend");
|
log::warn!("make_render_device is not supported by the X backend");
|
||||||
// nothing
|
// nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn version(&self) -> Result<DrmVersion, DrmError> {
|
||||||
|
self.backend.gbm.drm.version()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct XOutput {
|
struct XOutput {
|
||||||
|
|
|
||||||
16
src/state.rs
16
src/state.rs
|
|
@ -49,6 +49,7 @@ use {
|
||||||
xwayland::{self, XWaylandEvent},
|
xwayland::{self, XWaylandEvent},
|
||||||
},
|
},
|
||||||
ahash::AHashMap,
|
ahash::AHashMap,
|
||||||
|
bstr::ByteSlice,
|
||||||
jay_config::PciId,
|
jay_config::PciId,
|
||||||
std::{
|
std::{
|
||||||
cell::{Cell, RefCell},
|
cell::{Cell, RefCell},
|
||||||
|
|
@ -284,8 +285,21 @@ impl State {
|
||||||
config.devices_enumerated()
|
config.devices_enumerated()
|
||||||
}
|
}
|
||||||
if self.render_ctx.get().is_none() {
|
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();
|
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},
|
utils::{errorfmt::ErrorFmt, stack::Stack, syncqueue::SyncQueue, vec_ext::VecExt},
|
||||||
video::{
|
video::{
|
||||||
dmabuf::DmaBuf,
|
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,
|
INVALID_MODIFIER,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
@ -103,6 +103,8 @@ pub enum DrmError {
|
||||||
ReadEvents(#[source] OsError),
|
ReadEvents(#[source] OsError),
|
||||||
#[error("Read invalid data from drm device")]
|
#[error("Read invalid data from drm device")]
|
||||||
InvalidRead,
|
InvalidRead,
|
||||||
|
#[error("Could not determine the drm version")]
|
||||||
|
Version(#[source] OsError),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_node_name(fd: c::c_int) -> Result<Ustring, DrmError> {
|
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> {
|
pub fn get_nodes(&self) -> Result<AHashMap<NodeType, CString>, DrmError> {
|
||||||
get_nodes(self.fd.raw()).map_err(DrmError::GetNodes)
|
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 {
|
pub struct DrmMaster {
|
||||||
|
|
@ -590,6 +596,16 @@ pub struct DrmModeInfo {
|
||||||
pub name: BString,
|
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 {
|
impl DrmModeInfo {
|
||||||
pub fn create_blob(&self, master: &Rc<DrmMaster>) -> Result<PropBlob, DrmError> {
|
pub fn create_blob(&self, master: &Rc<DrmMaster>) -> Result<PropBlob, DrmError> {
|
||||||
let raw = self.to_raw();
|
let raw = self.to_raw();
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ use {
|
||||||
DrmBlob, DrmCardResources, DrmConnector, DrmConnectorInfo, DrmCrtc, DrmEncoder,
|
DrmBlob, DrmCardResources, DrmConnector, DrmConnectorInfo, DrmCrtc, DrmEncoder,
|
||||||
DrmEncoderInfo, DrmError, DrmFb, DrmModeInfo, DrmPlane, DrmPlaneInfo, DrmProperty,
|
DrmEncoderInfo, DrmError, DrmFb, DrmModeInfo, DrmPlane, DrmPlaneInfo, DrmProperty,
|
||||||
DrmPropertyDefinition, DrmPropertyEnumValue, DrmPropertyType, DrmPropertyValue,
|
DrmPropertyDefinition, DrmPropertyEnumValue, DrmPropertyType, DrmPropertyValue,
|
||||||
NodeType,
|
DrmVersion, NodeType,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ahash::AHashMap,
|
ahash::AHashMap,
|
||||||
|
|
@ -18,7 +18,7 @@ use {
|
||||||
io::{BufRead, BufReader},
|
io::{BufRead, BufReader},
|
||||||
mem,
|
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> {
|
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 _)
|
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