Skip to main content

PlaneCapabilities

Struct PlaneCapabilities 

Source
pub struct PlaneCapabilities {
Show 24 fields pub id: u32, pub possible_crtcs: u32, pub plane_type: PlaneType, pub formats: Vec<u32>, pub format_table: FormatTable, pub zpos_min: Option<u64>, pub zpos_max: Option<u64>, pub multirect_parent: Option<u32>, pub rotation_bits: u64, pub supports_rotation: bool, pub supports_scaling: bool, pub has_format_modifiers: bool, pub has_pixel_blend_mode: bool, pub has_fb_damage_clips: bool, pub has_per_plane_alpha: bool, pub blend_modes: BlendModeValues, pub has_color_encoding: bool, pub color_encodings: ColorEncodingValues, pub has_color_range: bool, pub color_ranges: ColorRangeValues, pub color_pipeline: ColorPipeline, pub cursor_max_w: u32, pub cursor_max_h: u32, pub modifier_classes: Vec<(u64, BandwidthClass)>,
}
Expand description

Everything the allocator needs to know about one plane.

The has_* flags mirror the kernel’s own property presence one-for-one, so they stay independent booleans rather than a bitfield: a caller building a fixture writes exactly the properties the hardware it is modeling exposes, and packing them would make that unreadable.

Fields§

§id: u32

The plane’s KMS object id.

§possible_crtcs: u32

Bitmask of CRTC indices this plane can feed.

§plane_type: PlaneType

Primary, overlay, or cursor.

§formats: Vec<u32>

Advertised FourCCs, from the bare formats list.

§format_table: FormatTable

The queryable view of IN_FORMATS.

Built from the blob at enumeration. When the driver exposes no IN_FORMATS, build_format_metadata synthesizes LINEAR for each advertised format. The allocator’s edge predicate queries this through drmkit_fmt::layer_fits_plane.

§zpos_min: Option<u64>

Minimum zpos, if the plane exposes the property.

§zpos_max: Option<u64>

Maximum zpos, if the plane exposes the property.

§multirect_parent: Option<u32>

For a multirect “virtual” plane – the second rectangle of a hardware pipe, which some controllers publish as its own plane – the id of the parent plane it is only valid alongside. None for ordinary planes. Read from the driver’s read-only capabilities blob (primary_smart_plane_id=); see parse_multirect_parent.

§rotation_bits: u64

Supported rotate/reflect angles as a DRM_MODE_ROTATE_* / DRM_MODE_REFLECT_* mask; 0 when the plane exposes no rotation.

A plane can have supports_rotation true and still omit 90/270 here — 0/180- or reflect-only hardware — which is why the allocator gates on these bits rather than the flag. Not hypothetical: measured on a Raspberry Pi 5, every one of vc4’s 56 planes reports 0x35 — 0, 180, and both reflects, with no 90 or 270. vkms reports 0x3f and amdgpu 0xf on the same probe.

§supports_rotation: bool

Whether the plane exposes a rotation property at all.

§supports_scaling: bool

Whether the plane may be asked to scale.

Not a measured capability, and the name is the most optimistic reading of what KMS offers. PlaneRegistry::probe sets it from the presence of SRC_W, which every atomic plane has – so on a real device it is true everywhere, vkms and its absent scaler included. There is no property that answers the question; the TEST_ONLY commit is what finds out, and the allocator’s search is built around that.

It stays because a fixture, a replay, or a caller that knows its hardware can set it false and have the matcher skip those planes before spending a test commit on them. See drm-cxx#252.

§has_format_modifiers: bool

Whether the driver exposed IN_FORMATS.

§has_pixel_blend_mode: bool

Whether the plane exposes "pixel blend mode".

Absence means scanout blending is hardwired by the driver — typically opaque pixel-replace, so a transparent source pixel paints opaque black over whatever is beneath it.

§has_fb_damage_clips: bool

Whether the plane exposes FB_DAMAGE_CLIPS.

Per plane, not per device, because it is not all-or-nothing: amdgpu attaches it to six of its ten planes. A scene that reports partial damage on a plane without it gets full-frame repaints there and partial ones elsewhere, which is correct but worth being able to see.

Narrower than it looks. drm_plane_enable_fb_damage_clips is opt-in per driver: amdgpu calls it, vkms and vc4 do not.

§has_per_plane_alpha: bool

Whether the plane exposes the "alpha" per-plane alpha property. Independent of has_pixel_blend_mode — some hardware has one without the other.

§blend_modes: BlendModeValues

Cached blend-mode enum integers.

§has_color_encoding: bool

Whether the plane exposes COLOR_ENCODING. Only YCbCr-capable planes do; the scene skips the write for the rest.

§color_encodings: ColorEncodingValues

Cached COLOR_ENCODING enum integers.

§has_color_range: bool

Whether the plane exposes COLOR_RANGE.

§color_ranges: ColorRangeValues

Cached COLOR_RANGE enum integers.

§color_pipeline: ColorPipeline

Per-plane color pipeline support.

§cursor_max_w: u32

The device’s DRM_CAP_CURSOR_WIDTH, on a cursor plane. Zero on any other plane, and where the driver reports none; zero leaves the allocator’s cursor-size guard off.

§cursor_max_h: u32

The device’s DRM_CAP_CURSOR_HEIGHT, on a cursor plane, as cursor_max_w.

§modifier_classes: Vec<(u64, BandwidthClass)>

One bandwidth class per distinct advertised modifier, sorted by modifier, so the allocator hot path never re-decodes modifier bits.

Filled by build_format_metadata; query through bandwidth_class.

Public because a caller building a fixture constructs PlaneCapabilities with struct-update syntax, which a private field would block — the same reason the C++ leaves it a public member. It is derived state: leave it empty and let PlaneRegistry::from_capabilities fill it.

Implementations§

Source§

impl PlaneCapabilities

Source

pub fn supports_format(&self, fourcc: u32) -> bool

Whether the bare formats list advertises a FourCC.

This is the pre-IN_FORMATS check and ignores modifiers entirely, so it does not say whether a given buffer will scan out: a plane can list a format it takes only compressed. Ask scans_out that.

Source

pub fn scans_out(&self, fourcc: u32, modifier: Modifier) -> bool

Whether the plane scans out fourcc in the modifier layout.

By the plane’s IN_FORMATS table, with layer_fits_plane’s equivalences, or by the bare format list on a plane without one. The RK3566’s Cluster windows are why the list alone is not enough: they list ARGB8888 and take it only as AFBC, and refuse a linear buffer at check time (P-48).

Source

pub fn scans_out_linear(&self, fourcc: u32) -> bool

Whether the plane scans out a linear buffer of fourcc: what a dumb buffer is.

Source

pub const fn compatible_with_crtc(&self, crtc_index: u32) -> bool

Whether this plane can feed the CRTC at crtc_index.

Source

pub fn bandwidth_class(&self, modifier: u64) -> BandwidthClass

The precomputed bandwidth class for a modifier.

Falls back to a live classify for a modifier outside the advertised set — decoding it rather than guessing.

Source

pub fn build_format_metadata(&mut self)

Populate the format table and bandwidth-class index.

Called once per plane at registry construction, and safe to re-run. A plane exposing no IN_FORMATS gets LINEAR synthesized for each advertised format, so the allocator can still place linear buffers on it.

Source

pub fn distinct_modifier_count(&self) -> usize

How many distinct modifiers have a precomputed class.

Trait Implementations§

Source§

impl Clone for PlaneCapabilities

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for PlaneCapabilities

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for PlaneCapabilities

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.