Signed-off-by: Jonathan Marek <jonat...@marek.ca> --- .../drivers/freedreno/freedreno_resource.c | 57 +++++++++++++++++-- .../drivers/freedreno/freedreno_resource.h | 1 + .../drivers/freedreno/freedreno_screen.c | 29 +++------- .../drivers/freedreno/freedreno_screen.h | 10 ++-- .../freedreno/drm/freedreno_drm_public.h | 4 ++ .../freedreno/drm/freedreno_drm_winsys.c | 23 ++++++-- 6 files changed, 85 insertions(+), 39 deletions(-)
diff --git a/src/gallium/drivers/freedreno/freedreno_resource.c b/src/gallium/drivers/freedreno/freedreno_resource.c index 344004f696..adfa0f27a7 100644 --- a/src/gallium/drivers/freedreno/freedreno_resource.c +++ b/src/gallium/drivers/freedreno/freedreno_resource.c @@ -645,6 +645,9 @@ fd_resource_destroy(struct pipe_screen *pscreen, fd_bc_invalidate_resource(rsc, true); if (rsc->bo) fd_bo_del(rsc->bo); + if (rsc->scanout) + renderonly_scanout_destroy(rsc->scanout, fd_screen(pscreen)->ro); + util_range_destroy(&rsc->valid_buffer_range); FREE(rsc); } @@ -657,9 +660,26 @@ fd_resource_get_handle(struct pipe_screen *pscreen, unsigned usage) { struct fd_resource *rsc = fd_resource(prsc); - - return fd_screen_bo_get_handle(pscreen, rsc->bo, - rsc->slices[0].pitch * rsc->cpp, handle); + struct renderonly_scanout *scanout = rsc->scanout; + struct fd_bo *bo = rsc->bo; + + handle->stride = rsc->slices[0].pitch * rsc->cpp; + + if (handle->type == WINSYS_HANDLE_TYPE_SHARED) { + return fd_bo_get_name(bo, &handle->handle) == 0; + } else if (handle->type == WINSYS_HANDLE_TYPE_KMS) { + if (renderonly_get_handle(scanout, handle)) { + return TRUE; + } else { + handle->handle = fd_bo_handle(bo); + return TRUE; + } + } else if (handle->type == WINSYS_HANDLE_TYPE_FD) { + handle->handle = fd_bo_dmabuf(bo); + return TRUE; + } else { + return FALSE; + } } static uint32_t @@ -801,8 +821,8 @@ fd_resource_create(struct pipe_screen *pscreen, const struct pipe_resource *tmpl) { struct fd_screen *screen = fd_screen(pscreen); - struct fd_resource *rsc = CALLOC_STRUCT(fd_resource); - struct pipe_resource *prsc = &rsc->base; + struct fd_resource *rsc; + struct pipe_resource *prsc; enum pipe_format format = tmpl->format; uint32_t size; @@ -813,6 +833,33 @@ fd_resource_create(struct pipe_screen *pscreen, tmpl->array_size, tmpl->last_level, tmpl->nr_samples, tmpl->usage, tmpl->bind, tmpl->flags); + if (tmpl->bind & PIPE_BIND_SCANOUT) { + struct pipe_resource scanout_templat = *tmpl; + struct renderonly_scanout *scanout; + struct winsys_handle handle; + + scanout = renderonly_scanout_for_resource(&scanout_templat, + screen->ro, &handle); + if (!scanout) + return NULL; + + assert(handle.type == WINSYS_HANDLE_TYPE_FD); + // handle.modifier = modifier; + scanout_templat.bind &= ~PIPE_BIND_SCANOUT; + rsc = fd_resource(pscreen->resource_from_handle(pscreen, &scanout_templat, + &handle, + PIPE_HANDLE_USAGE_WRITE)); + close(handle.handle); + if (!rsc) + return NULL; + + rsc->scanout = scanout; + return &rsc->base; + } + + rsc = CALLOC_STRUCT(fd_resource); + prsc = &rsc->base; + if (!rsc) return NULL; diff --git a/src/gallium/drivers/freedreno/freedreno_resource.h b/src/gallium/drivers/freedreno/freedreno_resource.h index 2834969110..baad2baa68 100644 --- a/src/gallium/drivers/freedreno/freedreno_resource.h +++ b/src/gallium/drivers/freedreno/freedreno_resource.h @@ -65,6 +65,7 @@ struct set; struct fd_resource { struct pipe_resource base; + struct renderonly_scanout *scanout; struct fd_bo *bo; uint32_t cpp; enum pipe_format internal_format; diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c index 33f14b8f24..ef88e5b121 100644 --- a/src/gallium/drivers/freedreno/freedreno_screen.c +++ b/src/gallium/drivers/freedreno/freedreno_screen.c @@ -649,27 +649,6 @@ fd_get_compiler_options(struct pipe_screen *pscreen, return NULL; } -boolean -fd_screen_bo_get_handle(struct pipe_screen *pscreen, - struct fd_bo *bo, - unsigned stride, - struct winsys_handle *whandle) -{ - whandle->stride = stride; - - if (whandle->type == WINSYS_HANDLE_TYPE_SHARED) { - return fd_bo_get_name(bo, &whandle->handle) == 0; - } else if (whandle->type == WINSYS_HANDLE_TYPE_KMS) { - whandle->handle = fd_bo_handle(bo); - return TRUE; - } else if (whandle->type == WINSYS_HANDLE_TYPE_FD) { - whandle->handle = fd_bo_dmabuf(bo); - return TRUE; - } else { - return FALSE; - } -} - struct fd_bo * fd_screen_bo_from_handle(struct pipe_screen *pscreen, struct winsys_handle *whandle) @@ -697,7 +676,7 @@ fd_screen_bo_from_handle(struct pipe_screen *pscreen, } struct pipe_screen * -fd_screen_create(struct fd_device *dev) +fd_screen_create(struct fd_device *dev, struct renderonly *ro) { struct fd_screen *screen = CALLOC_STRUCT(fd_screen); struct pipe_screen *pscreen; @@ -717,8 +696,14 @@ fd_screen_create(struct fd_device *dev) pscreen = &screen->base; screen->dev = dev; + screen->ro = renderonly_dup(ro); screen->refcnt = 1; + if (!screen->ro) { + DBG("could not create renderonly object"); + goto fail; + } + // maybe this should be in context? screen->pipe = fd_pipe_new(screen->dev, FD_PIPE_3D); if (!screen->pipe) { diff --git a/src/gallium/drivers/freedreno/freedreno_screen.h b/src/gallium/drivers/freedreno/freedreno_screen.h index 4d9497ccb5..a39fcb50a7 100644 --- a/src/gallium/drivers/freedreno/freedreno_screen.h +++ b/src/gallium/drivers/freedreno/freedreno_screen.h @@ -36,6 +36,7 @@ #include "util/u_memory.h" #include "util/slab.h" #include "os/os_thread.h" +#include "renderonly/renderonly.h" #include "freedreno_batch_cache.h" #include "freedreno_perfcntr.h" @@ -82,6 +83,7 @@ struct fd_screen { void *compiler; /* currently unused for a2xx */ struct fd_device *dev; + struct renderonly *ro; /* NOTE: we still need a pipe associated with the screen in a few * places, like screen->get_timestamp(). For anything context @@ -104,15 +106,11 @@ fd_screen(struct pipe_screen *pscreen) { return (struct fd_screen *)pscreen; } - -boolean fd_screen_bo_get_handle(struct pipe_screen *pscreen, - struct fd_bo *bo, - unsigned stride, - struct winsys_handle *whandle); struct fd_bo * fd_screen_bo_from_handle(struct pipe_screen *pscreen, struct winsys_handle *whandle); -struct pipe_screen * fd_screen_create(struct fd_device *dev); +struct pipe_screen * +fd_screen_create(struct fd_device *dev, struct renderonly *ro); static inline boolean is_a20x(struct fd_screen *screen) diff --git a/src/gallium/winsys/freedreno/drm/freedreno_drm_public.h b/src/gallium/winsys/freedreno/drm/freedreno_drm_public.h index a7ba20707d..ea643ccfe8 100644 --- a/src/gallium/winsys/freedreno/drm/freedreno_drm_public.h +++ b/src/gallium/winsys/freedreno/drm/freedreno_drm_public.h @@ -3,6 +3,10 @@ #define __FREEDRENO_DRM_PUBLIC_H__ struct pipe_screen; +struct renderonly; + +struct pipe_screen * +fd_drm_screen_create_renderonly(struct renderonly *ro); struct pipe_screen *fd_drm_screen_create(int drmFD); diff --git a/src/gallium/winsys/freedreno/drm/freedreno_drm_winsys.c b/src/gallium/winsys/freedreno/drm/freedreno_drm_winsys.c index c1ea22a064..ea28b5b6b2 100644 --- a/src/gallium/winsys/freedreno/drm/freedreno_drm_winsys.c +++ b/src/gallium/winsys/freedreno/drm/freedreno_drm_winsys.c @@ -36,9 +36,8 @@ #include "util/u_hash_table.h" #include "os/os_thread.h" -#include "freedreno_drm_public.h" - #include "freedreno/freedreno_screen.h" +#include "freedreno_drm_public.h" static struct util_hash_table *fd_tab = NULL; @@ -87,7 +86,7 @@ static int compare_fd(void *key1, void *key2) } struct pipe_screen * -fd_drm_screen_create(int fd) +fd_drm_screen_create_renderonly(struct renderonly *ro) { struct pipe_screen *pscreen = NULL; @@ -98,15 +97,15 @@ fd_drm_screen_create(int fd) goto unlock; } - pscreen = util_hash_table_get(fd_tab, intptr_to_pointer(fd)); + pscreen = util_hash_table_get(fd_tab, intptr_to_pointer(ro->gpu_fd)); if (pscreen) { fd_screen(pscreen)->refcnt++; } else { - struct fd_device *dev = fd_device_new_dup(fd); + struct fd_device *dev = fd_device_new_dup(ro->gpu_fd); if (!dev) goto unlock; - pscreen = fd_screen_create(dev); + pscreen = fd_screen_create(dev, ro); if (pscreen) { int fd = fd_device_fd(dev); @@ -125,3 +124,15 @@ unlock: mtx_unlock(&fd_screen_mutex); return pscreen; } + +struct pipe_screen * +fd_drm_screen_create(int fd) +{ + struct renderonly ro = { + .create_for_resource = renderonly_create_gpu_import_for_resource, + .kms_fd = -1, + .gpu_fd = fd + }; + + return fd_drm_screen_create_renderonly(&ro); +} -- 2.17.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev