xref: /aosp_15_r20/external/crosvm/devices/src/virtio/gpu/parameters.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2022 The ChromiumOS Authors
2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file.
4*bb4ee6a4SAndroid Build Coastguard Worker 
5*bb4ee6a4SAndroid Build Coastguard Worker //! Definitions and utilities for GPU related parameters.
6*bb4ee6a4SAndroid Build Coastguard Worker 
7*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(windows)]
8*bb4ee6a4SAndroid Build Coastguard Worker use std::marker::PhantomData;
9*bb4ee6a4SAndroid Build Coastguard Worker 
10*bb4ee6a4SAndroid Build Coastguard Worker use serde::Deserialize;
11*bb4ee6a4SAndroid Build Coastguard Worker use serde::Deserializer;
12*bb4ee6a4SAndroid Build Coastguard Worker use serde::Serialize;
13*bb4ee6a4SAndroid Build Coastguard Worker use serde::Serializer;
14*bb4ee6a4SAndroid Build Coastguard Worker use serde_keyvalue::FromKeyValues;
15*bb4ee6a4SAndroid Build Coastguard Worker use vm_control::gpu::DisplayParameters;
16*bb4ee6a4SAndroid Build Coastguard Worker 
17*bb4ee6a4SAndroid Build Coastguard Worker use super::GpuMode;
18*bb4ee6a4SAndroid Build Coastguard Worker use super::GpuWsi;
19*bb4ee6a4SAndroid Build Coastguard Worker use crate::virtio::gpu::VIRTIO_GPU_MAX_SCANOUTS;
20*bb4ee6a4SAndroid Build Coastguard Worker use crate::PciAddress;
21*bb4ee6a4SAndroid Build Coastguard Worker 
22*bb4ee6a4SAndroid Build Coastguard Worker mod serde_capset_mask {
23*bb4ee6a4SAndroid Build Coastguard Worker     use super::*;
24*bb4ee6a4SAndroid Build Coastguard Worker 
serialize<S>(capset_mask: &u64, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,25*bb4ee6a4SAndroid Build Coastguard Worker     pub fn serialize<S>(capset_mask: &u64, serializer: S) -> Result<S::Ok, S::Error>
26*bb4ee6a4SAndroid Build Coastguard Worker     where
27*bb4ee6a4SAndroid Build Coastguard Worker         S: Serializer,
28*bb4ee6a4SAndroid Build Coastguard Worker     {
29*bb4ee6a4SAndroid Build Coastguard Worker         let context_types = rutabaga_gfx::calculate_capset_names(*capset_mask).join(":");
30*bb4ee6a4SAndroid Build Coastguard Worker 
31*bb4ee6a4SAndroid Build Coastguard Worker         serializer.serialize_str(context_types.as_str())
32*bb4ee6a4SAndroid Build Coastguard Worker     }
33*bb4ee6a4SAndroid Build Coastguard Worker 
deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result<u64, D::Error>34*bb4ee6a4SAndroid Build Coastguard Worker     pub fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result<u64, D::Error> {
35*bb4ee6a4SAndroid Build Coastguard Worker         let s = String::deserialize(deserializer)?;
36*bb4ee6a4SAndroid Build Coastguard Worker         Ok(rutabaga_gfx::calculate_capset_mask(s.split(':')))
37*bb4ee6a4SAndroid Build Coastguard Worker     }
38*bb4ee6a4SAndroid Build Coastguard Worker }
39*bb4ee6a4SAndroid Build Coastguard Worker 
40*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
41*bb4ee6a4SAndroid Build Coastguard Worker pub enum AudioDeviceMode {
42*bb4ee6a4SAndroid Build Coastguard Worker     #[serde(rename = "per-surface")]
43*bb4ee6a4SAndroid Build Coastguard Worker     PerSurface,
44*bb4ee6a4SAndroid Build Coastguard Worker     #[serde(rename = "one-global")]
45*bb4ee6a4SAndroid Build Coastguard Worker     OneGlobal,
46*bb4ee6a4SAndroid Build Coastguard Worker }
47*bb4ee6a4SAndroid Build Coastguard Worker 
48*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone, Debug, Serialize, Deserialize, FromKeyValues)]
49*bb4ee6a4SAndroid Build Coastguard Worker #[serde(deny_unknown_fields, default, rename_all = "kebab-case")]
50*bb4ee6a4SAndroid Build Coastguard Worker pub struct GpuParameters {
51*bb4ee6a4SAndroid Build Coastguard Worker     #[serde(rename = "backend")]
52*bb4ee6a4SAndroid Build Coastguard Worker     pub mode: GpuMode,
53*bb4ee6a4SAndroid Build Coastguard Worker     #[serde(default = "default_max_num_displays")]
54*bb4ee6a4SAndroid Build Coastguard Worker     pub max_num_displays: u32,
55*bb4ee6a4SAndroid Build Coastguard Worker     #[serde(default = "default_audio_device_mode")]
56*bb4ee6a4SAndroid Build Coastguard Worker     pub audio_device_mode: AudioDeviceMode,
57*bb4ee6a4SAndroid Build Coastguard Worker     #[serde(rename = "displays")]
58*bb4ee6a4SAndroid Build Coastguard Worker     pub display_params: Vec<DisplayParameters>,
59*bb4ee6a4SAndroid Build Coastguard Worker     // `width` and `height` are supported for CLI backwards compatibility.
60*bb4ee6a4SAndroid Build Coastguard Worker     #[serde(rename = "width")]
61*bb4ee6a4SAndroid Build Coastguard Worker     pub __width_compat: Option<u32>,
62*bb4ee6a4SAndroid Build Coastguard Worker     #[serde(rename = "height")]
63*bb4ee6a4SAndroid Build Coastguard Worker     pub __height_compat: Option<u32>,
64*bb4ee6a4SAndroid Build Coastguard Worker     #[serde(rename = "egl")]
65*bb4ee6a4SAndroid Build Coastguard Worker     pub renderer_use_egl: bool,
66*bb4ee6a4SAndroid Build Coastguard Worker     #[serde(rename = "gles")]
67*bb4ee6a4SAndroid Build Coastguard Worker     pub renderer_use_gles: bool,
68*bb4ee6a4SAndroid Build Coastguard Worker     #[serde(rename = "glx")]
69*bb4ee6a4SAndroid Build Coastguard Worker     pub renderer_use_glx: bool,
70*bb4ee6a4SAndroid Build Coastguard Worker     #[serde(rename = "surfaceless")]
71*bb4ee6a4SAndroid Build Coastguard Worker     pub renderer_use_surfaceless: bool,
72*bb4ee6a4SAndroid Build Coastguard Worker     #[serde(rename = "vulkan")]
73*bb4ee6a4SAndroid Build Coastguard Worker     pub use_vulkan: Option<bool>,
74*bb4ee6a4SAndroid Build Coastguard Worker     pub wsi: Option<GpuWsi>,
75*bb4ee6a4SAndroid Build Coastguard Worker     pub udmabuf: bool,
76*bb4ee6a4SAndroid Build Coastguard Worker     pub cache_path: Option<String>,
77*bb4ee6a4SAndroid Build Coastguard Worker     pub cache_size: Option<String>,
78*bb4ee6a4SAndroid Build Coastguard Worker     pub pci_address: Option<PciAddress>,
79*bb4ee6a4SAndroid Build Coastguard Worker     pub pci_bar_size: u64,
80*bb4ee6a4SAndroid Build Coastguard Worker     #[serde(rename = "context-types", with = "serde_capset_mask")]
81*bb4ee6a4SAndroid Build Coastguard Worker     pub capset_mask: u64,
82*bb4ee6a4SAndroid Build Coastguard Worker     // enforce that blob resources MUST be exportable as file descriptors
83*bb4ee6a4SAndroid Build Coastguard Worker     pub external_blob: bool,
84*bb4ee6a4SAndroid Build Coastguard Worker     pub system_blob: bool,
85*bb4ee6a4SAndroid Build Coastguard Worker     // enable use of descriptor mapping to fixed host VA within a prepared vMMU mapping (e.g. kvm
86*bb4ee6a4SAndroid Build Coastguard Worker     // user memslot)
87*bb4ee6a4SAndroid Build Coastguard Worker     pub fixed_blob_mapping: bool,
88*bb4ee6a4SAndroid Build Coastguard Worker     #[serde(rename = "implicit-render-server")]
89*bb4ee6a4SAndroid Build Coastguard Worker     pub allow_implicit_render_server_exec: bool,
90*bb4ee6a4SAndroid Build Coastguard Worker     // Passthrough parameters sent to the underlying renderer in a renderer-specific format.
91*bb4ee6a4SAndroid Build Coastguard Worker     pub renderer_features: Option<String>,
92*bb4ee6a4SAndroid Build Coastguard Worker }
93*bb4ee6a4SAndroid Build Coastguard Worker 
94*bb4ee6a4SAndroid Build Coastguard Worker impl Default for GpuParameters {
default() -> Self95*bb4ee6a4SAndroid Build Coastguard Worker     fn default() -> Self {
96*bb4ee6a4SAndroid Build Coastguard Worker         GpuParameters {
97*bb4ee6a4SAndroid Build Coastguard Worker             max_num_displays: default_max_num_displays(),
98*bb4ee6a4SAndroid Build Coastguard Worker             audio_device_mode: default_audio_device_mode(),
99*bb4ee6a4SAndroid Build Coastguard Worker             display_params: vec![],
100*bb4ee6a4SAndroid Build Coastguard Worker             __width_compat: None,
101*bb4ee6a4SAndroid Build Coastguard Worker             __height_compat: None,
102*bb4ee6a4SAndroid Build Coastguard Worker             renderer_use_egl: true,
103*bb4ee6a4SAndroid Build Coastguard Worker             renderer_use_gles: true,
104*bb4ee6a4SAndroid Build Coastguard Worker             renderer_use_glx: false,
105*bb4ee6a4SAndroid Build Coastguard Worker             renderer_use_surfaceless: true,
106*bb4ee6a4SAndroid Build Coastguard Worker             use_vulkan: None,
107*bb4ee6a4SAndroid Build Coastguard Worker             mode: Default::default(),
108*bb4ee6a4SAndroid Build Coastguard Worker             wsi: None,
109*bb4ee6a4SAndroid Build Coastguard Worker             cache_path: None,
110*bb4ee6a4SAndroid Build Coastguard Worker             cache_size: None,
111*bb4ee6a4SAndroid Build Coastguard Worker             pci_address: None,
112*bb4ee6a4SAndroid Build Coastguard Worker             pci_bar_size: (1 << 33),
113*bb4ee6a4SAndroid Build Coastguard Worker             udmabuf: false,
114*bb4ee6a4SAndroid Build Coastguard Worker             capset_mask: 0,
115*bb4ee6a4SAndroid Build Coastguard Worker             external_blob: false,
116*bb4ee6a4SAndroid Build Coastguard Worker             system_blob: false,
117*bb4ee6a4SAndroid Build Coastguard Worker             // TODO(b/324649619): not yet fully compatible with other platforms (windows)
118*bb4ee6a4SAndroid Build Coastguard Worker             // TODO(b/246334944): gfxstream may map vulkan opaque blobs directly (without vulkano),
119*bb4ee6a4SAndroid Build Coastguard Worker             // so set the default to disabled when built with the gfxstream feature.
120*bb4ee6a4SAndroid Build Coastguard Worker             fixed_blob_mapping: cfg!(target_os = "linux") && !cfg!(feature = "gfxstream"),
121*bb4ee6a4SAndroid Build Coastguard Worker             allow_implicit_render_server_exec: false,
122*bb4ee6a4SAndroid Build Coastguard Worker             renderer_features: None,
123*bb4ee6a4SAndroid Build Coastguard Worker         }
124*bb4ee6a4SAndroid Build Coastguard Worker     }
125*bb4ee6a4SAndroid Build Coastguard Worker }
126*bb4ee6a4SAndroid Build Coastguard Worker 
default_max_num_displays() -> u32127*bb4ee6a4SAndroid Build Coastguard Worker fn default_max_num_displays() -> u32 {
128*bb4ee6a4SAndroid Build Coastguard Worker     VIRTIO_GPU_MAX_SCANOUTS as u32
129*bb4ee6a4SAndroid Build Coastguard Worker }
130*bb4ee6a4SAndroid Build Coastguard Worker 
default_audio_device_mode() -> AudioDeviceMode131*bb4ee6a4SAndroid Build Coastguard Worker fn default_audio_device_mode() -> AudioDeviceMode {
132*bb4ee6a4SAndroid Build Coastguard Worker     AudioDeviceMode::PerSurface
133*bb4ee6a4SAndroid Build Coastguard Worker }
134*bb4ee6a4SAndroid Build Coastguard Worker 
135*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(test)]
136*bb4ee6a4SAndroid Build Coastguard Worker mod tests {
137*bb4ee6a4SAndroid Build Coastguard Worker     use serde_json::*;
138*bb4ee6a4SAndroid Build Coastguard Worker 
139*bb4ee6a4SAndroid Build Coastguard Worker     use super::*;
140*bb4ee6a4SAndroid Build Coastguard Worker 
141*bb4ee6a4SAndroid Build Coastguard Worker     #[test]
capset_mask_serialize_deserialize()142*bb4ee6a4SAndroid Build Coastguard Worker     fn capset_mask_serialize_deserialize() {
143*bb4ee6a4SAndroid Build Coastguard Worker         #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
144*bb4ee6a4SAndroid Build Coastguard Worker         struct CapsetMask {
145*bb4ee6a4SAndroid Build Coastguard Worker             #[serde(rename = "context-types", with = "serde_capset_mask")]
146*bb4ee6a4SAndroid Build Coastguard Worker             pub value: u64,
147*bb4ee6a4SAndroid Build Coastguard Worker         }
148*bb4ee6a4SAndroid Build Coastguard Worker 
149*bb4ee6a4SAndroid Build Coastguard Worker         // Capset "virgl", id: 1, capset_mask: 0b0010
150*bb4ee6a4SAndroid Build Coastguard Worker         // Capset "gfxstream", id: 3, capset_mask: 0b1000
151*bb4ee6a4SAndroid Build Coastguard Worker         const CAPSET_MASK: u64 = 0b1010;
152*bb4ee6a4SAndroid Build Coastguard Worker         const SERIALIZED_CAPSET_MASK: &str = "{\"context-types\":\"virgl:gfxstream-vulkan\"}";
153*bb4ee6a4SAndroid Build Coastguard Worker 
154*bb4ee6a4SAndroid Build Coastguard Worker         let capset_mask = CapsetMask { value: CAPSET_MASK };
155*bb4ee6a4SAndroid Build Coastguard Worker 
156*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(to_string(&capset_mask).unwrap(), SERIALIZED_CAPSET_MASK);
157*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(
158*bb4ee6a4SAndroid Build Coastguard Worker             from_str::<CapsetMask>(SERIALIZED_CAPSET_MASK).unwrap(),
159*bb4ee6a4SAndroid Build Coastguard Worker             capset_mask
160*bb4ee6a4SAndroid Build Coastguard Worker         );
161*bb4ee6a4SAndroid Build Coastguard Worker     }
162*bb4ee6a4SAndroid Build Coastguard Worker }
163