rusticl/mesa: make PipeScreen transparent

Reviewed-by: Seán de Búrca <sdeburca@fastmail.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37377>
This commit is contained in:
Karol Herbst 2025-09-14 21:48:09 +02:00 committed by Marge Bot
parent f7fcd7ed5d
commit 501f59e159
3 changed files with 39 additions and 17 deletions

View file

@ -40,7 +40,7 @@ use std::sync::MutexGuard;
/// Contains basic stuff we need to partially initialize Device
pub struct DeviceBase {
pub screen: Arc<PipeScreen>,
pub screen: PipeScreenWithLdev,
pub cl_version: CLVersion,
pub clc_version: CLVersion,
pub clc_versions: Vec<cl_name_version>,
@ -1273,12 +1273,11 @@ impl DeviceBase {
}
impl Device {
fn new(screen: PipeScreen) -> Option<Device> {
fn new(screen: PipeScreenWithLdev) -> Option<Device> {
if !Self::check_valid(&screen) {
return None;
}
let screen = Arc::new(screen);
// Create before loading libclc as llvmpipe only creates the shader cache with the first
// context being created.
let helper_ctx = PipeContext::new(PipeContextPrio::Med, &screen)?;

View file

@ -24,9 +24,9 @@ impl PipeLoaderDevice {
})
}
fn load_screen(self) -> Option<PipeScreen> {
fn load_screen(self) -> Option<PipeScreenWithLdev> {
let s = unsafe { pipe_loader_create_screen(self.ldev.as_ptr(), false) };
PipeScreen::new(self, s)
PipeScreenWithLdev::new(self, s)
}
pub fn driver_name(&self) -> &CStr {
@ -115,7 +115,7 @@ fn get_enabled_devs() -> HashMap<String, u32> {
res
}
pub fn load_screens() -> impl Iterator<Item = PipeScreen> {
pub fn load_screens() -> impl Iterator<Item = PipeScreenWithLdev> {
let devs = load_devs();
let mut enabled_devs = get_enabled_devs();

View file

@ -15,6 +15,7 @@ use mesa_rust_util::ptr::ThreadSafeCPtr;
use std::ffi::c_int;
use std::ffi::CStr;
use std::num::NonZeroU64;
use std::ops::Deref;
use std::os::raw::c_schar;
use std::os::raw::c_uchar;
use std::os::raw::c_void;
@ -23,8 +24,14 @@ use std::ptr::NonNull;
use std::sync::Arc;
#[derive(PartialEq)]
pub struct PipeScreen {
pub struct PipeScreenWithLdev {
ldev: PipeLoaderDevice,
screen: Arc<PipeScreen>,
}
#[derive(PartialEq)]
#[repr(transparent)]
pub struct PipeScreen {
screen: ThreadSafeCPtr<pipe_screen>,
}
@ -69,7 +76,11 @@ impl Drop for ScreenVMAllocation<'_> {
}
}
impl PipeScreen {
/// A PipeScreen wrapper also containing an owned PipeLoaderDevice reference.
///
/// TODO: This exist purely for convenience reasons and we might want to split those objects
/// properly.
impl PipeScreenWithLdev {
pub(super) fn new(ldev: PipeLoaderDevice, screen: *mut pipe_screen) -> Option<Self> {
if screen.is_null() || !has_required_cbs(screen) {
return None;
@ -78,10 +89,30 @@ impl PipeScreen {
Some(Self {
ldev,
// SAFETY: `pipe_screen` is considered a thread-safe type
screen: unsafe { ThreadSafeCPtr::new(screen)? },
screen: Arc::new(PipeScreen {
screen: unsafe { ThreadSafeCPtr::new(screen)? },
}),
})
}
pub fn driver_name(&self) -> &CStr {
self.ldev.driver_name()
}
pub fn device_type(&self) -> pipe_loader_device_type {
self.ldev.device_type()
}
}
impl Deref for PipeScreenWithLdev {
type Target = Arc<PipeScreen>;
fn deref(&self) -> &Self::Target {
&self.screen
}
}
impl PipeScreen {
fn screen(&self) -> &pipe_screen {
// SAFETY: We own the pointer, so it's valid for every caller of this function as we are
// responsible of freeing it.
@ -306,10 +337,6 @@ impl PipeScreen {
&self.screen().compute_caps
}
pub fn driver_name(&self) -> &CStr {
self.ldev.driver_name()
}
pub fn name(&self) -> &CStr {
unsafe { CStr::from_ptr(self.screen().get_name.unwrap()(self.pipe())) }
}
@ -340,10 +367,6 @@ impl PipeScreen {
unsafe { CStr::from_ptr(self.screen().get_device_vendor.unwrap()(self.pipe())) }
}
pub fn device_type(&self) -> pipe_loader_device_type {
self.ldev.device_type()
}
pub fn driver_uuid(&self) -> Option<[c_schar; UUID_SIZE]> {
let mut uuid = [0; UUID_SIZE];
let ptr = uuid.as_mut_ptr();