[Mesa-dev] [PATCH 1/2] kms-swrast: Support Prime fd handling

Emil Velikov emil.l.velikov at gmail.com
Wed Aug 20 08:14:07 PDT 2014


On 15/08/14 22:32, Andreas Pokorny wrote:
> Allows using prime fds as display target and from display target.
> Test for PRIME capability after initializing kms_swrast screen.
> 
> Signed-off-by: Andreas Pokorny <andreas.pokorny at canonical.com>
> ---
>  src/gallium/state_trackers/dri/dri2.c             |  8 ++
>  src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.c | 91 +++++++++++++++++++----
>  2 files changed, 86 insertions(+), 13 deletions(-)
> 
> diff --git a/src/gallium/state_trackers/dri/dri2.c b/src/gallium/state_trackers/dri/dri2.c
> index c466de7..e52bd71 100644
> --- a/src/gallium/state_trackers/dri/dri2.c
> +++ b/src/gallium/state_trackers/dri/dri2.c
> @@ -1327,6 +1327,7 @@ dri_kms_init_screen(__DRIscreen * sPriv)
>     const __DRIconfig **configs;
>     struct dri_screen *screen;
>     struct pipe_screen *pscreen = NULL;
> +   uint64_t cap;
>  
>     screen = CALLOC_STRUCT(dri_screen);
>     if (!screen)
> @@ -1338,6 +1339,13 @@ dri_kms_init_screen(__DRIscreen * sPriv)
>     sPriv->driverPrivate = (void *)screen;
>  
>     pscreen = kms_swrast_create_screen(screen->fd);
> +
> +   if (drmGetCap(sPriv->fd, DRM_CAP_PRIME, &cap) == 0 &&
> +          (cap & DRM_PRIME_CAP_IMPORT)) {
> +      dri2ImageExtension.createImageFromFds = dri2_from_fds;
> +      dri2ImageExtension.createImageFromDmaBufs = dri2_from_dma_bufs;
> +   }
> +
>     sPriv->extensions = dri_screen_extensions;
>  
>     /* dri_init_screen_helper checks pscreen for us */
> diff --git a/src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.c b/src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.c
> index c9934bb..7246ffc 100644
> --- a/src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.c
> +++ b/src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.c
> @@ -38,6 +38,7 @@
>  #include <sys/mman.h>
>  #include <unistd.h>
>  #include <dlfcn.h>
> +#include <fcntl.h>
>  #include <xf86drm.h>
>  
>  #include "pipe/p_compiler.h"
> @@ -210,6 +211,38 @@ kms_sw_displaytarget_map(struct sw_winsys *ws,
>     return kms_sw_dt->mapped;
>  }
>  
> +static struct kms_sw_displaytarget *
> +kms_sw_displaytarget_add_from_prime(struct kms_sw_winsys *kms_sw, int fd)
> +{
> +   uint32_t handle;
> +   struct kms_sw_displaytarget * kms_sw_dt;
> +   int ret;
> +
> +   ret = drmPrimeFDToHandle(kms_sw->fd, fd, &handle);
> +
> +   if (ret)
> +      return NULL;
> +
> +   kms_sw_dt = CALLOC_STRUCT(kms_sw_displaytarget);
> +   if (!kms_sw_dt)
> +      return NULL;
> +
> +   kms_sw_dt->ref_count = 1;
> +   kms_sw_dt->handle = handle;
> +   kms_sw_dt->size = lseek(fd, 0, SEEK_END);
> +
> +   if (kms_sw_dt->size == (off_t)-1) {
> +      FREE(kms_sw_dt);
> +      return NULL;
> +   }
> +
> +   lseek(fd, 0, SEEK_SET);
> +
> +   list_add(&kms_sw_dt->link, &kms_sw->bo_list);
> +
> +   return kms_sw_dt;
> +}
> +
>  static void
>  kms_sw_displaytarget_unmap(struct sw_winsys *ws,
>                             struct sw_displaytarget *dt)
> @@ -231,17 +264,38 @@ kms_sw_displaytarget_from_handle(struct sw_winsys *ws,
>     struct kms_sw_winsys *kms_sw = kms_sw_winsys(ws);
>     struct kms_sw_displaytarget *kms_sw_dt;
>  
> -   assert(whandle->type == DRM_API_HANDLE_TYPE_KMS);
> -
> -   LIST_FOR_EACH_ENTRY(kms_sw_dt, &kms_sw->bo_list, link) {
> -      if (kms_sw_dt->handle == whandle->handle) {
> -         kms_sw_dt->ref_count++;
> -
> -         DEBUG("KMS-DEBUG: imported buffer %u (size %u)\n", kms_sw_dt->handle, kms_sw_dt->size);
> -
> -         *stride = kms_sw_dt->stride;
> +   assert(whandle->type == DRM_API_HANDLE_TYPE_KMS ||
> +          whandle->type == DRM_API_HANDLE_TYPE_FD);
> +
> +   switch(whandle->type) {
> +   case DRM_API_HANDLE_TYPE_FD:
> +      {
> +         kms_sw_dt = kms_sw_displaytarget_add_from_prime(kms_sw, whandle->handle);
> +         if (kms_sw_dt) {
> +            kms_sw_dt->ref_count++;
> +            kms_sw_dt->width = templ->width0;
> +            kms_sw_dt->height = templ->height0;
> +            if (kms_sw_dt->height)
> +               kms_sw_dt->stride = kms_sw_dt->size/kms_sw_dt->height;
> +            *stride = kms_sw_dt->stride;
> +         }
>           return (struct sw_displaytarget *)kms_sw_dt;
>        }
> +   case DRM_API_HANDLE_TYPE_KMS:
> +      {
> +         LIST_FOR_EACH_ENTRY(kms_sw_dt, &kms_sw->bo_list, link) {
> +            if (kms_sw_dt->handle == whandle->handle) {
> +               kms_sw_dt->ref_count++;
> +
> +               DEBUG("KMS-DEBUG: imported buffer %u (size %u)\n", kms_sw_dt->handle, kms_sw_dt->size);
> +
> +               *stride = kms_sw_dt->stride;
> +               return (struct sw_displaytarget *)kms_sw_dt;
> +            }
> +         }
> +      }
> +   default:
> +   break;
Please formatting the switch so that it matches the one below.

>     }
>  
>     assert(0);
> @@ -253,16 +307,27 @@ kms_sw_displaytarget_get_handle(struct sw_winsys *winsys,
>                                  struct sw_displaytarget *dt,
>                                  struct winsys_handle *whandle)
>  {
> +   struct kms_sw_winsys *kms_sw = kms_sw_winsys(winsys);
>     struct kms_sw_displaytarget *kms_sw_dt = kms_sw_displaytarget(dt);
>  
> -   if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
> +   switch(whandle->type) {
> +   case DRM_API_HANDLE_TYPE_KMS:
>        whandle->handle = kms_sw_dt->handle;
>        whandle->stride = kms_sw_dt->stride;
> -   } else {
> +      return TRUE;
> +   case DRM_API_HANDLE_TYPE_FD:
> +      if (drmPrimeHandleToFD(kms_sw->fd, kms_sw_dt->handle, DRM_CLOEXEC, &whandle->handle)) {
> +         whandle->handle = 0;
> +         whandle->stride = 0;
> +         return FALSE;
> +      }
> +      whandle->stride = kms_sw_dt->stride;
> +      return TRUE;
> +   default:
>        whandle->handle = 0;
>        whandle->stride = 0;
> +      return FALSE;
Nice catch. I'm not sure if we need to zero the handle/stride, but if you
prefer keeping it, can you please reshuffle it like below ?

   case DRM_API_HANDLE_TYPE_FD:
      if (!drmPrimeHandleToFD(kms_sw->fd, kms_sw_dt->handle,
                              DRM_CLOEXEC, &whandle->handle)) {
         whandle->stride = kms_sw_dt->stride;
         return TRUE;
      }
      /* fall-through */
   default:
      whandle->handle = 0;
      whandle->stride = 0;
      return FALSE;


Thanks
Emil

>     }
> -   return TRUE;
>  }
>  
>  static void
> @@ -315,4 +380,4 @@ kms_dri_create_winsys(int fd)
>     return &ws->base;
>  }
>  
> -/* vim: set sw=3 ts=8 sts=3 expandtab: */
> \ No newline at end of file
> +/* vim: set sw=3 ts=8 sts=3 expandtab: */
> 



More information about the mesa-dev mailing list