From: Jonathan Marek Date: Wed, 16 Jan 2019 15:22:53 +0000 (-0500) Subject: freedreno: add renderonly scanout X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=41ddf1d1506e4a1394ab784d805d1df78b1892e1;p=mesa.git freedreno: add renderonly scanout This allows creating a fd_screen with a renderonly object which will be used to allocated scanout resources. Signed-off-by: Jonathan Marek Reviewed-by: Eric Anholt [slight tweak to fix uninitialized 'prsc' in debug print] Signed-off-by: Rob Clark --- diff --git a/src/gallium/auxiliary/target-helpers/drm_helper.h b/src/gallium/auxiliary/target-helpers/drm_helper.h index 7eefa6e42ec..bb5c5790d9d 100644 --- a/src/gallium/auxiliary/target-helpers/drm_helper.h +++ b/src/gallium/auxiliary/target-helpers/drm_helper.h @@ -248,7 +248,7 @@ pipe_freedreno_create_screen(int fd, const struct pipe_screen_config *config) { struct pipe_screen *screen; - screen = fd_drm_screen_create(fd); + screen = fd_drm_screen_create(fd, NULL); return screen ? debug_screen_wrap(screen) : NULL; } diff --git a/src/gallium/drivers/freedreno/freedreno_resource.c b/src/gallium/drivers/freedreno/freedreno_resource.c index ca48fc9cee1..11319a44bb7 100644 --- a/src/gallium/drivers/freedreno/freedreno_resource.c +++ b/src/gallium/drivers/freedreno/freedreno_resource.c @@ -663,6 +663,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); } @@ -688,7 +691,7 @@ fd_resource_get_handle(struct pipe_screen *pscreen, handle->modifier = fd_resource_modifier(rsc); - return fd_screen_bo_get_handle(pscreen, rsc->bo, + return fd_screen_bo_get_handle(pscreen, rsc->bo, rsc->scanout, rsc->slices[0].pitch * rsc->cpp, handle); } @@ -845,11 +848,37 @@ fd_resource_create_with_modifiers(struct pipe_screen *pscreen, const uint64_t *modifiers, int count) { 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; + if (screen->ro && (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; + + renderonly_scanout_destroy(scanout, screen->ro); + + assert(handle.type == WINSYS_HANDLE_TYPE_FD); + rsc = fd_resource(pscreen->resource_from_handle(pscreen, tmpl, + &handle, + PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE)); + close(handle.handle); + if (!rsc) + return NULL; + + return &rsc->base; + } + + rsc = CALLOC_STRUCT(fd_resource); + prsc = &rsc->base; + DBG("%p: target=%d, format=%s, %ux%ux%u, array_size=%u, last_level=%u, " "nr_samples=%u, usage=%u, bind=%x, flags=%x", prsc, tmpl->target, util_format_name(format), @@ -1050,6 +1079,12 @@ fd_resource_from_handle(struct pipe_screen *pscreen, assert(rsc->cpp); + if (screen->ro) { + rsc->scanout = + renderonly_create_gpu_import_for_resource(prsc, screen->ro, NULL); + /* failure is expected in some cases.. */ + } + return prsc; fail: diff --git a/src/gallium/drivers/freedreno/freedreno_resource.h b/src/gallium/drivers/freedreno/freedreno_resource.h index 83708244857..10ab8bfa225 100644 --- a/src/gallium/drivers/freedreno/freedreno_resource.h +++ b/src/gallium/drivers/freedreno/freedreno_resource.h @@ -72,6 +72,7 @@ struct fd_resource { /* buffer range that has been initialized */ struct util_range valid_buffer_range; bool valid; + struct renderonly_scanout *scanout; /* reference to the resource holding stencil data for a z32_s8 texture */ /* TODO rename to secondary or auxiliary? */ diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c index b372d5c5596..e596a4e8462 100644 --- a/src/gallium/drivers/freedreno/freedreno_screen.c +++ b/src/gallium/drivers/freedreno/freedreno_screen.c @@ -147,6 +147,9 @@ fd_screen_destroy(struct pipe_screen *pscreen) if (screen->dev) fd_device_del(screen->dev); + if (screen->ro) + FREE(screen->ro); + fd_bc_fini(&screen->batch_cache); slab_destroy_parent(&screen->transfer_pool); @@ -637,6 +640,7 @@ fd_get_compiler_options(struct pipe_screen *pscreen, boolean fd_screen_bo_get_handle(struct pipe_screen *pscreen, struct fd_bo *bo, + struct renderonly_scanout *scanout, unsigned stride, struct winsys_handle *whandle) { @@ -645,6 +649,8 @@ fd_screen_bo_get_handle(struct pipe_screen *pscreen, if (whandle->type == WINSYS_HANDLE_TYPE_SHARED) { return fd_bo_get_name(bo, &whandle->handle) == 0; } else if (whandle->type == WINSYS_HANDLE_TYPE_KMS) { + if (renderonly_get_handle(scanout, whandle)) + return TRUE; whandle->handle = fd_bo_handle(bo); return TRUE; } else if (whandle->type == WINSYS_HANDLE_TYPE_FD) { @@ -713,7 +719,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; @@ -734,6 +740,14 @@ fd_screen_create(struct fd_device *dev) screen->dev = dev; screen->refcnt = 1; + if (ro) { + screen->ro = renderonly_dup(ro); + 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 1060f4609f6..7c457399f2a 100644 --- a/src/gallium/drivers/freedreno/freedreno_screen.h +++ b/src/gallium/drivers/freedreno/freedreno_screen.h @@ -34,6 +34,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" @@ -101,6 +102,8 @@ struct fd_screen { unsigned num_supported_modifiers; const uint64_t *supported_modifiers; + + struct renderonly *ro; }; static inline struct fd_screen * @@ -111,12 +114,14 @@ fd_screen(struct pipe_screen *pscreen) boolean fd_screen_bo_get_handle(struct pipe_screen *pscreen, struct fd_bo *bo, + struct renderonly_scanout *scanout, 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/targets/pipe-loader/pipe_msm.c b/src/gallium/targets/pipe-loader/pipe_msm.c index 886fbdfc7e3..683332579fe 100644 --- a/src/gallium/targets/pipe-loader/pipe_msm.c +++ b/src/gallium/targets/pipe-loader/pipe_msm.c @@ -8,7 +8,7 @@ create_screen(int fd, const struct pipe_screen_config *config) { struct pipe_screen *screen; - screen = fd_drm_screen_create(fd); + screen = fd_drm_screen_create(fd, NULL); if (!screen) return NULL; diff --git a/src/gallium/winsys/freedreno/drm/freedreno_drm_public.h b/src/gallium/winsys/freedreno/drm/freedreno_drm_public.h index a7ba20707d5..2f5591e867a 100644 --- a/src/gallium/winsys/freedreno/drm/freedreno_drm_public.h +++ b/src/gallium/winsys/freedreno/drm/freedreno_drm_public.h @@ -3,7 +3,8 @@ #define __FREEDRENO_DRM_PUBLIC_H__ struct pipe_screen; +struct renderonly; -struct pipe_screen *fd_drm_screen_create(int drmFD); +struct pipe_screen *fd_drm_screen_create(int drmFD, struct renderonly *ro); #endif diff --git a/src/gallium/winsys/freedreno/drm/freedreno_drm_winsys.c b/src/gallium/winsys/freedreno/drm/freedreno_drm_winsys.c index a65583f87d4..dff6209e1ef 100644 --- a/src/gallium/winsys/freedreno/drm/freedreno_drm_winsys.c +++ b/src/gallium/winsys/freedreno/drm/freedreno_drm_winsys.c @@ -85,7 +85,7 @@ static int compare_fd(void *key1, void *key2) } struct pipe_screen * -fd_drm_screen_create(int fd) +fd_drm_screen_create(int fd, struct renderonly *ro) { struct pipe_screen *pscreen = NULL; @@ -104,7 +104,7 @@ fd_drm_screen_create(int fd) if (!dev) goto unlock; - pscreen = fd_screen_create(dev); + pscreen = fd_screen_create(dev, ro); if (pscreen) { int fd = fd_device_fd(dev);