mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Daniel Almeida <daniel.almeida@collabora.com>
To: Lyude Paul <lyude@redhat.com>
Cc: dri-devel@lists.freedesktop.org, rust-for-linux@vger.kernel.org,
	"Asahi Lina" <lina@asahilina.net>,
	"Danilo Krummrich" <dakr@kernel.org>,
	mcanal@igalia.com, airlied@redhat.com, zhiw@nvidia.com,
	cjia@nvidia.com, jhubbard@nvidia.com,
	"Miguel Ojeda" <ojeda@kernel.org>,
	"Alex Gaynor" <alex.gaynor@gmail.com>,
	"Wedson Almeida Filho" <wedsonaf@gmail.com>,
	"Boqun Feng" <boqun.feng@gmail.com>,
	"Gary Guo" <gary@garyguo.net>,
	"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
	"Benno Lossin" <benno.lossin@proton.me>,
	"Andreas Hindborg" <a.hindborg@samsung.com>,
	"Alice Ryhl" <aliceryhl@google.com>,
	"Trevor Gross" <tmgross@umich.edu>,
	"open list" <linux-kernel@vger.kernel.org>
Subject: Re: [WIP RFC v2 07/35] WIP: rust: drm/kms: Add drm_crtc bindings
Date: Wed, 27 Nov 2024 11:36:50 -0300	[thread overview]
Message-ID: <042BD8BE-A0E1-4CD4-89AB-96314DABECA3@collabora.com> (raw)
In-Reply-To: <20240930233257.1189730-8-lyude@redhat.com>

Hi Lyude,

> On 30 Sep 2024, at 20:09, Lyude Paul <lyude@redhat.com> wrote:
> 
> This introduces basic bindings for DRM CRTCs which follow the same general
> pattern as connectors and planes (e.g. AsRawCrtc, AsRawCrtcState, etc.).
> There is one big difference though - drm_crtc_state appears to be the one
> atomic state that actually has data which can be mutated from outside of
> the atomic commit phase - which means we can't keep rust referencs to it,

Nit: typo in `references to it`

> and instead need to use the Opaque type and implement things through
> pointers instead.
> 
> This should be the last mode object we're introducing for the time being
> with its own atomic state. Note that we've not added bindings for private
> modesetting objects yet, but I don't think those will be needed for rvkms -
> and the same general patterns we're using here should work for adding
> private modesetting objects.
> 
> Signed-off-by: Lyude Paul <lyude@redhat.com>
> 
> ---
> 
> TODO:
> * Add commit data in the future
> 
> Signed-off-by: Lyude Paul <lyude@redhat.com>
> ---
> rust/kernel/drm/kms.rs      |   1 +
> rust/kernel/drm/kms/crtc.rs | 501 ++++++++++++++++++++++++++++++++++++
> 2 files changed, 502 insertions(+)
> create mode 100644 rust/kernel/drm/kms/crtc.rs
> 
> diff --git a/rust/kernel/drm/kms.rs b/rust/kernel/drm/kms.rs
> index 5b075794a1155..4b54611fdba8b 100644
> --- a/rust/kernel/drm/kms.rs
> +++ b/rust/kernel/drm/kms.rs
> @@ -3,6 +3,7 @@
> //! KMS driver abstractions for rust.
> 
> pub mod connector;
> +pub mod crtc;
> pub mod fbdev;
> pub mod plane;
> 
> diff --git a/rust/kernel/drm/kms/crtc.rs b/rust/kernel/drm/kms/crtc.rs
> new file mode 100644
> index 0000000000000..d84db49948380
> --- /dev/null
> +++ b/rust/kernel/drm/kms/crtc.rs
> @@ -0,0 +1,501 @@
> +// SPDX-License-Identifier: GPL-2.0 OR MIT
> +
> +//! KMS driver abstractions for rust.

Maybe this should be a little more specific?

