mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2024-11-25 05:03:05 +00:00
devices: gpu: virgl_renderer_resource_export_blob
With blob resources, there's a new export API. BUG=chromium:924405 TEST=local testing with blobs Change-Id: I4a6a48608fd6910b6deea53ef54f94def1799950 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2349395 Reviewed-by: Zach Reizner <zachr@chromium.org> Tested-by: Gurchetan Singh <gurchetansingh@chromium.org> Commit-Queue: Gurchetan Singh <gurchetansingh@chromium.org>
This commit is contained in:
parent
ca3817bda3
commit
fb72b4708b
3 changed files with 87 additions and 28 deletions
|
@ -13,8 +13,6 @@ use std::rc::Rc;
|
|||
use std::sync::Arc;
|
||||
use std::usize;
|
||||
|
||||
use libc::EINVAL;
|
||||
|
||||
use base::{error, warn, Error, ExternalMapping};
|
||||
use data_model::*;
|
||||
use msg_socket::{MsgReceiver, MsgSender};
|
||||
|
@ -24,8 +22,8 @@ use vm_memory::{GuestAddress, GuestMemory};
|
|||
|
||||
use gpu_display::*;
|
||||
use gpu_renderer::{
|
||||
Box3, Context as RendererContext, Error as GpuRendererError, Renderer, RendererFlags,
|
||||
Resource as GpuRendererResource, ResourceCreateArgs,
|
||||
Box3, Context as RendererContext, Renderer, RendererFlags, Resource as GpuRendererResource,
|
||||
ResourceCreateArgs,
|
||||
};
|
||||
|
||||
use super::protocol::{
|
||||
|
@ -110,14 +108,8 @@ impl VirtioResource for Virtio3DResource {
|
|||
}
|
||||
}
|
||||
|
||||
let (query, dmabuf) = match self.gpu_resource.export() {
|
||||
Ok(export) => (export.0, export.1),
|
||||
Err(GpuRendererError::Virglrenderer(e)) if e == -EINVAL => return None,
|
||||
Err(e) => {
|
||||
error!("failed to query resource: {}", e);
|
||||
return None;
|
||||
}
|
||||
};
|
||||
let dmabuf = self.gpu_resource.export().ok()?;
|
||||
let query = self.gpu_resource.query().ok()?;
|
||||
|
||||
let (width, height, format, stride, offset) = match self.scanout_data {
|
||||
Some(data) => (
|
||||
|
@ -349,18 +341,42 @@ impl Backend for Virtio3DBackend {
|
|||
|
||||
/// If supported, export the resource with the given id to a file.
|
||||
fn export_resource(&mut self, id: u32) -> ResourceResponse {
|
||||
self
|
||||
.resources
|
||||
.get(&id) // Option<resource>
|
||||
.and_then(|resource| resource.gpu_resource.export().ok()) // Option<(Query, File)>
|
||||
.map(|(q, file)| {
|
||||
ResourceResponse::Resource(ResourceInfo{file, planes: [
|
||||
PlaneInfo{offset: q.out_offsets[0], stride: q.out_strides[0]},
|
||||
PlaneInfo{offset: q.out_offsets[1], stride: q.out_strides[1]},
|
||||
PlaneInfo{offset: q.out_offsets[2], stride: q.out_strides[2]},
|
||||
PlaneInfo{offset: q.out_offsets[3], stride: q.out_strides[3]},
|
||||
]})
|
||||
}).unwrap_or(ResourceResponse::Invalid)
|
||||
let resource = match self.resources.get_mut(&id) {
|
||||
Some(r) => r,
|
||||
None => return ResourceResponse::Invalid,
|
||||
};
|
||||
|
||||
let q = match resource.gpu_resource.query() {
|
||||
Ok(query) => query,
|
||||
Err(_) => return ResourceResponse::Invalid,
|
||||
};
|
||||
|
||||
let file = match resource.gpu_resource.export() {
|
||||
Ok(file) => file,
|
||||
Err(_) => return ResourceResponse::Invalid,
|
||||
};
|
||||
|
||||
ResourceResponse::Resource(ResourceInfo {
|
||||
file,
|
||||
planes: [
|
||||
PlaneInfo {
|
||||
offset: q.out_offsets[0],
|
||||
stride: q.out_strides[0],
|
||||
},
|
||||
PlaneInfo {
|
||||
offset: q.out_offsets[1],
|
||||
stride: q.out_strides[1],
|
||||
},
|
||||
PlaneInfo {
|
||||
offset: q.out_offsets[2],
|
||||
stride: q.out_strides[2],
|
||||
},
|
||||
PlaneInfo {
|
||||
offset: q.out_offsets[3],
|
||||
stride: q.out_strides[3],
|
||||
},
|
||||
],
|
||||
})
|
||||
}
|
||||
|
||||
/// Creates a fence with the given id that can be used to determine when the previous command
|
||||
|
@ -879,7 +895,7 @@ impl Backend for Virtio3DBackend {
|
|||
let request = match export {
|
||||
Ok(ref export) => VmMemoryRequest::RegisterFdAtPciBarOffset(
|
||||
self.pci_bar,
|
||||
MaybeOwnedFd::Borrowed(export.1.as_raw_fd()),
|
||||
MaybeOwnedFd::Borrowed(export.as_raw_fd()),
|
||||
resource.size as usize,
|
||||
offset,
|
||||
),
|
||||
|
|
|
@ -21,6 +21,8 @@ pub const VIRGL_RES_BIND_CURSOR: u32 = 65536;
|
|||
pub const VIRGL_RES_BIND_CUSTOM: u32 = 131072;
|
||||
pub const VIRGL_RES_BIND_SCANOUT: u32 = 262144;
|
||||
pub const VIRGL_RES_BIND_SHARED: u32 = 1048576;
|
||||
pub const VIRGL_RENDERER_BLOB_FD_TYPE_DMABUF: u32 = 1;
|
||||
pub const VIRGL_RENDERER_BLOB_FD_TYPE_OPAQUE: u32 = 2;
|
||||
pub type __int32_t = ::std::os::raw::c_int;
|
||||
pub type __uint32_t = ::std::os::raw::c_uint;
|
||||
pub type __uint64_t = ::std::os::raw::c_ulong;
|
||||
|
@ -341,6 +343,13 @@ extern "C" {
|
|||
map_info: *mut u32,
|
||||
) -> ::std::os::raw::c_int;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn virgl_renderer_resource_export_blob(
|
||||
res_id: u32,
|
||||
fd_type: *mut u32,
|
||||
fd: *mut ::std::os::raw::c_int,
|
||||
) -> ::std::os::raw::c_int;
|
||||
}
|
||||
pub type __builtin_va_list = [__va_list_tag; 1usize];
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
|
|
|
@ -338,6 +338,7 @@ impl Renderer {
|
|||
ret_to_res(ret)?;
|
||||
Ok(Resource {
|
||||
id: args.handle,
|
||||
blob: false,
|
||||
backing_iovecs: Vec::new(),
|
||||
backing_mem: None,
|
||||
})
|
||||
|
@ -463,6 +464,7 @@ impl Renderer {
|
|||
|
||||
Ok(Resource {
|
||||
id: resource_id,
|
||||
blob: true,
|
||||
backing_iovecs: iovecs,
|
||||
backing_mem: None,
|
||||
})
|
||||
|
@ -585,6 +587,7 @@ fn unmap_func(resource_id: u32) {
|
|||
/// A resource handle used by the renderer.
|
||||
pub struct Resource {
|
||||
id: u32,
|
||||
blob: bool,
|
||||
backing_iovecs: Vec<VirglVec>,
|
||||
backing_mem: Option<GuestMemory>,
|
||||
}
|
||||
|
@ -618,8 +621,39 @@ impl Resource {
|
|||
self.export_query(false)
|
||||
}
|
||||
|
||||
/// Returns resource metadata and exports the associated dma-buf.
|
||||
pub fn export(&self) -> Result<(Query, File)> {
|
||||
/// Exports the associated dma-buf for a blob resource.
|
||||
fn export_blob(&self) -> Result<File> {
|
||||
#[cfg(feature = "virtio-gpu-next")]
|
||||
{
|
||||
let mut fd_type = 0;
|
||||
let mut fd = 0;
|
||||
let ret = unsafe {
|
||||
virgl_renderer_resource_export_blob(self.id as u32, &mut fd_type, &mut fd)
|
||||
};
|
||||
ret_to_res(ret)?;
|
||||
|
||||
/* Only support dma-bufs until someone wants opaque fds too. */
|
||||
if fd_type != VIRGL_RENDERER_BLOB_FD_TYPE_DMABUF {
|
||||
// Safe because the FD was just returned by a successful virglrenderer
|
||||
// call so it must be valid and owned by us.
|
||||
unsafe { close(fd) };
|
||||
return Err(Error::Unsupported);
|
||||
}
|
||||
|
||||
let dmabuf = unsafe { File::from_raw_fd(fd) };
|
||||
Ok(dmabuf)
|
||||
}
|
||||
#[cfg(not(feature = "virtio-gpu-next"))]
|
||||
Err(Error::Unsupported)
|
||||
}
|
||||
|
||||
/// Exports the associated dma-buf for a blob resource and traditional virtio-gpu resource
|
||||
/// backed by a dma-buf.
|
||||
pub fn export(&self) -> Result<File> {
|
||||
if self.blob {
|
||||
return self.export_blob();
|
||||
}
|
||||
|
||||
let query = self.export_query(true)?;
|
||||
if query.out_num_fds != 1 || query.out_fds[0] < 0 {
|
||||
for fd in &query.out_fds {
|
||||
|
@ -635,7 +669,7 @@ impl Resource {
|
|||
// Safe because the FD was just returned by a successful virglrenderer call so it must
|
||||
// be valid and owned by us.
|
||||
let dmabuf = unsafe { File::from_raw_fd(query.out_fds[0]) };
|
||||
Ok((query, dmabuf))
|
||||
Ok(dmabuf)
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
|
|
Loading…
Reference in a new issue