From 92aecd977319beb027446a22c47c28815e2d17d8 Mon Sep 17 00:00:00 2001 From: Matilde Morrone Date: Fri, 28 Feb 2025 14:42:43 +0100 Subject: [PATCH] Properly feature gate drm support and add safety docs --- wgpu-core/src/instance.rs | 53 +++++++++++++++++++++++++++++------ wgpu-hal/src/vulkan/drm.rs | 7 ++++- wgpu-hal/src/vulkan/mod.rs | 4 ++- wgpu/src/api/surface.rs | 1 + wgpu/src/backend/wgpu_core.rs | 1 + 5 files changed, 55 insertions(+), 11 deletions(-) diff --git a/wgpu-core/src/instance.rs b/wgpu-core/src/instance.rs index 0aae2172fa..a17c44491e 100644 --- a/wgpu-core/src/instance.rs +++ b/wgpu-core/src/instance.rs @@ -202,6 +202,18 @@ impl Instance { } } + /// Creates a new surface from the given drm configuration. + /// + /// # Safety + /// + /// - All parameters must point to valid DRM values. + /// + /// # Platform Support + /// + /// This function is only available on Unix-like platforms (Linux, FreeBSD) and + /// currently only works with the Vulkan backend. + #[cfg(all(unix, not(target_vendor = "apple")))] + pub unsafe fn create_surface_from_drm( &self, fd: i32, @@ -217,16 +229,28 @@ impl Instance { let mut surface_per_backend: HashMap> = HashMap::default(); - let instance = unsafe { self.as_hal::() } - .ok_or(CreateSurfaceError::BackendNotEnabled(Backend::Vulkan))?; - - match instance.create_surface_from_drm(fd, plane, connector_id, width, height, refresh_rate) + #[cfg(feature = "vulkan")] { - Ok(surface) => { - surface_per_backend.insert(Backend::Vulkan, Box::new(surface)); - } - Err(err) => { - errors.insert(Backend::Vulkan, err); + let instance = unsafe { self.as_hal::() } + .ok_or(CreateSurfaceError::BackendNotEnabled(Backend::Vulkan))?; + + // Safety must be upheld by the caller + match unsafe { + instance.create_surface_from_drm( + fd, + plane, + connector_id, + width, + height, + refresh_rate, + ) + } { + Ok(surface) => { + surface_per_backend.insert(Backend::Vulkan, Box::new(surface)); + } + Err(err) => { + errors.insert(Backend::Vulkan, err); + } } } @@ -814,6 +838,17 @@ impl Global { Ok(id) } + /// Creates a new surface from the given drm configuration. + /// + /// # Safety + /// + /// - All parameters must point to valid DRM values. + /// + /// # Platform Support + /// + /// This function is only available on Unix-like platforms (Linux, FreeBSD) and + /// currently only works with the Vulkan backend. + #[cfg(all(unix, not(target_vendor = "apple")))] pub unsafe fn instance_create_surface_from_drm( &self, fd: i32, diff --git a/wgpu-hal/src/vulkan/drm.rs b/wgpu-hal/src/vulkan/drm.rs index e96de25a05..3f63780e64 100644 --- a/wgpu-hal/src/vulkan/drm.rs +++ b/wgpu-hal/src/vulkan/drm.rs @@ -4,7 +4,12 @@ use std::{string::ToString, vec::Vec}; use ash::{ext, khr, vk}; impl super::Instance { - pub fn create_surface_from_drm( + /// Creates a new surface from the given drm configuration. + /// + /// # Safety + /// + /// - All parameters must point to valid DRM values. + pub unsafe fn create_surface_from_drm( &self, fd: i32, plane: u32, diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index 706a60f0ca..98175a5b7d 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -30,10 +30,12 @@ mod adapter; mod command; mod conv; mod device; -mod drm; mod instance; mod sampler; +#[cfg(all(unix, not(target_vendor = "apple")))] +mod drm; + use std::{ borrow::Borrow, boxed::Box, diff --git a/wgpu/src/api/surface.rs b/wgpu/src/api/surface.rs index 6cc89f5989..607218dca4 100644 --- a/wgpu/src/api/surface.rs +++ b/wgpu/src/api/surface.rs @@ -298,6 +298,7 @@ pub enum SurfaceTargetUnsafe { /// /// - All parameters must point to valid DRM values and remain valid for as long as the resulting [`Surface`] exists. /// - The file descriptor (`fd`), plane, connector, and mode configuration must be valid and compatible. + #[cfg(all(unix, not(target_vendor = "apple")))] Drm { /// The file descriptor of the DRM device. fd: i32, diff --git a/wgpu/src/backend/wgpu_core.rs b/wgpu/src/backend/wgpu_core.rs index 07428a1f9a..bb5fff8fab 100644 --- a/wgpu/src/backend/wgpu_core.rs +++ b/wgpu/src/backend/wgpu_core.rs @@ -794,6 +794,7 @@ impl dispatch::InstanceInterface for ContextWgpuCore { .instance_create_surface(raw_display_handle, raw_window_handle, None) }, + #[cfg(all(unix, not(target_vendor = "apple")))] SurfaceTargetUnsafe::Drm { fd, plane,