> +
> +use super::{
> +    plane::*,
> +    ModeObject,
> +    StaticModeObject,
> +    KmsDriver,
> +    UnregisteredKmsDevice
> +};
> +use crate::{
> +    bindings,
> +    drm::device::Device,
> +    device,
> +    prelude::*,
> +    private::Sealed,
> +    error::from_result,
> +    types::Opaque,
> +    init::Zeroable,
> +    sync::Arc,
> +    error::to_result,
> +};
> +use core::{
> +    cell::{Cell, UnsafeCell},
> +    marker::*,
> +    ptr::{NonNull, null, null_mut, addr_of_mut, self},
> +    ops::{Deref, DerefMut},
> +    mem,
> +};
> +use macros::vtable;
> +
> +/// The main trait for implementing the [`struct drm_crtc`] API for [`Crtc`].
> +///
> +/// Any KMS driver should have at least one implementation of this type, which allows them to create
> +/// [`Crtc`] objects. Additionally, a driver may store driver-private data within the type that
> +/// implements [`DriverCrtc`] - and it will be made available when using a fully typed [`Crtc`]
> +/// object.
> +///
> +/// # Invariants
> +///
> +/// - Any C FFI callbacks generated using this trait are guaranteed that passed-in
> +///   [`struct drm_crtc`] pointers are contained within a [`Crtc<Self>`].
> +/// - Any C FFI callbacks generated using this trait are guaranteed that passed-in
> +///   [`struct drm_crtc_state`] pointers are contained within a [`CrtcState<Self::State>`].
> +///
> +/// [`struct drm_crtc`]: srctree/include/drm/drm_crtc.h
> +/// [`struct drm_crtc_state`]: srctree/include/drm/drm_crtc.h
> +#[vtable]
> +pub trait DriverCrtc: Send + Sync + Sized {
> +    /// The generated C vtable for this [`DriverCrtc`] implementation.
> +    #[unique]
> +    const OPS: &'static DriverCrtcOps = &DriverCrtcOps {
> +        funcs: bindings::drm_crtc_funcs {
> +            atomic_destroy_state: Some(atomic_destroy_state_callback::<Self::State>),
> +            atomic_duplicate_state: Some(atomic_duplicate_state_callback::<Self::State>),
> +            atomic_get_property: None,
> +            atomic_print_state: None,
> +            atomic_set_property: None,
> +            cursor_move: None,
> +            cursor_set2: None,
> +            cursor_set: None,
> +            destroy: Some(crtc_destroy_callback::<Self>),
> +            disable_vblank: None,
> +            early_unregister: None,
> +            enable_vblank: None,
> +            gamma_set: None, // TODO
> +            get_crc_sources: None,
> +            get_vblank_counter: None,
> +            get_vblank_timestamp: None,
> +            late_register: None,
> +            page_flip: Some(bindings::drm_atomic_helper_page_flip),
> +            page_flip_target: None,
> +            reset: Some(crtc_reset_callback::<Self::State>),
> +            set_config: Some(bindings::drm_atomic_helper_set_config),
> +            set_crc_source: None,
> +            set_property: None,
> +            verify_crc_source: None,
> +        },
> +
> +        helper_funcs: bindings::drm_crtc_helper_funcs {
> +            atomic_disable: None,
> +            atomic_enable: None,
> +            atomic_check: None,
> +            dpms: None,
> +            commit: None,
> +            prepare: None,
> +            disable: None,
> +            mode_set: None,
> +            mode_valid: None,
> +            mode_fixup: None,
> +            atomic_begin: None,
> +            atomic_flush: None,
> +            mode_set_nofb: None,
> +            mode_set_base: None,
> +            mode_set_base_atomic: None,
> +            get_scanout_position: None,
> +        },
> +    };
> +
> +    /// The type to pass to the `args` field of [`Crtc::new`].
> +    ///
> +    /// This type will be made available in in the `args` argument of [`Self::new`]. Drivers which
> +    /// don't need this can simply pass [`()`] here.
> +    type Args;
> +
> +    /// The parent [`KmsDriver`] implementation.
> +    type Driver: KmsDriver;
> +
> +    /// The [`DriverCrtcState`] implementation for this [`DriverCrtc`].
> +    ///
> +    /// See [`DriverCrtcState`] for more info.
> +    type State: DriverCrtcState;
> +
> +    /// The constructor for creating a [`Crtc`] using this [`DriverCrtc`] implementation.
> +    ///
> +    /// Drivers may use this to instantiate their [`DriverCrtc`] object.
> +    fn new(device: &Device<Self::Driver>, args: &Self::Args) -> impl PinInit<Self, Error>;
> +}
> +
> +/// The generated C vtable for a [`DriverCrtc`].
> +///
> +/// This type is created internally by DRM.
> +pub struct DriverCrtcOps {
> +    funcs: bindings::drm_crtc_funcs,
> +    helper_funcs: bindings::drm_crtc_helper_funcs,
> +}
> +
> +/// The main interface for a [`struct drm_crtc`].
> +///
> +/// This type is the main interface for dealing with DRM CRTCs. In addition, it also allows
> +/// immutable access to whatever private data is contained within an implementor's [`DriverCrtc`]
> +/// type.
> +///
> +/// # Invariants
> +///
> +/// - `crtc` and `inner` are initialized for as long as this object is made available to users.
> +/// - The data layout of this structure begins with [`struct drm_crtc`].
> +/// - The atomic state for this type can always be assumed to be of type [`CrtcState<T::State>`].
> +///
> +/// [`struct drm_crtc`]: srctree/include/drm/drm_crtc.h
> +#[repr(C)]
> +#[pin_data]
> +pub struct Crtc<T: DriverCrtc> {
> +    // The FFI drm_crtc object
> +    crtc: Opaque<bindings::drm_crtc>,
> +    /// The driver's private inner data
> +    #[pin]
> +    inner: T,
> +    #[pin]
> +    _p: PhantomPinned,
> +}
> +
> +// SAFETY: DRM expects this struct to be zero-initialized
> +unsafe impl Zeroable for bindings::drm_crtc { }
> +
> +impl<T: DriverCrtc> Sealed for Crtc<T> {}
> +
> +// SAFETY: Our CRTC interfaces are guaranteed to be thread-safe
> +unsafe impl<T: DriverCrtc> Send for Crtc<T> { }
> +
> +// SAFETY: Our CRTC interfaces are guaranteed to be thread-safe
> +unsafe impl<T: DriverCrtc> Sync for Crtc<T> { }
> +
> +impl<T: DriverCrtc> Deref for Crtc<T> {
> +    type Target = T;
> +
> +    fn deref(&self) -> &Self::Target {
> +        &self.inner
> +    }
> +}
> +
> +impl<T: DriverCrtc> ModeObject for Crtc<T> {
> +    type Driver = T::Driver;
> +
> +    fn drm_dev(&self) -> &Device<Self::Driver> {
> +        // SAFETY: DRM connectors exist for as long as the device does, so this pointer is always
> +        // valid
> +        unsafe { Device::borrow((*self.as_raw()).dev) }
> +    }
> +
> +    fn raw_mode_obj(&self) -> *mut bindings::drm_mode_object {
> +        // SAFETY: We don't expose Crtc<T> to users before it's initialized, so `base` is always
> +        // initialized
> +        unsafe { addr_of_mut!((*self.as_raw()).base) }
> +    }
> +}
> +
> +// SAFETY: CRTCs are non-refcounted modesetting objects
> +unsafe impl<T: DriverCrtc> StaticModeObject for Crtc<T> { }
> +
> +impl<T: DriverCrtc> Crtc<T> {
> +    /// Construct a new [`Crtc`].
> +    ///
> +    /// A driver may use this from their [`Kms::create_objects`] callback in order to construct new
> +    /// [`Crtc`] objects.
> +    ///
> +    /// [`Kms::create_objects`]: kernel::drm::kms::Kms::create_objects
> +    pub fn new<'a, 'b: 'a, P, C>(

With two lifetimes and two generic types, this is getting a bit convoluted IMHO.

I wonder if more descriptive names for the generics would help here, like `PlaneData` instead of P.

> +        dev: &'a UnregisteredKmsDevice<'a, T::Driver>,
> +        primary: &'a Plane<P>,
> +        cursor: Option<&'a Plane<C>>,
> +        name: Option<&CStr>,
> +        args: T::Args,
> +    ) -> Result<&'b Self>
> +    where
> +        P: DriverPlane<Driver = T::Driver>,
> +        C: DriverPlane<Driver = T::Driver>
> +    {
> +        let this = Box::try_pin_init(
> +            try_pin_init!(Self {
> +                crtc: Opaque::new(bindings::drm_crtc {
> +                    helper_private: &T::OPS.helper_funcs,
> +                    ..Default::default()
> +                }),
> +                inner <- T::new(dev, &args),
> +                _p: PhantomPinned,
> +            }),
> +            GFP_KERNEL
> +        )?;
> +
> +        to_result(unsafe {
> +            bindings::drm_crtc_init_with_planes(
> +                dev.as_raw(),
> +                this.as_raw(),
> +                primary.as_raw(),
> +                cursor.map_or(null_mut(), |c| c.as_raw()),
> +                &T::OPS.funcs,
> +                name.map_or(null(), |n| n.as_char_ptr())
> +            )
> +        })?;
> +
> +        // Convert the box into a raw pointer, we'll re-assemble it in crtc_destroy_callback()
> +        // SAFETY: We don't move anything
> +        Ok(unsafe { &*Box::into_raw(Pin::into_inner_unchecked(this)) })

Maybe break this into multiple lines?

> +    }
> +}
> +
> +/// A trait implemented by any type that acts as a [`struct drm_crtc`] interface.
> +///
> +/// This is implemented internally by DRM.
> +///
> +/// [`struct drm_crtc`]: srctree/include/drm/drm_crtc.h
> +pub trait AsRawCrtc: StaticModeObject {
> +    /// The type that should be returned for a CRTC state acquired using this CRTC interface
> +    type State: FromRawCrtcState;
> +
> +    /// Return a raw pointer to the `bindings::drm_crtc` for this object
> +    fn as_raw(&self) -> *mut bindings::drm_crtc;
> +
> +    /// Convert a raw `bindings::drm_crtc` pointer into an object of this type.
> +    ///
> +    /// SAFETY: Callers promise that `ptr` points to a valid instance of this type
> +    unsafe fn from_raw<'a>(ptr: *mut bindings::drm_crtc) -> &'a Self;
> +}
> +
> +impl<T: DriverCrtc> AsRawCrtc for Crtc<T> {
> +    type State = CrtcState<T::State>;
> +
> +    fn as_raw(&self) -> *mut bindings::drm_crtc {
> +        self.crtc.get()
> +    }
> +
> +    unsafe fn from_raw<'a>(ptr: *mut bindings::drm_crtc) -> &'a Self {
> +        // SAFETY: Our data layout starts with `bindings::drm_crtc`
> +        unsafe { &*ptr.cast() }
> +    }
> +}
> +
> +unsafe impl Zeroable for bindings::drm_crtc_state { }
> +
> +impl<T: DriverCrtcState> Sealed for CrtcState<T> {}
> +
> +/// The main trait for implementing the [`struct drm_crtc_state`] API for a [`Crtc`].
> +///
> +/// A driver may store driver-private data within the implementor's type, which will be available
> +/// when using a full typed [`CrtcState`] object.
> +///
> +/// # Invariants
> +///
> +/// - Any C FFI callbacks generated using this trait are guaranteed that passed-in
> +///   [`struct drm_crtc`] pointers are contained within a [`Crtc<Self::Crtc>`].
> +/// - Any C FFI callbacks generated using this trait are guaranteed that passed-in
> +///   [`struct drm_crtc_state`] pointers are contained within a [`CrtcState<Self>`].
> +///
> +/// [`struct drm_crtc`]: srctree/include/drm_crtc.h
> +/// [`struct drm_crtc_state`]: srctree/include/drm_crtc.h
> +pub trait DriverCrtcState: Clone + Default + Unpin {
> +    /// The parent CRTC driver for this CRTC state
> +    type Crtc: DriverCrtc<State = Self> where Self: Sized;
> +}
> +
> +/// The main interface for a [`struct drm_crtc_state`].
> +///
> +/// This type is the main interface for dealing with the atomic state of DRM crtcs. In addition, it
> +/// allows access to whatever private data is contained within an implementor's [`DriverCrtcState`]
> +/// type.
> +///
> +/// # Invariants
> +///
> +/// - `state` and `inner` initialized for as long as this object is exposed to users.
> +/// - The data layout of this structure begins with [`struct drm_crtc_state`].
> +/// - The CRTC for this type can always be assumed to be of type [`Crtc<T::Crtc>`].
> +///
> +/// [`struct drm_crtc_state`]: srctree/include/drm/drm_crtc.h
> +#[repr(C)]
> +pub struct CrtcState<T: DriverCrtcState> {
> +    state: Opaque<bindings::drm_crtc_state>,
> +    inner: UnsafeCell<T>,

I don’t think this is being passed to C, nor do I see UnsafeCell being used for its interior mutability
Here, so can’t this just be T?

> +}
> +
> +impl<T: DriverCrtcState> Deref for CrtcState<T> {
> +    type Target = T;
> +
> +    fn deref(&self) -> &Self::Target {
> +        // SAFETY: Our interface ensures that `inner` will not be modified unless only a single
> +        // mutable reference exists to `inner`, so this is safe
> +        unsafe { &*self.inner.get() }
> +    }
> +}
> +
> +impl<T: DriverCrtcState> DerefMut for CrtcState<T> {
> +    fn deref_mut(&mut self) -> &mut Self::Target {
> +        // SAFETY: Our interfaces ensures that we either have one mutable reference to the state
> +        // (this one), or multiple immutable references
> +        unsafe { self.inner.get_mut() }
> +    }
> +}
> +
> +/// A trait implemented by any type which can produce a reference to a [`struct drm_crtc_state`].
> +///
> +/// This is implemented internally by DRM.
> +///
> +/// [`struct drm_crtc_state`]: srctree/include/drm/drm_crtc.h
> +pub trait AsRawCrtcState: private::AsRawCrtcState {
> +    /// The type that this CRTC state interface returns to represent the parent CRTC
> +    type Crtc: AsRawCrtc;
> +}
> +
> +pub(crate) mod private {
> +    use super::*;
> +
> +    #[doc(hidden)]
> +    pub trait AsRawCrtcState {
> +        /// Return a raw pointer to the DRM CRTC state
> +        ///
> +        /// Note that CRTC states are the only atomic state in KMS which don't nicely follow rust's
> +        /// data aliasing rules already.
> +        fn as_raw(&self) -> *mut bindings::drm_crtc_state;
> +    }
> +}
> +
> +pub(super) use private::AsRawCrtcState as AsRawCrtcStatePrivate;
> +
> +/// A trait for providing common methods which can be used on any type that can be used as an atomic
> +/// CRTC state.
> +pub trait RawCrtcState: AsRawCrtcState {
> +    /// Return the CRTC that owns this state.
> +    fn crtc(&self) -> &Self::Crtc {
> +        // SAFETY:
> +        // * This type conversion is guaranteed by type invariance
> +        // * Our interface ensures that this access follows rust's data-aliasing rules
> +        // * `crtc` is guaranteed to never be NULL and is invariant throughout the lifetime of the
> +        //   state
> +        unsafe { <Self::Crtc as AsRawCrtc>::from_raw((*self.as_raw()).crtc) }
> +    }
> +}
> +impl<T: AsRawCrtcState> RawCrtcState for T {}
> +
> +/// A trait implemented for any type which can be constructed directly from a
> +/// [`struct drm_crtc_state`] pointer.
> +///
> +/// This is implemented internally by DRM.
> +///
> +/// [`struct drm_crtc_state`]: srctree/include/drm/drm_crtc.h
> +pub trait FromRawCrtcState: AsRawCrtcState {
> +    /// Obtain a reference back to this type from a raw DRM crtc state pointer
> +    ///
> +    /// # Safety
> +    ///
> +    /// Callers must ensure that ptr contains a valid instance of this type.
> +    unsafe fn from_raw<'a>(ptr: *const bindings::drm_crtc_state) -> &'a Self;
> +}
> +
> +impl<T: DriverCrtcState> private::AsRawCrtcState for CrtcState<T> {
> +    #[inline]
> +    fn as_raw(&self) -> *mut bindings::drm_crtc_state {
> +        self.state.get()
> +    }
> +}
> +
> +impl<T: DriverCrtcState> AsRawCrtcState for CrtcState<T> {
> +    type Crtc = Crtc<T::Crtc>;
> +}
> +
> +impl<T: DriverCrtcState> FromRawCrtcState for CrtcState<T> {
> +    unsafe fn from_raw<'a>(ptr: *const bindings::drm_crtc_state) -> &'a Self {
> +        // SAFETY: Our data layout starts with `bindings::drm_crtc_state`
> +        unsafe { &*(ptr.cast()) }
> +    }
> +}
> +
> +unsafe extern "C" fn crtc_destroy_callback<T: DriverCrtc>(
> +    crtc: *mut bindings::drm_crtc
> +) {
> +    // SAFETY: DRM guarantees that `crtc` points to a valid initialized `drm_crtc`.
> +    unsafe { bindings::drm_crtc_cleanup(crtc) };
> +
> +    // SAFETY:
> +    // - DRM guarantees we are now the only one with access to this [`drm_crtc`].
> +    // - This cast is safe via `DriverCrtc`s type invariants.
> +    // - We created this as a pinned type originally
> +    drop(unsafe { Pin::new_unchecked(Box::from_raw(crtc as *mut Crtc<T>)) });
> +}
> +
> +unsafe extern "C" fn atomic_duplicate_state_callback<T: DriverCrtcState>(
> +    crtc: *mut bindings::drm_crtc
> +) -> *mut bindings::drm_crtc_state {
> +    // SAFETY: DRM guarantees that `crtc` points to a valid initialized `drm_crtc`.
> +    let state = unsafe { (*crtc).state };
> +    if state.is_null() {
> +        return null_mut();
> +    }
> +
> +    // SAFETY: This cast is safe via `DriverCrtcState`s type invariants.
> +    let crtc = unsafe { Crtc::<T::Crtc>::from_raw(crtc) };
> +
> +    // SAFETY: This cast is safe via `DriverCrtcState`s type invariants.
> +    let state = unsafe { CrtcState::<T>::from_raw(state) };
> +
> +    let mut new = Box::try_init(
> +        try_init!(CrtcState::<T> {
> +            state: Opaque::new(Default::default()),
> +            inner: UnsafeCell::new((*state).clone()),
> +        }),
> +        GFP_KERNEL
> +    );
> +
> +    if let Ok(mut new) = new {
> +        let new = Box::into_raw(new).cast();
> +
> +        // SAFETY: DRM simply copies the data from the previous base DRM state here and does not
> +        // move the contents of `ptr`
> +        unsafe { bindings::__drm_atomic_helper_crtc_duplicate_state(crtc.as_raw(), new) }
> +
> +        new
> +    } else {
> +        null_mut()
> +    }
> +}
> +
> +unsafe extern "C" fn atomic_destroy_state_callback<T: DriverCrtcState>(
> +    _crtc: *mut bindings::drm_crtc,
> +    crtc_state: *mut bindings::drm_crtc_state,
> +) {
> +    // SAFETY: DRM guarantees that `state` points to a valid instance of `drm_crtc_state`
> +    unsafe { bindings::__drm_atomic_helper_crtc_destroy_state(crtc_state) };
> +
> +    // SAFETY:
> +    // * DRM guarantees we are the only one with access to this `drm_crtc_state`
> +    // * This cast is safe via our type invariants.
> +    // * All data in `CrtcState` is either Unpin, or pinned
> +    drop(unsafe { Box::from_raw(crtc_state as *mut CrtcState<T>) });
> +}
> +
> +unsafe extern "C" fn crtc_reset_callback<T: DriverCrtcState>(
> +    crtc: *mut bindings::drm_crtc,
> +) {
> +    // SAFETY: DRM guarantees that `state` points to a valid instance of `drm_crtc_state`
> +    let state = unsafe { (*crtc).state };
> +    if !state.is_null() {
> +        // SAFETY:
> +        // * We're guaranteed `crtc` is `Crtc<T>` via type invariants
> +        // * We're guaranteed `state` is `CrtcState<T>` via type invariants.
> +        unsafe { atomic_destroy_state_callback::<T>(crtc, state) }
> +
> +        // SAFETY: No special requirements here, DRM expects this to be NULL
> +        unsafe { (*crtc).state = null_mut(); }
> +    }
> +
> +    // SAFETY: `crtc` is guaranteed to be of type `Crtc<T::Crtc>` by type invariance
> +    let crtc = unsafe { Crtc::<T::Crtc>::from_raw(crtc) };
> +
> +    // Unfortunately, this is the best we can do at the moment as this FFI callback was mistakenly
> +    // presumed to be infallible :(
> +    let new = Box::try_init(
> +        try_init!(CrtcState::<T> {
> +            state: Opaque::new(Default::default()),
> +            inner: UnsafeCell::new(Default::default()),
> +        }),
> +        GFP_KERNEL
> +    ).expect("Unfortunately, this API was presumed infallible");
> +
> +    // SAFETY: DRM takes ownership of the state from here, and will never move it
> +    unsafe {
> +        bindings::__drm_atomic_helper_crtc_reset(
> +            crtc.as_raw(),
> +            Box::into_raw(new).cast()
> +        )
> +    };
> +}
> -- 
> 2.46.1
> 
> 

