drmkit_fmt/lib.rs
1// SPDX-FileCopyrightText: (c) 2026 Joel Winarske
2// SPDX-License-Identifier: MIT
3
4#![no_std]
5
6//! Format-modifier and hardware-compression support for drmkit's plane
7//! allocator.
8//!
9//! Port of `src/fmt/` from drm-cxx @ `dc2915b`.
10//!
11//! # Design contract
12//!
13//! Carried verbatim from the C++, because the allocator depends on all three:
14//!
15//! - **`IN_FORMATS` prunes the bipartite graph — necessary, not sufficient.**
16//! - **The atomic `TEST_ONLY` commit is ground truth** for what a plane can
17//! scan out.
18//! - **[`BandwidthClass`] is a cost input to placement scoring, never a
19//! correctness gate.**
20//!
21//! This keeps every vendor on one code path — AFBC (Arm/Rockchip/MediaTek),
22//! AMD DCC, Qualcomm UBWC, NVIDIA block-linear, Broadcom tiling: a
23//! `(fourcc, modifier)` pair flows from the producer's allocation, through
24//! `IN_FORMATS` eligibility, to a probed-and-memoized test commit.
25//!
26//! # Scope
27//!
28//! This crate is `no_std + alloc` and device-free. Two pieces of the C++
29//! `fmt/` header live elsewhere in the port:
30//!
31//! - `FormatTable::from_plane(fd, plane_id)` — blob fetching belongs to
32//! `drmkit-core`'s property layer, which hands the bytes to
33//! [`FormatTable::from_blob`]. The C++ had already split the parser out for
34//! testability; this makes the split structural.
35//! - `ScanoutBuffer` — not ported as one type: GBM allocation is
36//! `drmkit-gbm`'s `GbmBuffer`, and the framebuffer modifier rule is
37//! `drmkit-core`'s `framebuffer_modifier`.
38//!
39//! # Example
40//!
41//! ```
42//! use drmkit_fmt::{
43//! BandwidthClass, FormatTable, Modifier, classify, fourcc, layer_fits_plane,
44//! };
45//!
46//! let plane = FormatTable::from_pairs([
47//! (fourcc::XRGB8888, Modifier::LINEAR),
48//! (fourcc::NV12, Modifier::LINEAR),
49//! ]);
50//!
51//! assert!(layer_fits_plane(&plane, fourcc::XRGB8888, Modifier::LINEAR));
52//! assert!(!layer_fits_plane(&plane, fourcc::ARGB8888, Modifier::LINEAR));
53//!
54//! // The INVALID sentinel is interchangeable with LINEAR.
55//! assert!(layer_fits_plane(&plane, fourcc::NV12, Modifier::INVALID));
56//!
57//! assert_eq!(classify(Modifier::LINEAR), BandwidthClass::Linear);
58//! ```
59
60extern crate alloc;
61
62pub mod fourcc;
63
64mod cost;
65mod describe;
66mod family;
67mod modifier;
68mod probe;
69mod table;
70
71pub use cost::{DEFAULT_COMPRESSED_RATIO, scanout_cost_bytes};
72pub use describe::describe;
73pub use family::{ModifierFamily, sand_col_height, sand128_col_height};
74pub use fourcc::{format_bpp, format_name};
75pub use modifier::{
76 ARM_16X16_BLOCK_U_INTERLEAVED, BandwidthClass, Modifier, Rotation, afbc_block, afbc_flag,
77 arm_type, broadcom, classify, mod_code, rotation_compatible, vendor,
78};
79pub use probe::{ModifierProbeCache, Verdict};
80pub use table::{FormatMod, FormatTable, layer_fits_plane};
81
82#[cfg(test)]
83mod tests;