diff mbox

intel: make bufmgr_gem shareable from different API

Message ID CAPj87rMjG2advvvPGkASzwNZOexH5mZ8R77PKeF4yEj7aga6sw@mail.gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Daniel Stone Sept. 11, 2014, 12:16 p.m. UTC
Hi,

On 11 September 2014 12:52, Chris Wilson <chris@chris-wilson.co.uk> wrote:

> On Thu, Sep 11, 2014 at 12:33:41PM +0100, Lionel Landwerlin wrote:
> > When using Mesa and LibVA in the same process, one would like to be
> > able bind buffers from the output of the decoder to a GL texture
> > through an EGLImage.
> >
> > LibVA can reuse buffers allocated by Gbm through a file descriptor. It
> > will then wrap it into a drm_intel_bo with
> > drm_intel_bo_gem_create_from_prime().
> >
> > Given both libraries are using libdrm to allocate and use buffer
> > objects, there is a need to have the buffer objects properly
> > refcounted. That is possible if both API use the same drm_intel_bo
> > objects, but that also requires that both API use the same
> > drm_intel_bufmgr object.
>
> The description is wrong though. Reusing buffers export and import
> through a dmabuf, should work and be correctly refcounted already.
>

Indeed.

I've been using the attached patch to deal with the case where we have two
EGLDisplays/DRIscreens that can share DRIimage objects (long story, and a
much more ugly patch), and it works perfectly.

The cover letter's description is right though, in that you get a cryptic
message thanks to relocation having been totally skipped when you submit
objects from a foreign bufmgr.

Cheers,
Daniel
diff mbox

Patch

diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index 23aa528..54df6a8 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -1262,7 +1262,8 @@  dri2_create_image_wayland_wl_buffer(_EGLDisplay *disp, _EGLContext *ctx,
       return NULL;
    }
 
-   dri_image = dri2_dpy->image->fromPlanar(buffer->driver_buffer, plane, NULL);
+   dri_image = dri2_dpy->image->fromPlanar(buffer->driver_buffer, plane,
+                                           dri2_dpy->dri_screen);
 
    if (dri_image == NULL) {
       _eglError(EGL_BAD_PARAMETER, "dri2_create_image_wayland_wl_buffer");
diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c
index 9bd4fda..667620b 100644
--- a/src/mesa/drivers/dri/i965/intel_screen.c
+++ b/src/mesa/drivers/dri/i965/intel_screen.c
@@ -739,6 +739,9 @@  intel_from_planar(__DRIimage *parent, int plane, void *loaderPrivate)
     struct intel_image_format *f;
     uint32_t mask_x, mask_y;
     __DRIimage *image;
+    const __DRIscreen *dri_screen = loaderPrivate;
+    const struct intel_screen *const intel_screen =
+        (struct intel_screen *) dri_screen->driverPrivate;
 
     if (parent == NULL || parent->planar_format == NULL)
         return NULL;
@@ -771,13 +774,42 @@  intel_from_planar(__DRIimage *parent, int plane, void *loaderPrivate)
        return NULL;
     }
 
+    if (parent->region->bo->bufmgr == intel_screen->bufmgr) {
+ 
+
+        image->region->bo = parent->region->bo;
+        drm_intel_bo_reference(image->region->bo);
+    } else {
+        int err, fd;
+
+  
+
+        err = drm_intel_bo_gem_export_to_prime(parent->region->bo, &fd);
+        if (err != 0) {
+            _mesa_warning(NULL, "intel_create_sub_image: prime export failed: %d\n",
+                          -err);
+            free(image->region);
+            free(image);
+            return NULL;
+        }
+
+        image->region->bo =
+            drm_intel_bo_gem_create_from_prime(intel_screen->bufmgr, fd,
+                                               parent->region->bo->size);
+        close(fd);
+        if (!image->region->bo) {
+           _mesa_warning(NULL, "intel_create_sub_image: prime import failed\n");
+           free(image->region);
+           free(image);
+           return NULL;
+       }
+    }
+
     image->region->cpp = _mesa_get_format_bytes(image->format);
     image->region->width = width;
     image->region->height = height;
     image->region->pitch = stride;
     image->region->refcount = 1;
-    image->region->bo = parent->region->bo;
-    drm_intel_bo_reference(image->region->bo);
     image->region->tiling = parent->region->tiling;
     image->offset = offset;
     intel_setup_image_from_dimensions(image);