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