diff options
author | David Riley <davidriley@chromium.org> | 2018-05-22 15:37:22 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-07-30 23:08:03 -0700 |
commit | af9d7edfb743e7f23f03f6500b382aef678dc7fb (patch) | |
tree | 2c817f5fa99de3bec6fc27c79f67196918734de5 /devices/src/virtio/gpu | |
parent | 150daf94c261747c020cd41ce7f7146f656b77a1 (diff) | |
download | crosvm-af9d7edfb743e7f23f03f6500b382aef678dc7fb.tar crosvm-af9d7edfb743e7f23f03f6500b382aef678dc7fb.tar.gz crosvm-af9d7edfb743e7f23f03f6500b382aef678dc7fb.tar.bz2 crosvm-af9d7edfb743e7f23f03f6500b382aef678dc7fb.tar.lz crosvm-af9d7edfb743e7f23f03f6500b382aef678dc7fb.tar.xz crosvm-af9d7edfb743e7f23f03f6500b382aef678dc7fb.tar.zst crosvm-af9d7edfb743e7f23f03f6500b382aef678dc7fb.zip |
gpu: import buffers for rendering from minigbm
BUG=None TEST=build with --features=gpu; null_platform_test (has tearing) Change-Id: Ic53ac703971bfdafcff2a4df55ddc4cf382144f1 Reviewed-on: https://chromium-review.googlesource.com/1050989 Commit-Ready: David Riley <davidriley@chromium.org> Tested-by: David Riley <davidriley@chromium.org> Reviewed-by: Zach Reizner <zachr@chromium.org>
Diffstat (limited to 'devices/src/virtio/gpu')
-rw-r--r-- | devices/src/virtio/gpu/backend.rs | 135 |
1 files changed, 112 insertions, 23 deletions
diff --git a/devices/src/virtio/gpu/backend.rs b/devices/src/virtio/gpu/backend.rs index 8aadc73..561ce74 100644 --- a/devices/src/virtio/gpu/backend.rs +++ b/devices/src/virtio/gpu/backend.rs @@ -18,7 +18,8 @@ use sys_util::{GuestAddress, GuestMemory}; use super::gpu_buffer::{Device, Buffer, Format, Flags}; use super::gpu_display::*; use super::gpu_renderer::{Box3, Renderer, Context as RendererContext, - Resource as GpuRendererResource, ResourceCreateArgs}; + Resource as GpuRendererResource, ResourceCreateArgs, + format_fourcc as renderer_fourcc}; use super::protocol::GpuResponse; @@ -154,6 +155,19 @@ struct BackedBuffer { display_import: Option<(Rc<RefCell<GpuDisplay>>, u32)>, backing: Vec<(GuestAddress, usize)>, buffer: Buffer, + gpu_renderer_resource: Option<GpuRendererResource>, +} + +impl BackedBuffer { + fn new_renderer_registered(buffer: Buffer, + gpu_renderer_resource: GpuRendererResource) -> BackedBuffer { + BackedBuffer { + display_import: None, + backing: Vec::new(), + buffer, + gpu_renderer_resource: Some(gpu_renderer_resource), + } + } } impl From<Buffer> for BackedBuffer { @@ -162,6 +176,7 @@ impl From<Buffer> for BackedBuffer { display_import: None, backing: Vec::new(), buffer, + gpu_renderer_resource: None, } } } @@ -183,6 +198,10 @@ impl VirglResource for BackedBuffer { self.backing.clear() } + fn gpu_renderer_resource(&mut self) -> Option<&mut GpuRendererResource> { + self.gpu_renderer_resource.as_mut() + } + fn buffer(&self) -> Option<&Buffer> { Some(&self.buffer) } @@ -646,6 +665,17 @@ impl Backend { } } + pub fn validate_args_as_fourcc(args: ResourceCreateArgs) -> Option<u32> { + if args.depth == 1 && + args.array_size == 1 && + args.last_level == 0 && + args.nr_samples == 0 { + renderer_fourcc(args.format) + } else { + None + } + } + /// Creates a 3D resource with the given properties and associated it with the given id. pub fn resource_create_3d(&mut self, id: u32, @@ -663,31 +693,90 @@ impl Backend { if id == 0 { return GpuResponse::ErrInvalidResourceId; } + + let create_args = ResourceCreateArgs { + handle: id, + target, + format, + bind, + width, + height, + depth, + array_size, + last_level, + nr_samples, + flags, + }; + match self.resources.entry(id) { Entry::Occupied(_) => GpuResponse::ErrInvalidResourceId, Entry::Vacant(slot) => { - let res = self.renderer - .create_resource(ResourceCreateArgs { - handle: id, - target, - format, - bind, - width, - height, - depth, - array_size, - last_level, - nr_samples, - flags, - }); - match res { - Ok(res) => { - slot.insert(Box::new(res)); - GpuResponse::OkNoData - } - Err(e) => { - error!("failed to create renderer resource: {}", e); - GpuResponse::ErrUnspec + match Backend::validate_args_as_fourcc(create_args) { + Some(fourcc) => { + let buffer = match self.device + .create_buffer(width, + height, + Format::from(fourcc), + Flags::empty().use_scanout(true).use_linear(true)) { + Ok(buffer) => buffer, + Err(e) => { + error!("failed to create buffer for 3d resource {}: {}", format, e); + return GpuResponse::ErrUnspec; + } + }; + + 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 mut backed = + BackedBuffer::new_renderer_registered(buffer, + res); + slot.insert(Box::new(backed)); + GpuResponse::OkNoData + } + Err(e) => { + error!("failed to import renderer resource: {}", + e); + GpuResponse::ErrUnspec + } + } + }, + None => { + 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 + } + } } } } |