Overall LGTM.

By the way, what is WIP about this?

— Daniel

  reply	other threads:[~2024-11-27 14:37 UTC|newest]

Thread overview: 109+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20240930233257.1189730-1-lyude@redhat.com>
2024-09-30 23:09 ` [WIP RFC v2 01/35] WIP: rust/drm: Add fourcc bindings Lyude Paul
2024-10-01  9:25   ` Jani Nikula
2024-10-01 15:18     ` Miguel Ojeda
2024-10-03  8:33   ` Louis Chauvet
2024-10-03 20:16     ` Lyude Paul
2024-11-26 17:40   ` Daniel Almeida
2024-11-27 21:11     ` Lyude Paul
2025-01-14 18:54       ` Daniel Almeida
2024-09-30 23:09 ` [WIP RFC v2 02/35] WIP: rust: drm: Add traits for registering KMS devices Lyude Paul
2024-11-26 18:18   ` Daniel Almeida
2024-11-27 21:21     ` Lyude Paul
2024-12-05 14:03       ` Daniel Almeida
2024-12-03 22:41     ` Lyude Paul
2024-12-05 13:43       ` Daniel Almeida
2024-12-06 15:23   ` Alice Ryhl
2024-12-09 23:20     ` Lyude Paul
2024-09-30 23:09 ` [WIP RFC v2 03/35] rust: drm/kms/fbdev: Add FbdevShmem Lyude Paul
2024-11-26 19:58   ` Daniel Almeida
2024-09-30 23:09 ` [WIP RFC v2 04/35] rust: drm/kms: Introduce the main ModeConfigObject traits Lyude Paul
2024-11-26 20:34   ` Daniel Almeida
2024-09-30 23:09 ` [WIP RFC v2 05/35] rust: drm/kms: Add bindings for drm_connector Lyude Paul
2024-11-26 21:25   ` Daniel Almeida
2024-12-04 21:16     ` Lyude Paul
2024-12-04 21:18       ` Lyude Paul
2024-12-10 23:41     ` Lyude Paul
2024-12-11  8:43       ` Simona Vetter
2024-12-12  0:34         ` Lyude Paul
2024-12-12 10:03           ` Simona Vetter
2024-09-30 23:09 ` [WIP RFC v2 06/35] rust: drm/kms: Add drm_plane bindings Lyude Paul
2024-10-03  8:30   ` Louis Chauvet
2024-10-03 20:06     ` Lyude Paul
2024-11-27 14:05   ` Daniel Almeida
2024-12-12 21:28     ` Lyude Paul
2024-09-30 23:09 ` [WIP RFC v2 07/35] WIP: rust: drm/kms: Add drm_crtc bindings Lyude Paul
2024-11-27 14:36   ` Daniel Almeida [this message]
2024-12-12 22:25     ` Lyude Paul
2024-09-30 23:09 ` [WIP RFC v2 08/35] rust: drm/kms: Add bindings for drm_encoder Lyude Paul
2024-09-30 23:09 ` [WIP RFC v2 09/35] WIP: rust: drm/kms: Add Connector.attach_encoder() Lyude Paul
2024-11-27 14:43   ` Daniel Almeida
2024-09-30 23:09 ` [WIP RFC v2 10/35] rust: drm/kms: Add DriverConnector::get_mode callback Lyude Paul
2024-11-27 15:03   ` Daniel Almeida
2024-12-12 22:37     ` Lyude Paul
2024-09-30 23:09 ` [WIP RFC v2 11/35] rust: drm/kms: Add ConnectorGuard::add_modes_noedid() Lyude Paul
2024-11-27 15:06   ` Daniel Almeida
2024-09-30 23:09 ` [WIP RFC v2 12/35] rust: drm/kms: Add ConnectorGuard::set_preferred_mode Lyude Paul
2024-11-27 15:11   ` Daniel Almeida
2024-09-30 23:09 ` [WIP RFC v2 13/35] WIP: rust: drm/kms: Add OpaqueConnector and OpaqueConnectorState Lyude Paul
2024-11-27 15:51   ` Daniel Almeida
2024-12-05 23:25     ` Lyude Paul
2024-09-30 23:09 ` [WIP RFC v2 14/35] WIP: rust: drm/kms: Add OpaqueCrtc and OpaqueCrtcState Lyude Paul
2024-11-27 16:00   ` Daniel Almeida
2024-12-12 23:01     ` Lyude Paul
2024-09-30 23:09 ` [WIP RFC v2 15/35] WIP: rust: drm/kms: Add OpaquePlane and OpaquePlaneState Lyude Paul
2024-11-27 17:03   ` Daniel Almeida
2024-09-30 23:09 ` [WIP RFC v2 16/35] rust: drm/kms: Add RawConnector and RawConnectorState Lyude Paul
2024-11-27 19:26   ` Daniel Almeida
2024-09-30 23:10 ` [WIP RFC v2 17/35] rust: drm/kms: Add RawCrtc and RawCrtcState Lyude Paul
2024-11-27 19:29   ` Daniel Almeida
2024-09-30 23:10 ` [WIP RFC v2 18/35] rust: drm/kms: Add RawPlane and RawPlaneState Lyude Paul
2024-11-27 19:30   ` Daniel Almeida
2024-09-30 23:10 ` [WIP RFC v2 19/35] WIP: rust: drm/kms: Add OpaqueEncoder Lyude Paul
2024-11-27 19:35   ` Daniel Almeida
2024-09-30 23:10 ` [WIP RFC v2 20/35] WIP: rust: drm/kms: Add drm_atomic_state bindings Lyude Paul
2024-11-27 20:54   ` Daniel Almeida
2024-12-12 23:37     ` Lyude Paul
2024-09-30 23:10 ` [WIP RFC v2 21/35] rust: drm/kms: Introduce DriverCrtc::atomic_check() Lyude Paul
2024-11-28 13:37   ` Daniel Almeida
2025-01-13 23:43     ` Lyude Paul
2024-09-30 23:10 ` [WIP RFC v2 22/35] rust: drm/kms: Add DriverPlane::atomic_update() Lyude Paul
2024-11-28 13:38   ` Daniel Almeida
2025-01-13 23:47     ` Lyude Paul
2024-11-28 13:51   ` Daniel Almeida
2025-01-13 23:53     ` Lyude Paul
2024-09-30 23:10 ` [WIP RFC v2 23/35] rust: drm/kms: Add DriverPlane::atomic_check() Lyude Paul
2024-11-28 13:49   ` Daniel Almeida
2025-01-13 23:51     ` Lyude Paul
2024-09-30 23:10 ` [WIP RFC v2 24/35] rust: drm/kms: Add RawCrtcState::active() Lyude Paul
2024-11-28 13:54   ` Daniel Almeida
2024-09-30 23:10 ` [WIP RFC v2 25/35] rust: drm/kms: Add RawPlaneState::crtc() Lyude Paul
2024-11-28 13:58   ` Daniel Almeida
2024-09-30 23:10 ` [WIP RFC v2 26/35] WIP: rust: drm/kms: Add RawPlaneState::atomic_helper_check() Lyude Paul
2024-11-28 14:04   ` Daniel Almeida
2025-01-13 23:57     ` Lyude Paul
2025-01-14 14:07       ` Simona Vetter
2024-09-30 23:10 ` [WIP RFC v2 27/35] rust: drm/kms: Add drm_framebuffer bindings Lyude Paul
2024-11-28 14:26   ` Daniel Almeida
2024-09-30 23:10 ` [WIP RFC v2 28/35] rust: drm/kms: Add RawPlane::framebuffer() Lyude Paul
2024-11-28 14:29   ` Daniel Almeida
2025-01-14  0:03     ` Lyude Paul
2025-01-14 14:09       ` Simona Vetter
2024-09-30 23:10 ` [WIP RFC v2 29/35] rust: drm/kms: Add DriverCrtc::atomic_begin() and atomic_flush() Lyude Paul
2024-11-28 14:31   ` Daniel Almeida
2024-09-30 23:10 ` [WIP RFC v2 30/35] rust: drm/kms: Add DriverCrtc::atomic_enable() and atomic_disable() Lyude Paul
2024-11-28 14:33   ` Daniel Almeida
2024-09-30 23:10 ` [WIP RFC v2 31/35] rust: drm: Add Device::event_lock() Lyude Paul
2024-11-28 14:35   ` Daniel Almeida
2024-09-30 23:10 ` [WIP RFC v2 32/35] rust: drm/kms: Add Device::num_crtcs() Lyude Paul
2024-11-28 14:38   ` Daniel Almeida
2025-01-14  0:05     ` Lyude Paul
2024-09-30 23:10 ` [WIP RFC v2 33/35] WIP: rust: drm/kms: Add VblankSupport Lyude Paul
2024-12-05 15:29   ` Daniel Almeida
2025-01-14  0:43     ` Lyude Paul
2025-01-14 14:24       ` Simona Vetter
2025-01-14 15:04         ` Miguel Ojeda
2025-01-14 15:38           ` Simona Vetter
2024-09-30 23:10 ` [WIP RFC v2 34/35] WIP: rust: drm/kms: Add Kms::atomic_commit_tail Lyude Paul
2024-12-05 16:09   ` Daniel Almeida
2024-09-30 23:10 ` [WIP RFC v2 35/35] WIP: drm: Introduce RVKMS! Lyude Paul
2024-12-05 16:36   ` Daniel Almeida

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=042BD8BE-A0E1-4CD4-89AB-96314DABECA3@collabora.com \
    --to=daniel.almeida@collabora.com \
    --cc=a.hindborg@samsung.com \
    --cc=airlied@redhat.com \
    --cc=alex.gaynor@gmail.com \
    --cc=aliceryhl@google.com \
    --cc=benno.lossin@proton.me \
    --cc=bjorn3_gh@protonmail.com \
    --cc=boqun.feng@gmail.com \
    --cc=cjia@nvidia.com \
    --cc=dakr@kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=gary@garyguo.net \
    --cc=jhubbard@nvidia.com \
    --cc=lina@asahilina.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lyude@redhat.com \
    --cc=mcanal@igalia.com \
    --cc=ojeda@kernel.org \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=tmgross@umich.edu \
    --cc=wedsonaf@gmail.com \
    --cc=zhiw@nvidia.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®