devices/virtio/
resource_bridge.rs1use std::fmt;
9
10use base::with_as_descriptor;
11use base::SafeDescriptor;
12use base::Tube;
13use base::TubeError;
14use remain::sorted;
15use serde::Deserialize;
16use serde::Serialize;
17use thiserror::Error;
18
19#[derive(Debug, Serialize, Deserialize)]
20pub enum ResourceRequest {
21 GetBuffer { id: u32 },
22 GetFence { seqno: u64 },
23}
24
25#[derive(Serialize, Deserialize, Clone, Copy, Default)]
26pub struct PlaneInfo {
27 pub offset: u32,
28 pub stride: u32,
29}
30
31#[derive(Serialize, Deserialize)]
32pub struct BufferInfo {
33 #[serde(with = "with_as_descriptor")]
34 pub handle: SafeDescriptor,
35 pub planes: [PlaneInfo; RESOURE_PLANE_NUM],
36 pub modifier: u64,
37 pub guest_cpu_mappable: bool,
39}
40
41pub const RESOURE_PLANE_NUM: usize = 4;
42#[derive(Serialize, Deserialize)]
43pub enum ResourceInfo {
44 Buffer(BufferInfo),
45 Fence {
46 #[serde(with = "with_as_descriptor")]
47 handle: SafeDescriptor,
48 },
49}
50
51#[derive(Serialize, Deserialize)]
52pub enum ResourceResponse {
53 Resource(ResourceInfo),
54 Invalid,
55}
56
57#[sorted]
58#[derive(Error, Debug)]
59pub enum ResourceBridgeError {
60 #[error("attempt to send non-existent gpu resource for {0}")]
61 InvalidResource(ResourceRequest),
62 #[error("error receiving resource bridge response for {0}: {1}")]
63 RecieveFailure(ResourceRequest, TubeError),
64 #[error("failed to send a resource bridge request for {0}: {1}")]
65 SendFailure(ResourceRequest, TubeError),
66}
67
68impl fmt::Display for ResourceRequest {
69 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
70 match self {
71 ResourceRequest::GetBuffer { id } => write!(f, "Buffer-{id}"),
72 ResourceRequest::GetFence { seqno } => write!(f, "Fence-{seqno}"),
73 }
74 }
75}
76
77pub fn get_resource_info(
78 tube: &Tube,
79 request: ResourceRequest,
80) -> std::result::Result<ResourceInfo, ResourceBridgeError> {
81 if let Err(e) = tube.send(&request) {
82 return Err(ResourceBridgeError::SendFailure(request, e));
83 }
84
85 match tube.recv() {
86 Ok(ResourceResponse::Resource(info)) => Ok(info),
87 Ok(ResourceResponse::Invalid) => Err(ResourceBridgeError::InvalidResource(request)),
88 Err(e) => Err(ResourceBridgeError::RecieveFailure(request, e)),
89 }
90}