xref: /aosp_15_r20/external/mesa3d/src/nouveau/nil/modifiers.rs (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker // Copyright © 2024 Valve Corporation
2*61046927SAndroid Build Coastguard Worker // SPDX-License-Identifier: MIT
3*61046927SAndroid Build Coastguard Worker 
4*61046927SAndroid Build Coastguard Worker use crate::format::Format;
5*61046927SAndroid Build Coastguard Worker use crate::image::Image;
6*61046927SAndroid Build Coastguard Worker use crate::tiling::Tiling;
7*61046927SAndroid Build Coastguard Worker 
8*61046927SAndroid Build Coastguard Worker use bitview::*;
9*61046927SAndroid Build Coastguard Worker use nvidia_headers::classes::{cl9097, clc597};
10*61046927SAndroid Build Coastguard Worker 
11*61046927SAndroid Build Coastguard Worker pub const MAX_DRM_FORMAT_MODS: usize = 7;
12*61046927SAndroid Build Coastguard Worker 
13*61046927SAndroid Build Coastguard Worker #[repr(u8)]
14*61046927SAndroid Build Coastguard Worker #[derive(Clone, Copy, Eq, PartialEq)]
15*61046927SAndroid Build Coastguard Worker pub enum GOBKindVersion {
16*61046927SAndroid Build Coastguard Worker     Fermi = 0,
17*61046927SAndroid Build Coastguard Worker     G80 = 1,
18*61046927SAndroid Build Coastguard Worker     Turing = 2,
19*61046927SAndroid Build Coastguard Worker }
20*61046927SAndroid Build Coastguard Worker 
21*61046927SAndroid Build Coastguard Worker impl TryFrom<u64> for GOBKindVersion {
22*61046927SAndroid Build Coastguard Worker     type Error = &'static str;
23*61046927SAndroid Build Coastguard Worker 
try_from(gob_kind_version: u64) -> Result<Self, Self::Error>24*61046927SAndroid Build Coastguard Worker     fn try_from(gob_kind_version: u64) -> Result<Self, Self::Error> {
25*61046927SAndroid Build Coastguard Worker         match gob_kind_version {
26*61046927SAndroid Build Coastguard Worker             0 => Ok(GOBKindVersion::Fermi),
27*61046927SAndroid Build Coastguard Worker             1 => Ok(GOBKindVersion::G80),
28*61046927SAndroid Build Coastguard Worker             2 => Ok(GOBKindVersion::Turing),
29*61046927SAndroid Build Coastguard Worker             _ => Err("Invalid gob/kind version"),
30*61046927SAndroid Build Coastguard Worker         }
31*61046927SAndroid Build Coastguard Worker     }
32*61046927SAndroid Build Coastguard Worker }
33*61046927SAndroid Build Coastguard Worker 
34*61046927SAndroid Build Coastguard Worker impl GOBKindVersion {
for_dev(dev: &nil_rs_bindings::nv_device_info) -> GOBKindVersion35*61046927SAndroid Build Coastguard Worker     pub fn for_dev(dev: &nil_rs_bindings::nv_device_info) -> GOBKindVersion {
36*61046927SAndroid Build Coastguard Worker         if dev.cls_eng3d >= clc597::TURING_A {
37*61046927SAndroid Build Coastguard Worker             GOBKindVersion::Turing
38*61046927SAndroid Build Coastguard Worker         } else if dev.cls_eng3d >= cl9097::FERMI_A {
39*61046927SAndroid Build Coastguard Worker             GOBKindVersion::Fermi
40*61046927SAndroid Build Coastguard Worker         } else {
41*61046927SAndroid Build Coastguard Worker             GOBKindVersion::G80
42*61046927SAndroid Build Coastguard Worker         }
43*61046927SAndroid Build Coastguard Worker     }
44*61046927SAndroid Build Coastguard Worker }
45*61046927SAndroid Build Coastguard Worker 
46*61046927SAndroid Build Coastguard Worker #[repr(u8)]
47*61046927SAndroid Build Coastguard Worker #[derive(Clone, Copy, Eq, PartialEq)]
48*61046927SAndroid Build Coastguard Worker pub enum SectorLayout {
49*61046927SAndroid Build Coastguard Worker     TegraK1 = 0,
50*61046927SAndroid Build Coastguard Worker     Desktop = 1,
51*61046927SAndroid Build Coastguard Worker }
52*61046927SAndroid Build Coastguard Worker 
53*61046927SAndroid Build Coastguard Worker impl TryFrom<u64> for SectorLayout {
54*61046927SAndroid Build Coastguard Worker     type Error = &'static str;
55*61046927SAndroid Build Coastguard Worker 
try_from(sector_layout: u64) -> Result<Self, Self::Error>56*61046927SAndroid Build Coastguard Worker     fn try_from(sector_layout: u64) -> Result<Self, Self::Error> {
57*61046927SAndroid Build Coastguard Worker         match sector_layout {
58*61046927SAndroid Build Coastguard Worker             0 => Ok(SectorLayout::TegraK1),
59*61046927SAndroid Build Coastguard Worker             1 => Ok(SectorLayout::Desktop),
60*61046927SAndroid Build Coastguard Worker             _ => Err("Invalid gob/kind version"),
61*61046927SAndroid Build Coastguard Worker         }
62*61046927SAndroid Build Coastguard Worker     }
63*61046927SAndroid Build Coastguard Worker }
64*61046927SAndroid Build Coastguard Worker 
65*61046927SAndroid Build Coastguard Worker impl SectorLayout {
66*61046927SAndroid Build Coastguard Worker     // For now, this always returns desktop, but will be different for Tegra
for_dev(_dev: &nil_rs_bindings::nv_device_info) -> SectorLayout67*61046927SAndroid Build Coastguard Worker     pub fn for_dev(_dev: &nil_rs_bindings::nv_device_info) -> SectorLayout {
68*61046927SAndroid Build Coastguard Worker         SectorLayout::Desktop
69*61046927SAndroid Build Coastguard Worker     }
70*61046927SAndroid Build Coastguard Worker }
71*61046927SAndroid Build Coastguard Worker 
72*61046927SAndroid Build Coastguard Worker #[repr(u8)]
73*61046927SAndroid Build Coastguard Worker #[allow(dead_code)]
74*61046927SAndroid Build Coastguard Worker #[derive(Clone, Copy, Eq, PartialEq)]
75*61046927SAndroid Build Coastguard Worker pub enum CompressionType {
76*61046927SAndroid Build Coastguard Worker     None = 0,
77*61046927SAndroid Build Coastguard Worker     ROP3DOne = 1,
78*61046927SAndroid Build Coastguard Worker     ROP3DTwo = 2,
79*61046927SAndroid Build Coastguard Worker     CDEHorizontal = 3,
80*61046927SAndroid Build Coastguard Worker     CDEVertical = 4,
81*61046927SAndroid Build Coastguard Worker }
82*61046927SAndroid Build Coastguard Worker 
83*61046927SAndroid Build Coastguard Worker impl TryFrom<u64> for CompressionType {
84*61046927SAndroid Build Coastguard Worker     type Error = &'static str;
85*61046927SAndroid Build Coastguard Worker 
try_from(compression_type: u64) -> Result<Self, Self::Error>86*61046927SAndroid Build Coastguard Worker     fn try_from(compression_type: u64) -> Result<Self, Self::Error> {
87*61046927SAndroid Build Coastguard Worker         match compression_type {
88*61046927SAndroid Build Coastguard Worker             0 => Ok(CompressionType::None),
89*61046927SAndroid Build Coastguard Worker             1 => Ok(CompressionType::ROP3DOne),
90*61046927SAndroid Build Coastguard Worker             2 => Ok(CompressionType::ROP3DTwo),
91*61046927SAndroid Build Coastguard Worker             3 => Ok(CompressionType::CDEHorizontal),
92*61046927SAndroid Build Coastguard Worker             4 => Ok(CompressionType::CDEVertical),
93*61046927SAndroid Build Coastguard Worker             _ => Err("Invalid gob/kind version"),
94*61046927SAndroid Build Coastguard Worker         }
95*61046927SAndroid Build Coastguard Worker     }
96*61046927SAndroid Build Coastguard Worker }
97*61046927SAndroid Build Coastguard Worker 
98*61046927SAndroid Build Coastguard Worker pub const DRM_FORMAT_MOD_LINEAR: u64 = 0;
99*61046927SAndroid Build Coastguard Worker pub const DRM_FORMAT_MOD_INVALID: u64 = 0x00ffffff_ffffffff;
100*61046927SAndroid Build Coastguard Worker 
101*61046927SAndroid Build Coastguard Worker const DRM_FORMAT_MOD_VENDOR_NVIDIA: u8 = 0x03;
102*61046927SAndroid Build Coastguard Worker 
103*61046927SAndroid Build Coastguard Worker pub struct BlockLinearModifier {
104*61046927SAndroid Build Coastguard Worker     drm_modifier: u64,
105*61046927SAndroid Build Coastguard Worker }
106*61046927SAndroid Build Coastguard Worker 
107*61046927SAndroid Build Coastguard Worker impl TryFrom<u64> for BlockLinearModifier {
108*61046927SAndroid Build Coastguard Worker     type Error = &'static str;
109*61046927SAndroid Build Coastguard Worker 
try_from(drm_modifier: u64) -> Result<Self, Self::Error>110*61046927SAndroid Build Coastguard Worker     fn try_from(drm_modifier: u64) -> Result<Self, Self::Error> {
111*61046927SAndroid Build Coastguard Worker         let bv = BitView::new(&drm_modifier);
112*61046927SAndroid Build Coastguard Worker         let vendor: u8 = bv.get_bit_range_u64(56..64).try_into().unwrap();
113*61046927SAndroid Build Coastguard Worker         if vendor != DRM_FORMAT_MOD_VENDOR_NVIDIA {
114*61046927SAndroid Build Coastguard Worker             Err("modifier does not have DRM_FORMAT_MOD_VENDOR_NVIDIA")
115*61046927SAndroid Build Coastguard Worker         } else if !bv.get_bit(4) {
116*61046927SAndroid Build Coastguard Worker             Err("modifier is not block linear")
117*61046927SAndroid Build Coastguard Worker         } else if bv.get_bit_range_u64(5..12) != 0
118*61046927SAndroid Build Coastguard Worker             || bv.get_bit_range_u64(26..56) != 0
119*61046927SAndroid Build Coastguard Worker         {
120*61046927SAndroid Build Coastguard Worker             Err("unknown reserved bits")
121*61046927SAndroid Build Coastguard Worker         } else {
122*61046927SAndroid Build Coastguard Worker             Ok(BlockLinearModifier { drm_modifier })
123*61046927SAndroid Build Coastguard Worker         }
124*61046927SAndroid Build Coastguard Worker     }
125*61046927SAndroid Build Coastguard Worker }
126*61046927SAndroid Build Coastguard Worker 
127*61046927SAndroid Build Coastguard Worker impl BlockLinearModifier {
block_linear_2d( compression_type: CompressionType, sector_layout: SectorLayout, gob_kind_version: GOBKindVersion, pte_kind: u8, height_log2: u8, ) -> BlockLinearModifier128*61046927SAndroid Build Coastguard Worker     pub fn block_linear_2d(
129*61046927SAndroid Build Coastguard Worker         compression_type: CompressionType,
130*61046927SAndroid Build Coastguard Worker         sector_layout: SectorLayout,
131*61046927SAndroid Build Coastguard Worker         gob_kind_version: GOBKindVersion,
132*61046927SAndroid Build Coastguard Worker         pte_kind: u8,
133*61046927SAndroid Build Coastguard Worker         height_log2: u8,
134*61046927SAndroid Build Coastguard Worker     ) -> BlockLinearModifier {
135*61046927SAndroid Build Coastguard Worker         let mut drm_modifier = 0_u64;
136*61046927SAndroid Build Coastguard Worker         let mut bv = BitMutView::new(&mut drm_modifier);
137*61046927SAndroid Build Coastguard Worker         bv.set_field(0..4, height_log2);
138*61046927SAndroid Build Coastguard Worker         bv.set_bit(4, true); // Must be 1, to indicate block-linear layout.
139*61046927SAndroid Build Coastguard Worker         bv.set_field(12..20, pte_kind);
140*61046927SAndroid Build Coastguard Worker         bv.set_field(20..22, gob_kind_version as u8);
141*61046927SAndroid Build Coastguard Worker         bv.set_field(22..23, sector_layout as u8);
142*61046927SAndroid Build Coastguard Worker         bv.set_field(23..26, compression_type as u8);
143*61046927SAndroid Build Coastguard Worker         bv.set_field(56..64, DRM_FORMAT_MOD_VENDOR_NVIDIA);
144*61046927SAndroid Build Coastguard Worker         BlockLinearModifier { drm_modifier }
145*61046927SAndroid Build Coastguard Worker     }
146*61046927SAndroid Build Coastguard Worker 
height_log2(&self) -> u8147*61046927SAndroid Build Coastguard Worker     pub fn height_log2(&self) -> u8 {
148*61046927SAndroid Build Coastguard Worker         let bv = BitView::new(&self.drm_modifier);
149*61046927SAndroid Build Coastguard Worker         bv.get_bit_range_u64(0..4).try_into().unwrap()
150*61046927SAndroid Build Coastguard Worker     }
151*61046927SAndroid Build Coastguard Worker 
pte_kind(&self) -> u8152*61046927SAndroid Build Coastguard Worker     pub fn pte_kind(&self) -> u8 {
153*61046927SAndroid Build Coastguard Worker         let bv = BitView::new(&self.drm_modifier);
154*61046927SAndroid Build Coastguard Worker         bv.get_bit_range_u64(12..20).try_into().unwrap()
155*61046927SAndroid Build Coastguard Worker     }
156*61046927SAndroid Build Coastguard Worker 
gob_kind_version(&self) -> GOBKindVersion157*61046927SAndroid Build Coastguard Worker     pub fn gob_kind_version(&self) -> GOBKindVersion {
158*61046927SAndroid Build Coastguard Worker         let bv = BitView::new(&self.drm_modifier);
159*61046927SAndroid Build Coastguard Worker         bv.get_bit_range_u64(20..22).try_into().unwrap()
160*61046927SAndroid Build Coastguard Worker     }
161*61046927SAndroid Build Coastguard Worker 
sector_layout(&self) -> SectorLayout162*61046927SAndroid Build Coastguard Worker     pub fn sector_layout(&self) -> SectorLayout {
163*61046927SAndroid Build Coastguard Worker         let bv = BitView::new(&self.drm_modifier);
164*61046927SAndroid Build Coastguard Worker         bv.get_bit_range_u64(22..23).try_into().unwrap()
165*61046927SAndroid Build Coastguard Worker     }
166*61046927SAndroid Build Coastguard Worker 
compression_type(&self) -> CompressionType167*61046927SAndroid Build Coastguard Worker     pub fn compression_type(&self) -> CompressionType {
168*61046927SAndroid Build Coastguard Worker         let bv = BitView::new(&self.drm_modifier);
169*61046927SAndroid Build Coastguard Worker         bv.get_bit_range_u64(23..26).try_into().unwrap()
170*61046927SAndroid Build Coastguard Worker     }
171*61046927SAndroid Build Coastguard Worker 
tiling(&self) -> Tiling172*61046927SAndroid Build Coastguard Worker     pub fn tiling(&self) -> Tiling {
173*61046927SAndroid Build Coastguard Worker         Tiling {
174*61046927SAndroid Build Coastguard Worker             is_tiled: true,
175*61046927SAndroid Build Coastguard Worker             gob_height_is_8: self.gob_kind_version() != GOBKindVersion::G80,
176*61046927SAndroid Build Coastguard Worker             x_log2: 0,
177*61046927SAndroid Build Coastguard Worker             y_log2: self.height_log2(),
178*61046927SAndroid Build Coastguard Worker             z_log2: 0,
179*61046927SAndroid Build Coastguard Worker         }
180*61046927SAndroid Build Coastguard Worker     }
181*61046927SAndroid Build Coastguard Worker }
182*61046927SAndroid Build Coastguard Worker 
183*61046927SAndroid Build Coastguard Worker #[no_mangle]
nil_drm_format_mods_for_format( dev: &nil_rs_bindings::nv_device_info, format: Format, mod_count: &mut usize, mods: &mut [u64; MAX_DRM_FORMAT_MODS], )184*61046927SAndroid Build Coastguard Worker pub extern "C" fn nil_drm_format_mods_for_format(
185*61046927SAndroid Build Coastguard Worker     dev: &nil_rs_bindings::nv_device_info,
186*61046927SAndroid Build Coastguard Worker     format: Format,
187*61046927SAndroid Build Coastguard Worker     mod_count: &mut usize,
188*61046927SAndroid Build Coastguard Worker     mods: &mut [u64; MAX_DRM_FORMAT_MODS],
189*61046927SAndroid Build Coastguard Worker ) {
190*61046927SAndroid Build Coastguard Worker     drm_format_mods_for_format(dev, format, mod_count, mods)
191*61046927SAndroid Build Coastguard Worker }
192*61046927SAndroid Build Coastguard Worker 
drm_format_mods_for_format( dev: &nil_rs_bindings::nv_device_info, format: Format, mod_count: &mut usize, mods: &mut [u64; MAX_DRM_FORMAT_MODS], )193*61046927SAndroid Build Coastguard Worker pub fn drm_format_mods_for_format(
194*61046927SAndroid Build Coastguard Worker     dev: &nil_rs_bindings::nv_device_info,
195*61046927SAndroid Build Coastguard Worker     format: Format,
196*61046927SAndroid Build Coastguard Worker     mod_count: &mut usize,
197*61046927SAndroid Build Coastguard Worker     mods: &mut [u64; MAX_DRM_FORMAT_MODS],
198*61046927SAndroid Build Coastguard Worker ) {
199*61046927SAndroid Build Coastguard Worker     let max_mod_count = *mod_count;
200*61046927SAndroid Build Coastguard Worker     *mod_count = 0;
201*61046927SAndroid Build Coastguard Worker 
202*61046927SAndroid Build Coastguard Worker     if format.is_depth_or_stencil() {
203*61046927SAndroid Build Coastguard Worker         return;
204*61046927SAndroid Build Coastguard Worker     }
205*61046927SAndroid Build Coastguard Worker 
206*61046927SAndroid Build Coastguard Worker     if !format.supports_color_targets(dev) {
207*61046927SAndroid Build Coastguard Worker         return;
208*61046927SAndroid Build Coastguard Worker     }
209*61046927SAndroid Build Coastguard Worker 
210*61046927SAndroid Build Coastguard Worker     // These formats don't have a corresponding fourcc format
211*61046927SAndroid Build Coastguard Worker     let p_format: nil_rs_bindings::pipe_format = format.into();
212*61046927SAndroid Build Coastguard Worker     if p_format == nil_rs_bindings::PIPE_FORMAT_R11G11B10_FLOAT
213*61046927SAndroid Build Coastguard Worker         || p_format == nil_rs_bindings::PIPE_FORMAT_R9G9B9E5_FLOAT
214*61046927SAndroid Build Coastguard Worker     {
215*61046927SAndroid Build Coastguard Worker         return;
216*61046927SAndroid Build Coastguard Worker     }
217*61046927SAndroid Build Coastguard Worker 
218*61046927SAndroid Build Coastguard Worker     let compression_type = CompressionType::None;
219*61046927SAndroid Build Coastguard Worker     let sector_layout = SectorLayout::for_dev(dev);
220*61046927SAndroid Build Coastguard Worker     let gob_kind_version = GOBKindVersion::for_dev(dev);
221*61046927SAndroid Build Coastguard Worker     let pte_kind = Image::choose_pte_kind(dev, format, 1, false);
222*61046927SAndroid Build Coastguard Worker 
223*61046927SAndroid Build Coastguard Worker     // We assume bigger tiling is better
224*61046927SAndroid Build Coastguard Worker     for i in 0..6 {
225*61046927SAndroid Build Coastguard Worker         let height_log2 = 5 - i;
226*61046927SAndroid Build Coastguard Worker 
227*61046927SAndroid Build Coastguard Worker         let bl_mod = BlockLinearModifier::block_linear_2d(
228*61046927SAndroid Build Coastguard Worker             compression_type,
229*61046927SAndroid Build Coastguard Worker             sector_layout,
230*61046927SAndroid Build Coastguard Worker             gob_kind_version,
231*61046927SAndroid Build Coastguard Worker             pte_kind,
232*61046927SAndroid Build Coastguard Worker             height_log2,
233*61046927SAndroid Build Coastguard Worker         );
234*61046927SAndroid Build Coastguard Worker 
235*61046927SAndroid Build Coastguard Worker         assert!(*mod_count < max_mod_count);
236*61046927SAndroid Build Coastguard Worker         mods[*mod_count] = bl_mod.drm_modifier;
237*61046927SAndroid Build Coastguard Worker         *mod_count += 1;
238*61046927SAndroid Build Coastguard Worker     }
239*61046927SAndroid Build Coastguard Worker 
240*61046927SAndroid Build Coastguard Worker     assert!(*mod_count < max_mod_count);
241*61046927SAndroid Build Coastguard Worker     mods[*mod_count] = DRM_FORMAT_MOD_LINEAR;
242*61046927SAndroid Build Coastguard Worker     *mod_count += 1;
243*61046927SAndroid Build Coastguard Worker }
244*61046927SAndroid Build Coastguard Worker 
drm_format_mod_is_supported( dev: &nil_rs_bindings::nv_device_info, format: Format, modifier: u64, ) -> bool245*61046927SAndroid Build Coastguard Worker pub fn drm_format_mod_is_supported(
246*61046927SAndroid Build Coastguard Worker     dev: &nil_rs_bindings::nv_device_info,
247*61046927SAndroid Build Coastguard Worker     format: Format,
248*61046927SAndroid Build Coastguard Worker     modifier: u64,
249*61046927SAndroid Build Coastguard Worker ) -> bool {
250*61046927SAndroid Build Coastguard Worker     if modifier == DRM_FORMAT_MOD_LINEAR {
251*61046927SAndroid Build Coastguard Worker         return true;
252*61046927SAndroid Build Coastguard Worker     }
253*61046927SAndroid Build Coastguard Worker 
254*61046927SAndroid Build Coastguard Worker     let Ok(bl_mod) = BlockLinearModifier::try_from(modifier) else {
255*61046927SAndroid Build Coastguard Worker         return false;
256*61046927SAndroid Build Coastguard Worker     };
257*61046927SAndroid Build Coastguard Worker 
258*61046927SAndroid Build Coastguard Worker     if bl_mod.height_log2() > 5 {
259*61046927SAndroid Build Coastguard Worker         return false;
260*61046927SAndroid Build Coastguard Worker     }
261*61046927SAndroid Build Coastguard Worker 
262*61046927SAndroid Build Coastguard Worker     if bl_mod.gob_kind_version() != GOBKindVersion::for_dev(dev) {
263*61046927SAndroid Build Coastguard Worker         return false;
264*61046927SAndroid Build Coastguard Worker     }
265*61046927SAndroid Build Coastguard Worker 
266*61046927SAndroid Build Coastguard Worker     if bl_mod.sector_layout() != SectorLayout::for_dev(dev) {
267*61046927SAndroid Build Coastguard Worker         return false;
268*61046927SAndroid Build Coastguard Worker     }
269*61046927SAndroid Build Coastguard Worker 
270*61046927SAndroid Build Coastguard Worker     if bl_mod.compression_type() != CompressionType::None {
271*61046927SAndroid Build Coastguard Worker         return false;
272*61046927SAndroid Build Coastguard Worker     }
273*61046927SAndroid Build Coastguard Worker 
274*61046927SAndroid Build Coastguard Worker     let pte_kind = Image::choose_pte_kind(dev, format, 1, false);
275*61046927SAndroid Build Coastguard Worker     if bl_mod.pte_kind() != pte_kind {
276*61046927SAndroid Build Coastguard Worker         return false;
277*61046927SAndroid Build Coastguard Worker     }
278*61046927SAndroid Build Coastguard Worker 
279*61046927SAndroid Build Coastguard Worker     return true;
280*61046927SAndroid Build Coastguard Worker }
281*61046927SAndroid Build Coastguard Worker 
score_drm_format_mod(modifier: u64) -> u32282*61046927SAndroid Build Coastguard Worker fn score_drm_format_mod(modifier: u64) -> u32 {
283*61046927SAndroid Build Coastguard Worker     if modifier == DRM_FORMAT_MOD_LINEAR {
284*61046927SAndroid Build Coastguard Worker         return 1;
285*61046927SAndroid Build Coastguard Worker     }
286*61046927SAndroid Build Coastguard Worker 
287*61046927SAndroid Build Coastguard Worker     let bl_mod = BlockLinearModifier::try_from(modifier).unwrap();
288*61046927SAndroid Build Coastguard Worker 
289*61046927SAndroid Build Coastguard Worker     // Assume bigger Y-tiling is better
290*61046927SAndroid Build Coastguard Worker     let mut score = 10 + u32::from(bl_mod.height_log2());
291*61046927SAndroid Build Coastguard Worker 
292*61046927SAndroid Build Coastguard Worker     if bl_mod.compression_type() != CompressionType::None {
293*61046927SAndroid Build Coastguard Worker         score += 10;
294*61046927SAndroid Build Coastguard Worker     }
295*61046927SAndroid Build Coastguard Worker 
296*61046927SAndroid Build Coastguard Worker     score
297*61046927SAndroid Build Coastguard Worker }
298*61046927SAndroid Build Coastguard Worker 
select_best_drm_format_mod( dev: &nil_rs_bindings::nv_device_info, format: Format, modifiers: &[u64], ) -> u64299*61046927SAndroid Build Coastguard Worker pub fn select_best_drm_format_mod(
300*61046927SAndroid Build Coastguard Worker     dev: &nil_rs_bindings::nv_device_info,
301*61046927SAndroid Build Coastguard Worker     format: Format,
302*61046927SAndroid Build Coastguard Worker     modifiers: &[u64],
303*61046927SAndroid Build Coastguard Worker ) -> u64 {
304*61046927SAndroid Build Coastguard Worker     let mut best = DRM_FORMAT_MOD_INVALID;
305*61046927SAndroid Build Coastguard Worker     let mut best_score = 0;
306*61046927SAndroid Build Coastguard Worker 
307*61046927SAndroid Build Coastguard Worker     for &modifier in modifiers {
308*61046927SAndroid Build Coastguard Worker         if !drm_format_mod_is_supported(dev, format, modifier) {
309*61046927SAndroid Build Coastguard Worker             continue;
310*61046927SAndroid Build Coastguard Worker         }
311*61046927SAndroid Build Coastguard Worker 
312*61046927SAndroid Build Coastguard Worker         let score = score_drm_format_mod(modifier);
313*61046927SAndroid Build Coastguard Worker         if score > best_score {
314*61046927SAndroid Build Coastguard Worker             best = modifier;
315*61046927SAndroid Build Coastguard Worker             best_score = score;
316*61046927SAndroid Build Coastguard Worker         }
317*61046927SAndroid Build Coastguard Worker     }
318*61046927SAndroid Build Coastguard Worker 
319*61046927SAndroid Build Coastguard Worker     return best;
320*61046927SAndroid Build Coastguard Worker }
321*61046927SAndroid Build Coastguard Worker 
322*61046927SAndroid Build Coastguard Worker #[no_mangle]
nil_select_best_drm_format_mod( dev: &nil_rs_bindings::nv_device_info, format: Format, modifier_count: usize, modifiers: *const u64, ) -> u64323*61046927SAndroid Build Coastguard Worker pub extern "C" fn nil_select_best_drm_format_mod(
324*61046927SAndroid Build Coastguard Worker     dev: &nil_rs_bindings::nv_device_info,
325*61046927SAndroid Build Coastguard Worker     format: Format,
326*61046927SAndroid Build Coastguard Worker     modifier_count: usize,
327*61046927SAndroid Build Coastguard Worker     modifiers: *const u64,
328*61046927SAndroid Build Coastguard Worker ) -> u64 {
329*61046927SAndroid Build Coastguard Worker     let modifiers =
330*61046927SAndroid Build Coastguard Worker         unsafe { std::slice::from_raw_parts(modifiers, modifier_count) };
331*61046927SAndroid Build Coastguard Worker     select_best_drm_format_mod(dev, format, modifiers)
332*61046927SAndroid Build Coastguard Worker }
333