kms: Fixup new backend initializtion
This commit is contained in:
parent
1a05121498
commit
5ba068ec82
1 changed files with 57 additions and 27 deletions
|
|
@ -179,7 +179,7 @@ pub fn init_backend(
|
||||||
match match event {
|
match match event {
|
||||||
UdevEvent::Added { device_id, path } => data
|
UdevEvent::Added { device_id, path } => data
|
||||||
.state
|
.state
|
||||||
.device_added(device_id, path, &data.display.handle())
|
.device_added(device_id, path, &data.display.handle(), true)
|
||||||
.with_context(|| format!("Failed to add drm device: {}", device_id)),
|
.with_context(|| format!("Failed to add drm device: {}", device_id)),
|
||||||
UdevEvent::Changed { device_id } => data
|
UdevEvent::Changed { device_id } => data
|
||||||
.state
|
.state
|
||||||
|
|
@ -241,7 +241,7 @@ pub fn init_backend(
|
||||||
} else {
|
} else {
|
||||||
if let Err(err) =
|
if let Err(err) =
|
||||||
data.state
|
data.state
|
||||||
.device_added(dev, path.into(), &data.display.handle())
|
.device_added(dev, path.into(), &data.display.handle(), true)
|
||||||
{
|
{
|
||||||
slog_scope::error!(
|
slog_scope::error!(
|
||||||
"Failed to add drm device {}: {}",
|
"Failed to add drm device {}: {}",
|
||||||
|
|
@ -319,14 +319,21 @@ pub fn init_backend(
|
||||||
|
|
||||||
for (dev, path) in udev_dispatcher.as_source_ref().device_list() {
|
for (dev, path) in udev_dispatcher.as_source_ref().device_list() {
|
||||||
state
|
state
|
||||||
.device_added(dev, path.into(), dh)
|
.device_added(dev, path.into(), dh, false)
|
||||||
.with_context(|| format!("Failed to add drm device: {}", path.display()))?;
|
.with_context(|| format!("Failed to add drm device: {}", path.display()))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HACK: amdgpu doesn't like us initializing vulkan too early..
|
||||||
|
// so lets do that delayed until mesa fixes that.
|
||||||
|
let devices = state.backend.kms().devices.iter().map(|(drm_node, device)| (*drm_node, device.render_node)).collect::<Vec<_>>();
|
||||||
|
for (drm_node, render_node) in devices {
|
||||||
|
state.init_vulkan(drm_node, render_node);
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
impl State {
|
impl State {
|
||||||
fn device_added(&mut self, dev: dev_t, path: PathBuf, dh: &DisplayHandle) -> Result<()> {
|
fn device_added(&mut self, dev: dev_t, path: PathBuf, dh: &DisplayHandle, try_vulkan: bool) -> Result<()> {
|
||||||
if !self.backend.kms().session.is_active() {
|
if !self.backend.kms().session.is_active() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
@ -358,25 +365,30 @@ impl State {
|
||||||
|
|
||||||
let gbm = GbmDevice::new(fd)
|
let gbm = GbmDevice::new(fd)
|
||||||
.with_context(|| format!("Failed to initialize GBM device for {}", path.display()))?;
|
.with_context(|| format!("Failed to initialize GBM device for {}", path.display()))?;
|
||||||
let egl_display = EGLDisplay::new(gbm.clone(), None).with_context(|| {
|
let (render_node, formats) = {
|
||||||
format!("Failed to create EGLDisplay for device: {}", path.display())
|
let egl_display = EGLDisplay::new(gbm.clone(), None).with_context(|| {
|
||||||
})?;
|
format!("Failed to create EGLDisplay for device: {}", path.display())
|
||||||
let egl_device = EGLDevice::device_for_display(&egl_display).with_context(|| {
|
})?;
|
||||||
format!("Unable to find matching egl device for {}", path.display())
|
let egl_device = EGLDevice::device_for_display(&egl_display).with_context(|| {
|
||||||
})?;
|
format!("Unable to find matching egl device for {}", path.display())
|
||||||
let render_node = egl_device
|
})?;
|
||||||
.try_get_render_node()
|
let render_node = egl_device
|
||||||
.ok()
|
.try_get_render_node()
|
||||||
.and_then(std::convert::identity)
|
.ok()
|
||||||
.unwrap_or(drm_node);
|
.and_then(std::convert::identity)
|
||||||
let egl_context = EGLContext::new(&egl_display, None).with_context(|| {
|
.unwrap_or(drm_node);
|
||||||
format!(
|
let egl_context = EGLContext::new(&egl_display, None).with_context(|| {
|
||||||
"Failed to create EGLContext for device {:?}:{}",
|
format!(
|
||||||
egl_device,
|
"Failed to create EGLContext for device {:?}:{}",
|
||||||
path.display()
|
egl_device,
|
||||||
)
|
path.display()
|
||||||
})?;
|
)
|
||||||
let formats = egl_context.dmabuf_render_formats().clone();
|
})?;
|
||||||
|
let formats = egl_context.dmabuf_render_formats().clone();
|
||||||
|
(render_node, formats)
|
||||||
|
// NOTE: We need the to drop the EGL types here again,
|
||||||
|
// otherwise the EGLDisplay created below might share the same GBM context
|
||||||
|
};
|
||||||
|
|
||||||
let dispatcher =
|
let dispatcher =
|
||||||
Dispatcher::new(drm, move |event, metadata, data: &mut Data| match event {
|
Dispatcher::new(drm, move |event, metadata, data: &mut Data| match event {
|
||||||
|
|
@ -494,7 +506,7 @@ impl State {
|
||||||
let mut device = Device {
|
let mut device = Device {
|
||||||
render_node,
|
render_node,
|
||||||
surfaces: HashMap::new(),
|
surfaces: HashMap::new(),
|
||||||
gbm,
|
gbm: gbm.clone(),
|
||||||
allocator,
|
allocator,
|
||||||
drm: dispatcher,
|
drm: dispatcher,
|
||||||
formats,
|
formats,
|
||||||
|
|
@ -508,6 +520,16 @@ impl State {
|
||||||
let mut w = self.common.shell.global_space().size.w;
|
let mut w = self.common.shell.global_space().size.w;
|
||||||
{
|
{
|
||||||
let backend = self.backend.kms();
|
let backend = self.backend.kms();
|
||||||
|
backend
|
||||||
|
.api
|
||||||
|
.as_mut()
|
||||||
|
.add_node(render_node, gbm)
|
||||||
|
.with_context(|| {
|
||||||
|
format!(
|
||||||
|
"Failed to initialize renderer for device: {}, skipping",
|
||||||
|
render_node
|
||||||
|
)
|
||||||
|
})?;
|
||||||
for (crtc, conn) in outputs {
|
for (crtc, conn) in outputs {
|
||||||
let mut renderer = match backend.api.single_renderer(&render_node) {
|
let mut renderer = match backend.api.single_renderer(&render_node) {
|
||||||
Ok(renderer) => renderer,
|
Ok(renderer) => renderer,
|
||||||
|
|
@ -545,6 +567,14 @@ impl State {
|
||||||
&self.common.event_loop_handle,
|
&self.common.event_loop_handle,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if try_vulkan {
|
||||||
|
self.init_vulkan(drm_node, render_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn init_vulkan(&mut self, drm_node: DrmNode, render_node: DrmNode) {
|
||||||
if let Ok(instance) = Instance::new(Version::VERSION_1_2, None, None) {
|
if let Ok(instance) = Instance::new(Version::VERSION_1_2, None, None) {
|
||||||
if let Some(physical_device) =
|
if let Some(physical_device) =
|
||||||
PhysicalDevice::enumerate(&instance)
|
PhysicalDevice::enumerate(&instance)
|
||||||
|
|
@ -582,8 +612,6 @@ impl State {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn device_changed(&mut self, dev: dev_t) -> Result<()> {
|
fn device_changed(&mut self, dev: dev_t) -> Result<()> {
|
||||||
|
|
@ -663,7 +691,9 @@ impl State {
|
||||||
fn device_removed(&mut self, dev: dev_t, dh: &DisplayHandle) -> Result<()> {
|
fn device_removed(&mut self, dev: dev_t, dh: &DisplayHandle) -> Result<()> {
|
||||||
let drm_node = DrmNode::from_dev_id(dev)?;
|
let drm_node = DrmNode::from_dev_id(dev)?;
|
||||||
let mut outputs_removed = Vec::new();
|
let mut outputs_removed = Vec::new();
|
||||||
if let Some(mut device) = self.backend.kms().devices.remove(&drm_node) {
|
let backend = self.backend.kms();
|
||||||
|
if let Some(mut device) = backend.devices.remove(&drm_node) {
|
||||||
|
backend.api.as_mut().remove_node(&device.render_node);
|
||||||
for surface in device.surfaces.values_mut() {
|
for surface in device.surfaces.values_mut() {
|
||||||
if let Some(token) = surface.render_timer_token.take() {
|
if let Some(token) = surface.render_timer_token.take() {
|
||||||
self.common.event_loop_handle.remove(token);
|
self.common.event_loop_handle.remove(token);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue