summary refs log tree commit diff
path: root/devices/src/virtio/gpu/backend.rs
diff options
context:
space:
mode:
Diffstat (limited to 'devices/src/virtio/gpu/backend.rs')
-rw-r--r--devices/src/virtio/gpu/backend.rs195
1 files changed, 55 insertions, 140 deletions
diff --git a/devices/src/virtio/gpu/backend.rs b/devices/src/virtio/gpu/backend.rs
index 8dd7806..99e3449 100644
--- a/devices/src/virtio/gpu/backend.rs
+++ b/devices/src/virtio/gpu/backend.rs
@@ -14,14 +14,13 @@ use std::usize;
 use data_model::*;
 
 use msg_socket::{MsgReceiver, MsgSender};
-use sys_util::{error, warn, GuestAddress, GuestMemory};
+use sys_util::{error, GuestAddress, GuestMemory};
 
 use gpu_buffer::{Buffer, Device, Flags, Format};
 use gpu_display::*;
 use gpu_renderer::{
     format_fourcc as renderer_fourcc, Box3, Context as RendererContext, Image as RendererImage,
-    Renderer, Resource as GpuRendererResource, ResourceCreateArgs, VIRGL_RES_BIND_SCANOUT,
-    VIRGL_RES_BIND_SHARED,
+    Renderer, Resource as GpuRendererResource, ResourceCreateArgs,
 };
 
 use super::protocol::{
@@ -54,7 +53,13 @@ trait VirglResource {
     }
 
     /// Returns the renderer's concrete `GpuRendererResource` for this resource, if it has one.
-    fn gpu_renderer_resource(&mut self) -> Option<&mut GpuRendererResource> {
+    fn gpu_renderer_resource_mut(&mut self) -> Option<&mut GpuRendererResource> {
+        None
+    }
+
+    /// Returns the renderer's concrete non-mutable `GpuRendererResource` for this resource, if
+    /// it has one.
+    fn gpu_renderer_resource(&self) -> Option<&GpuRendererResource> {
         None
     }
 
@@ -111,7 +116,11 @@ impl VirglResource for GpuRendererResource {
         self.detach_backing();
     }
 
-    fn gpu_renderer_resource(&mut self) -> Option<&mut GpuRendererResource> {
+    fn gpu_renderer_resource_mut(&mut self) -> Option<&mut GpuRendererResource> {
+        Some(self)
+    }
+
+    fn gpu_renderer_resource(&self) -> Option<&GpuRendererResource> {
         Some(self)
     }
 
@@ -167,22 +176,6 @@ struct BackedBuffer {
     _image: Option<RendererImage>,
 }
 
-impl BackedBuffer {
-    fn new_renderer_registered(
-        buffer: Buffer,
-        gpu_renderer_resource: GpuRendererResource,
-        image: RendererImage,
-    ) -> BackedBuffer {
-        BackedBuffer {
-            display_import: None,
-            backing: Vec::new(),
-            buffer,
-            gpu_renderer_resource: Some(gpu_renderer_resource),
-            _image: Some(image),
-        }
-    }
-}
-
 impl From<Buffer> for BackedBuffer {
     fn from(buffer: Buffer) -> BackedBuffer {
         BackedBuffer {
@@ -220,10 +213,14 @@ impl VirglResource for BackedBuffer {
         self.backing.clear();
     }
 
-    fn gpu_renderer_resource(&mut self) -> Option<&mut GpuRendererResource> {
+    fn gpu_renderer_resource_mut(&mut self) -> Option<&mut GpuRendererResource> {
         self.gpu_renderer_resource.as_mut()
     }
 
+    fn gpu_renderer_resource(&self) -> Option<&GpuRendererResource> {
+        self.gpu_renderer_resource.as_ref()
+    }
+
     fn buffer(&self) -> Option<&Buffer> {
         Some(&self.buffer)
     }
@@ -385,8 +382,9 @@ impl Backend {
             ResourceRequest::GetResource { id } => self
                 .resources
                 .get(&id)
-                .and_then(|resource| resource.buffer())
-                .and_then(|buffer| buffer.export_plane_fd(0).ok())
+                .and_then(|resource| resource.gpu_renderer_resource())
+                .and_then(|gpu_renderer_resource| gpu_renderer_resource.export().ok())
+                .and_then(|export| Some(export.1))
                 .map(ResourceResponse::Resource)
                 .unwrap_or(ResourceResponse::Invalid),
         };
@@ -747,7 +745,7 @@ impl Backend {
             self.contexts.get_mut(&ctx_id),
             self.resources
                 .get_mut(&res_id)
-                .and_then(|res| res.gpu_renderer_resource()),
+                .and_then(|res| res.gpu_renderer_resource_mut()),
         ) {
             (Some(ctx), Some(res)) => {
                 ctx.attach(res);
@@ -764,7 +762,7 @@ impl Backend {
             self.contexts.get_mut(&ctx_id),
             self.resources
                 .get_mut(&res_id)
-                .and_then(|res| res.gpu_renderer_resource()),
+                .and_then(|res| res.gpu_renderer_resource_mut()),
         ) {
             (Some(ctx), Some(res)) => {
                 ctx.detach(res);
@@ -775,14 +773,6 @@ impl Backend {
         }
     }
 
-    pub fn allocate_using_minigbm(args: ResourceCreateArgs) -> bool {
-        args.bind & (VIRGL_RES_BIND_SCANOUT | VIRGL_RES_BIND_SHARED) != 0
-            && args.depth == 1
-            && args.array_size == 1
-            && args.last_level == 0
-            && args.nr_samples == 0
-    }
-
     /// Creates a 3D resource with the given properties and associated it with the given id.
     pub fn resource_create_3d(
         &mut self,
@@ -819,120 +809,45 @@ impl Backend {
         match self.resources.entry(id) {
             Entry::Occupied(_) => GpuResponse::ErrInvalidResourceId,
             Entry::Vacant(slot) => {
-                if self.device.is_some() && Backend::allocate_using_minigbm(create_args) {
-                    let device = self.device.as_ref().unwrap();
-                    match renderer_fourcc(create_args.format) {
-                        Some(fourcc) => {
-                            let buffer = match device.create_buffer(
-                                width,
-                                height,
-                                Format::from(fourcc),
-                                Flags::empty().use_scanout(true).use_rendering(true),
-                            ) {
-                                Ok(buffer) => buffer,
-                                Err(_) => {
-                                    // Attempt to allocate the buffer without scanout flag.
-                                    match device.create_buffer(
-                                        width,
-                                        height,
-                                        Format::from(fourcc),
-                                        Flags::empty().use_rendering(true),
-                                    ) {
-                                        Ok(buffer) => buffer,
-                                        Err(e) => {
-                                            error!(
-                                                "failed to create buffer for 3d resource {}: {}",
-                                                format, e
-                                            );
-                                            return GpuResponse::ErrUnspec;
-                                        }
-                                    }
+                let res = self.renderer.create_resource(create_args);
+                match res {
+                    Ok(res) => {
+                        let query = match res.query() {
+                            Ok(query) => query,
+                            Err(_) => return GpuResponse::ErrUnspec,
+                        };
+
+                        let response = match query.out_num_fds {
+                            0 => GpuResponse::OkNoData,
+                            1 => {
+                                let mut plane_info = Vec::with_capacity(4);
+                                for plane_index in 0..4 {
+                                    plane_info.push(GpuResponsePlaneInfo {
+                                        stride: query.out_strides[plane_index],
+                                        offset: query.out_offsets[plane_index],
+                                    });
                                 }
-                            };
 
-                            let dma_buf_fd = match buffer.export_plane_fd(0) {
-                                Ok(dma_buf_fd) => dma_buf_fd,
-                                Err(e) => {
-                                    error!("failed to export plane fd: {}", e);
-                                    return GpuResponse::ErrUnspec;
-                                }
-                            };
-
-                            let image = match self.renderer.image_from_dmabuf(
-                                fourcc,
-                                width,
-                                height,
-                                dma_buf_fd.as_raw_fd(),
-                                buffer.plane_offset(0),
-                                buffer.plane_stride(0),
-                            ) {
-                                Ok(image) => image,
-                                Err(e) => {
-                                    error!("failed to create egl image: {}", e);
-                                    return GpuResponse::ErrUnspec;
-                                }
-                            };
-
-                            let res = self.renderer.import_resource(create_args, &image);
-                            match res {
-                                Ok(res) => {
-                                    let format_modifier = buffer.format_modifier();
-                                    let mut plane_info = Vec::with_capacity(buffer.num_planes());
-                                    for plane_index in 0..buffer.num_planes() {
-                                        plane_info.push(GpuResponsePlaneInfo {
-                                            stride: buffer.plane_stride(plane_index),
-                                            offset: buffer.plane_offset(plane_index),
-                                        });
-                                    }
-                                    let backed =
-                                        BackedBuffer::new_renderer_registered(buffer, res, image);
-                                    slot.insert(Box::new(backed));
-                                    GpuResponse::OkResourcePlaneInfo {
-                                        format_modifier,
-                                        plane_info,
-                                    }
-                                }
-                                Err(e) => {
-                                    error!("failed to import renderer resource: {}", e);
-                                    GpuResponse::ErrUnspec
-                                }
-                            }
-                        }
-                        None => {
-                            warn!(
-                                "failed to get fourcc for minigbm 3d resource {}, falling back",
-                                format
-                            );
-                            let res = self.renderer.create_resource(create_args);
-                            match res {
-                                Ok(res) => {
-                                    slot.insert(Box::new(res));
-                                    GpuResponse::OkNoData
-                                }
-                                Err(e) => {
-                                    error!("failed to create renderer resource: {}", e);
-                                    GpuResponse::ErrUnspec
+                                let format_modifier = query.out_modifier;
+                                GpuResponse::OkResourcePlaneInfo {
+                                    format_modifier,
+                                    plane_info,
                                 }
                             }
-                        }
+                            _ => return GpuResponse::ErrUnspec,
+                        };
+
+                        slot.insert(Box::new(res));
+                        response
                     }
-                } else {
-                    let res = self.renderer.create_resource(create_args);
-                    match res {
-                        Ok(res) => {
-                            slot.insert(Box::new(res));
-                            GpuResponse::OkNoData
-                        }
-                        Err(e) => {
-                            error!("failed to create renderer resource: {}", e);
-                            GpuResponse::ErrUnspec
-                        }
+                    Err(e) => {
+                        error!("failed to create renderer resource: {}", e);
+                        GpuResponse::ErrUnspec
                     }
                 }
             }
         }
     }
-
     /// Copes the given 3D rectangle of pixels of the given resource's backing memory to the host
     /// side resource.
     pub fn transfer_to_resource_3d(
@@ -958,7 +873,7 @@ impl Backend {
             },
         };
         match self.resources.get_mut(&res_id) {
-            Some(res) => match res.gpu_renderer_resource() {
+            Some(res) => match res.gpu_renderer_resource_mut() {
                 Some(res) => {
                     let transfer_box = Box3 {
                         x,
@@ -1009,7 +924,7 @@ impl Backend {
             },
         };
         match self.resources.get_mut(&res_id) {
-            Some(res) => match res.gpu_renderer_resource() {
+            Some(res) => match res.gpu_renderer_resource_mut() {
                 Some(res) => {
                     let transfer_box = Box3 {
                         x,