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: u32The plane’s KMS object id.
possible_crtcs: u32Bitmask of CRTC indices this plane can feed.
plane_type: PlaneTypePrimary, overlay, or cursor.
formats: Vec<u32>Advertised FourCCs, from the bare formats list.
format_table: FormatTableThe 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: u64Supported 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: boolWhether the plane exposes a rotation property at all.
supports_scaling: boolWhether 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: boolWhether the driver exposed IN_FORMATS.
has_pixel_blend_mode: boolWhether 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: boolWhether 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: boolWhether the plane exposes the "alpha" per-plane alpha property.
Independent of has_pixel_blend_mode —
some hardware has one without the other.
blend_modes: BlendModeValuesCached blend-mode enum integers.
has_color_encoding: boolWhether the plane exposes COLOR_ENCODING. Only YCbCr-capable planes
do; the scene skips the write for the rest.
color_encodings: ColorEncodingValuesCached COLOR_ENCODING enum integers.
has_color_range: boolWhether the plane exposes COLOR_RANGE.
color_ranges: ColorRangeValuesCached COLOR_RANGE enum integers.
color_pipeline: ColorPipelinePer-plane color pipeline support.
cursor_max_w: u32The 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: u32The 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
impl PlaneCapabilities
Sourcepub fn supports_format(&self, fourcc: u32) -> bool
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.
Sourcepub fn scans_out(&self, fourcc: u32, modifier: Modifier) -> bool
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).
Sourcepub fn scans_out_linear(&self, fourcc: u32) -> bool
pub fn scans_out_linear(&self, fourcc: u32) -> bool
Whether the plane scans out a linear buffer of fourcc: what a dumb
buffer is.
Sourcepub const fn compatible_with_crtc(&self, crtc_index: u32) -> bool
pub const fn compatible_with_crtc(&self, crtc_index: u32) -> bool
Whether this plane can feed the CRTC at crtc_index.
Sourcepub fn bandwidth_class(&self, modifier: u64) -> BandwidthClass
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.
Sourcepub fn build_format_metadata(&mut self)
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.
Sourcepub fn distinct_modifier_count(&self) -> usize
pub fn distinct_modifier_count(&self) -> usize
How many distinct modifiers have a precomputed class.