[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