summary refs log tree commit diff
path: root/gpu_renderer
diff options
context:
space:
mode:
authorDavid Riley <davidriley@chromium.org>2018-05-22 15:37:22 -0700
committerchrome-bot <chrome-bot@chromium.org>2018-07-30 23:08:03 -0700
commitaf9d7edfb743e7f23f03f6500b382aef678dc7fb (patch)
tree2c817f5fa99de3bec6fc27c79f67196918734de5 /gpu_renderer
parent150daf94c261747c020cd41ce7f7146f656b77a1 (diff)
downloadcrosvm-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 'gpu_renderer')
-rw-r--r--gpu_renderer/src/lib.rs81
1 files changed, 79 insertions, 2 deletions
diff --git a/gpu_renderer/src/lib.rs b/gpu_renderer/src/lib.rs
index dfb8bf9..7a8c7fa 100644
--- a/gpu_renderer/src/lib.rs
+++ b/gpu_renderer/src/lib.rs
@@ -19,7 +19,7 @@ use std::marker::PhantomData;
 use std::mem::{size_of, transmute, uninitialized};
 use std::ops::Deref;
 use std::os::raw::{c_void, c_int, c_uint, c_char};
-use std::os::unix::io::FromRawFd;
+use std::os::unix::io::{FromRawFd, RawFd};
 use std::ptr::{null, null_mut};
 use std::rc::Rc;
 use std::result;
@@ -32,7 +32,10 @@ use generated::virglrenderer::*;
 pub use generated::virglrenderer::{virgl_renderer_resource_create_args,
                                    virgl_renderer_resource_info};
 use generated::epoxy_egl::{EGL_CONTEXT_CLIENT_VERSION, EGL_SURFACE_TYPE, EGL_OPENGL_ES_API,
-                           EGL_NONE, EGL_GL_TEXTURE_2D_KHR, EGLDEBUGPROCKHR, EGLAttrib,
+                           EGL_NONE, EGL_GL_TEXTURE_2D_KHR, EGL_WIDTH, EGL_HEIGHT,
+                           EGL_LINUX_DRM_FOURCC_EXT, EGL_DMA_BUF_PLANE0_FD_EXT,
+                           EGL_DMA_BUF_PLANE0_OFFSET_EXT, EGL_DMA_BUF_PLANE0_PITCH_EXT,
+                           EGL_LINUX_DMA_BUF_EXT, EGLDEBUGPROCKHR, EGLAttrib,
                            EGLuint64KHR, EGLNativeDisplayType, EGLConfig, EGLContext, EGLDisplay,
                            EGLSurface, EGLClientBuffer, EGLBoolean, EGLint, EGLenum, EGLImageKHR};
 use generated::p_defines::{PIPE_TEXTURE_1D, PIPE_TEXTURE_2D, PIPE_BIND_SAMPLER_VIEW};
@@ -301,6 +304,7 @@ impl Deref for EGLFunctions {
 pub struct Renderer {
     no_sync_send: PhantomData<*mut ()>,
     egl_funcs: EGLFunctions,
+    display: EGLDisplay,
 }
 
 impl Renderer {
@@ -397,6 +401,7 @@ impl Renderer {
         Ok(Renderer {
                no_sync_send: PhantomData,
                egl_funcs,
+               display
            })
     }
 
@@ -458,6 +463,22 @@ impl Renderer {
            })
     }
 
+    /// Imports a resource from an EGLImage.
+    pub fn import_resource(&self,
+                           mut args: virgl_renderer_resource_create_args,
+                           image: Image)
+                           -> Result<Resource> {
+        let ret = unsafe { virgl_renderer_resource_import_eglimage(&mut args, image.image) };
+        ret_to_res(ret)?;
+        Ok(Resource {
+               id: args.handle,
+               backing_iovecs: Vec::new(),
+               backing_mem: None,
+               egl_funcs: self.egl_funcs.clone(),
+               no_sync_send: PhantomData,
+           })
+    }
+
     /// Helper that creates a simple 1 dimensional resource with basic metadata.
     pub fn create_tex_1d(&self, id: u32, width: u32) -> Result<Resource> {
         self.create_resource(virgl_renderer_resource_create_args {
@@ -491,6 +512,47 @@ impl Renderer {
                                  flags: 0,
                              })
     }
+
+    /// Creates an EGLImage from a DMA buffer.
+    pub fn image_from_dmabuf(&self,
+                             fourcc: u32,
+                             width: u32,
+                             height: u32,
+                             fd: RawFd,
+                             offset: u32,
+                             stride: u32) -> Result<Image> {
+        let mut attrs = [EGL_WIDTH as EGLint,
+                         width as EGLint,
+                         EGL_HEIGHT as EGLint,
+                         height as EGLint,
+                         EGL_LINUX_DRM_FOURCC_EXT as EGLint,
+                         fourcc as EGLint,
+                         EGL_DMA_BUF_PLANE0_FD_EXT as EGLint,
+                         fd as EGLint,
+                         EGL_DMA_BUF_PLANE0_OFFSET_EXT as EGLint,
+                         offset as EGLint,
+                         EGL_DMA_BUF_PLANE0_PITCH_EXT as EGLint,
+                         stride as EGLint,
+                         EGL_NONE as EGLint];
+
+        let image = unsafe {
+            (self.egl_funcs.CreateImageKHR)(self.display,
+                                            0 as EGLContext,
+                                            EGL_LINUX_DMA_BUF_EXT,
+                                            null_mut() as EGLClientBuffer,
+                                            attrs.as_mut_ptr())
+        };
+
+        if image.is_null() {
+            return Err(Error::CreateImage);
+        }
+
+        Ok(Image {
+            egl_funcs: self.egl_funcs.clone(),
+            egl_dpy: self.display,
+            image
+        })
+    }
 }
 
 /// A context in which resources can be attached/detached and commands can be submitted.
@@ -548,6 +610,21 @@ impl Drop for Context {
     }
 }
 
+/// A wrapper of an EGLImage to manage its destruction.
+pub struct Image {
+    egl_funcs: EGLFunctions,
+    egl_dpy: EGLDisplay,
+    image: EGLImageKHR,
+}
+
+impl Drop for Image {
+    fn drop(&mut self) {
+        unsafe {
+            (self.egl_funcs.DestroyImageKHR)(self.egl_dpy, self.image);
+        }
+    }
+}
+
 /// A DMABUF file descriptor handle and metadata returned from `Resource::export`.
 #[derive(Debug)]
 pub struct ExportedResource {