2017-07-04 17:45 GMT+02:00 Lucas Stach <l.st...@pengutronix.de>: > The current way of importing the resource from renderonly after allocation > is opaque and is taking away control from the driver, which it needs in > order to implement more advanced scenarios, than the simple linear > scanout with matching stride alignments. > > Signed-off-by: Lucas Stach <l.st...@pengutronix.de>
Looks good ti me (but I did not test this series on real hw). Reviewed-by: Christian Gmeiner <christian.gmei...@gmail.com> > --- > src/gallium/auxiliary/renderonly/renderonly.c | 52 > +++++++----------------- > src/gallium/auxiliary/renderonly/renderonly.h | 20 ++++----- > src/gallium/drivers/etnaviv/etnaviv_clear_blit.c | 8 ++-- > src/gallium/drivers/etnaviv/etnaviv_resource.c | 34 ++++++++++++---- > src/gallium/drivers/etnaviv/etnaviv_resource.h | 5 +++ > src/gallium/drivers/vc4/vc4_resource.c | 5 ++- > 6 files changed, 62 insertions(+), 62 deletions(-) > > diff --git a/src/gallium/auxiliary/renderonly/renderonly.c > b/src/gallium/auxiliary/renderonly/renderonly.c > index d3ed214f4e43..da91f12b2ea1 100644 > --- a/src/gallium/auxiliary/renderonly/renderonly.c > +++ b/src/gallium/auxiliary/renderonly/renderonly.c > @@ -50,27 +50,12 @@ renderonly_dup(const struct renderonly *ro) > return copy; > } > > -struct renderonly_scanout * > -renderonly_scanout_for_prime(struct pipe_resource *rsc, struct renderonly > *ro) > -{ > - struct renderonly_scanout *scanout; > - > - scanout = CALLOC_STRUCT(renderonly_scanout); > - if (!scanout) > - return NULL; > - > - scanout->prime = rsc; > - > - return scanout; > -} > - > void > renderonly_scanout_destroy(struct renderonly_scanout *scanout, > struct renderonly *ro) > { > struct drm_mode_destroy_dumb destroy_dumb = { }; > > - pipe_resource_reference(&scanout->prime, NULL); > if (ro->kms_fd != -1) { > destroy_dumb.handle = scanout->handle; > drmIoctl(ro->kms_fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_dumb); > @@ -80,12 +65,11 @@ renderonly_scanout_destroy(struct renderonly_scanout > *scanout, > > struct renderonly_scanout * > renderonly_create_kms_dumb_buffer_for_resource(struct pipe_resource *rsc, > - struct renderonly *ro) > + struct renderonly *ro, > + struct winsys_handle > *out_handle) > { > - struct pipe_screen *screen = rsc->screen; > struct renderonly_scanout *scanout; > - struct winsys_handle handle; > - int prime_fd, err; > + int err; > struct drm_mode_create_dumb create_dumb = { > .width = rsc->width0, > .height = rsc->height0, > @@ -108,30 +92,21 @@ renderonly_create_kms_dumb_buffer_for_resource(struct > pipe_resource *rsc, > scanout->handle = create_dumb.handle; > scanout->stride = create_dumb.pitch; > > - /* export dumb buffer */ > + if (!out_handle) > + return scanout; > + > + /* fill in winsys handle */ > + memset(out_handle, 0, sizeof(*out_handle)); > + out_handle->type = DRM_API_HANDLE_TYPE_FD; > + out_handle->stride = create_dumb.pitch; > + > err = drmPrimeHandleToFD(ro->kms_fd, create_dumb.handle, O_CLOEXEC, > - &prime_fd); > + (int *)&out_handle->handle); > if (err < 0) { > fprintf(stderr, "failed to export dumb buffer: %s\n", strerror(errno)); > goto free_dumb; > } > > - /* import dumb buffer */ > - memset(&handle, 0, sizeof(handle)); > - handle.type = DRM_API_HANDLE_TYPE_FD; > - handle.handle = prime_fd; > - handle.stride = create_dumb.pitch; > - > - scanout->prime = screen->resource_from_handle(screen, rsc, > - &handle, PIPE_HANDLE_USAGE_READ_WRITE); > - > - close(prime_fd); > - > - if (!scanout->prime) { > - fprintf(stderr, "failed to create resource_from_handle: %s\n", > strerror(errno)); > - goto free_dumb; > - } > - > return scanout; > > free_dumb: > @@ -146,7 +121,8 @@ free_scanout: > > struct renderonly_scanout * > renderonly_create_gpu_import_for_resource(struct pipe_resource *rsc, > - struct renderonly *ro) > + struct renderonly *ro, > + struct winsys_handle *out_handle) > { > struct pipe_screen *screen = rsc->screen; > struct renderonly_scanout *scanout; > diff --git a/src/gallium/auxiliary/renderonly/renderonly.h > b/src/gallium/auxiliary/renderonly/renderonly.h > index 70641c45878a..6a89c29e2ef6 100644 > --- a/src/gallium/auxiliary/renderonly/renderonly.h > +++ b/src/gallium/auxiliary/renderonly/renderonly.h > @@ -34,8 +34,6 @@ > struct renderonly_scanout { > uint32_t handle; > uint32_t stride; > - > - struct pipe_resource *prime; > }; > > struct renderonly { > @@ -59,7 +57,8 @@ struct renderonly { > * to be done in flush_resource(..) like a resolve to linear. > */ > struct renderonly_scanout *(*create_for_resource)(struct pipe_resource > *rsc, > - struct renderonly *ro); > + struct renderonly *ro, > + struct winsys_handle > *out_handle); > int kms_fd; > int gpu_fd; > }; > @@ -68,14 +67,13 @@ struct renderonly * > renderonly_dup(const struct renderonly *ro); > > static inline struct renderonly_scanout * > -renderonly_scanout_for_resource(struct pipe_resource *rsc, struct renderonly > *ro) > +renderonly_scanout_for_resource(struct pipe_resource *rsc, > + struct renderonly *ro, > + struct winsys_handle *out_handle) > { > - return ro->create_for_resource(rsc, ro); > + return ro->create_for_resource(rsc, ro, out_handle); > } > > -struct renderonly_scanout * > -renderonly_scanout_for_prime(struct pipe_resource *rsc, struct renderonly > *ro); > - > void > renderonly_scanout_destroy(struct renderonly_scanout *scanout, > struct renderonly *ro); > @@ -99,13 +97,15 @@ renderonly_get_handle(struct renderonly_scanout *scanout, > */ > struct renderonly_scanout * > renderonly_create_kms_dumb_buffer_for_resource(struct pipe_resource *rsc, > - struct renderonly *ro); > + struct renderonly *ro, > + struct winsys_handle > *out_handle); > > /** > * Import GPU resource into scanout hw. > */ > struct renderonly_scanout * > renderonly_create_gpu_import_for_resource(struct pipe_resource *rsc, > - struct renderonly *ro); > + struct renderonly *ro, > + struct winsys_handle *out_handle); > > #endif /* RENDERONLY_H_ */ > diff --git a/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c > b/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c > index 80967be3f93d..83acfe21d033 100644 > --- a/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c > +++ b/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c > @@ -602,10 +602,10 @@ etna_flush_resource(struct pipe_context *pctx, struct > pipe_resource *prsc) > { > struct etna_resource *rsc = etna_resource(prsc); > > - if (rsc->scanout) { > - if (etna_resource_older(etna_resource(rsc->scanout->prime), rsc)) { > - etna_copy_resource(pctx, rsc->scanout->prime, prsc, 0, 0); > - etna_resource(rsc->scanout->prime)->seqno = rsc->seqno; > + if (rsc->external) { > + if (etna_resource_older(etna_resource(rsc->external), rsc)) { > + etna_copy_resource(pctx, rsc->external, prsc, 0, 0); > + etna_resource(rsc->external)->seqno = rsc->seqno; > } > } else if (etna_resource_needs_flush(rsc)) { > etna_copy_resource(pctx, prsc, prsc, 0, 0); > diff --git a/src/gallium/drivers/etnaviv/etnaviv_resource.c > b/src/gallium/drivers/etnaviv/etnaviv_resource.c > index 97e0a15597fa..a62c22d0f338 100644 > --- a/src/gallium/drivers/etnaviv/etnaviv_resource.c > +++ b/src/gallium/drivers/etnaviv/etnaviv_resource.c > @@ -214,8 +214,20 @@ etna_resource_alloc(struct pipe_screen *pscreen, > unsigned layout, > rsc->bo = bo; > rsc->ts_bo = 0; /* TS is only created when first bound to surface */ > > - if (templat->bind & PIPE_BIND_SCANOUT) > - rsc->scanout = renderonly_scanout_for_resource(&rsc->base, screen->ro); > + if (templat->bind & PIPE_BIND_SCANOUT) { > + struct winsys_handle handle; > + rsc->scanout = renderonly_scanout_for_resource(&rsc->base, screen->ro, > + &handle); > + if (!rsc->scanout) > + goto free_rsc; > + > + rsc->external = pscreen->resource_from_handle(pscreen, &rsc->base, > + &handle, > + PIPE_HANDLE_USAGE_WRITE); > + close(handle.handle); > + if (!rsc->external) > + goto free_rsc; > + } > > if (DBG_ENABLED(ETNA_DBG_ZERO)) { > void *map = etna_bo_map(bo); > @@ -310,6 +322,7 @@ etna_resource_destroy(struct pipe_screen *pscreen, struct > pipe_resource *prsc) > list_delinit(&rsc->list); > > pipe_resource_reference(&rsc->texture, NULL); > + pipe_resource_reference(&rsc->external, NULL); > > FREE(rsc); > } > @@ -375,16 +388,12 @@ etna_resource_from_handle(struct pipe_screen *pscreen, > /* Render targets are linear in Xorg but must be tiled > * here. It would be nice if dri_drawable_get_format() > * set scanout for these buffers too. */ > - struct etna_resource *tiled; > > ptiled = etna_resource_create(pscreen, tmpl); > if (!ptiled) > goto fail; > > - tiled = etna_resource(ptiled); > - tiled->scanout = renderonly_scanout_for_prime(prsc, screen->ro); > - if (!tiled->scanout) > - goto fail; > + etna_resource(ptiled)->external = prsc; > > return ptiled; > } > @@ -406,9 +415,18 @@ etna_resource_get_handle(struct pipe_screen *pscreen, > struct winsys_handle *handle, unsigned usage) > { > struct etna_resource *rsc = etna_resource(prsc); > + /* Scanout is always attached to the base resource */ > + struct renderonly_scanout *scanout = rsc->scanout; > + > + /* > + * External resources are preferred, so a import->export chain of > + * render/sampler incompatible buffers yield the same handle. > + * */ nitpick: remove one * > + if (rsc->external) > + rsc = etna_resource(rsc->external); > > if (handle->type == DRM_API_HANDLE_TYPE_KMS && > - renderonly_get_handle(rsc->scanout, handle)) > + renderonly_get_handle(scanout, handle)) > return TRUE; > > return etna_screen_bo_get_handle(pscreen, rsc->bo, rsc->levels[0].stride, > diff --git a/src/gallium/drivers/etnaviv/etnaviv_resource.h > b/src/gallium/drivers/etnaviv/etnaviv_resource.h > index 3507e5ccecbc..5f563c06adcf 100644 > --- a/src/gallium/drivers/etnaviv/etnaviv_resource.h > +++ b/src/gallium/drivers/etnaviv/etnaviv_resource.h > @@ -75,6 +75,11 @@ struct etna_resource { > > /* When we are rendering to a texture, we need a differently tiled > resource */ > struct pipe_resource *texture; > + /* > + * If imported resources have an render/sampler incompatible tiling, we > keep > + * them as an external resource, which is blitted as needed. > + */ > + struct pipe_resource *external; > > enum etna_resource_status status; > > diff --git a/src/gallium/drivers/vc4/vc4_resource.c > b/src/gallium/drivers/vc4/vc4_resource.c > index 5aaa31d6e67d..480ef6860ef9 100644 > --- a/src/gallium/drivers/vc4/vc4_resource.c > +++ b/src/gallium/drivers/vc4/vc4_resource.c > @@ -598,7 +598,7 @@ vc4_resource_create(struct pipe_screen *pscreen, > > if (screen->ro && tmpl->bind & PIPE_BIND_SCANOUT) { > rsc->scanout = > - renderonly_scanout_for_resource(prsc, screen->ro); > + renderonly_scanout_for_resource(prsc, screen->ro, > NULL); > if (!rsc->scanout) > goto fail; > } > @@ -679,7 +679,8 @@ vc4_resource_from_handle(struct pipe_screen *pscreen, > */ > rsc->scanout = > renderonly_create_gpu_import_for_resource(prsc, > - > screen->ro); > + screen->ro, > + NULL); > if (!rsc->scanout) > goto fail; > } > -- > 2.11.0 > greets -- Christian Gmeiner, MSc https://christian-gmeiner.info _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev