On Fri, 2017-06-23 at 17:50 +0200, Lucas Stach wrote: > This implements resource import with modifier, deriving the correct > internal layout from the modifier and constructing a render compatible > base resource if needed. > > This removes the special cases for DDX and renderonly scanout allocated > buffers, as the linear modifier is enough to trigger correct handling > of those buffers. > > Signed-off-by: Lucas Stach <l.st...@pengutronix.de> > --- > src/gallium/drivers/etnaviv/etnaviv_resource.c | 112 > +++++++++++++++++-------- > 1 file changed, 78 insertions(+), 34 deletions(-) > > diff --git a/src/gallium/drivers/etnaviv/etnaviv_resource.c > b/src/gallium/drivers/etnaviv/etnaviv_resource.c > index 43f63f8908a0..f006d24a1bba 100644 > --- a/src/gallium/drivers/etnaviv/etnaviv_resource.c > +++ b/src/gallium/drivers/etnaviv/etnaviv_resource.c > @@ -36,6 +36,29 @@ > #include "util/u_inlines.h" > #include "util/u_memory.h" > > +#include <drm_fourcc.h> > + > +#ifndef DRM_FORMAT_MOD_INVALID > +#define DRM_FORMAT_MOD_INVALID ((1ULL<<56) - 1) > +#endif > + > +static unsigned int modifier_to_layout(uint64_t modifier)
This could return a value of type enum etna_surface_layout. > +{ > + switch (modifier) { > + case DRM_FORMAT_MOD_VIVANTE_TILED: > + return ETNA_LAYOUT_TILED; > + case DRM_FORMAT_MOD_VIVANTE_SUPER_TILED: > + return ETNA_LAYOUT_SUPER_TILED; > + case DRM_FORMAT_MOD_VIVANTE_SPLIT_TILED: > + return ETNA_LAYOUT_MULTI_TILED; > + case DRM_FORMAT_MOD_VIVANTE_SPLIT_SUPER_TILED: > + return ETNA_LAYOUT_MULTI_SUPERTILED; > + case DRM_FORMAT_MOD_LINEAR: > + default: > + return ETNA_LAYOUT_LINEAR; > + } > +} > + > /* A tile is 4x4 pixels, having 'screen->specs.bits_per_tile' of tile status. > * So, in a buffer of N pixels, there are N / (4 * 4) tiles. > * We need N * screen->specs.bits_per_tile / (4 * 4) bits of tile status, or > @@ -141,6 +164,7 @@ etna_resource_alloc(struct pipe_screen *pscreen, unsigned > layout, > const struct pipe_resource *templat) > { > struct etna_screen *screen = etna_screen(pscreen); > + struct etna_resource *rsc; > unsigned size; > > DBG_F(ETNA_DBG_RESOURCE_MSGS, > @@ -186,8 +210,36 @@ etna_resource_alloc(struct pipe_screen *pscreen, > unsigned layout, > paddingY = min_paddingY; > } > > - struct etna_resource *rsc = CALLOC_STRUCT(etna_resource); > + if (templat->bind & PIPE_BIND_SCANOUT) { > + struct pipe_resource scanout_templat = *templat; > + struct renderonly_scanout *scanout; > + struct winsys_handle handle; > + unsigned padX, padY; > > + /* pad scanout buffer size to be compatible with the RS */ > + padX = ETNA_RS_WIDTH_MASK + 1; > + padY = (ETNA_RS_HEIGHT_MASK + 1) * screen->specs.pixel_pipes; > + scanout_templat.width0 = align(scanout_templat.width0, padX); > + scanout_templat.height0 = align(scanout_templat.height0, padY); > + > + scanout = renderonly_scanout_for_resource(&scanout_templat, > + screen->ro, &handle); > + if (!scanout) > + return NULL; > + > + rsc = etna_resource(pscreen->resource_from_handle(pscreen, templat, > + &handle, > + > PIPE_HANDLE_USAGE_WRITE)); > + close(handle.handle); > + if (!rsc) > + return NULL; > + > + rsc->scanout = scanout; > + > + return &rsc->base; > + } > + > + rsc = CALLOC_STRUCT(etna_resource); > if (!rsc) > return NULL; > > @@ -214,30 +266,6 @@ 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) { > - struct pipe_resource scanout_templat = *templat; > - struct winsys_handle handle; > - unsigned padX, padY; > - > - /* pad scanout buffer size to be compatible with the RS */ > - padX = ETNA_RS_WIDTH_MASK + 1; > - padY = (ETNA_RS_HEIGHT_MASK + 1) * screen->specs.pixel_pipes; > - scanout_templat.width0 = align(scanout_templat.width0, padX); > - scanout_templat.height0 = align(scanout_templat.height0, padY); > - > - rsc->scanout = renderonly_scanout_for_resource(&scanout_templat, > - 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); > memset(map, 0, size); > @@ -370,14 +398,21 @@ etna_resource_from_handle(struct pipe_screen *pscreen, > goto fail; > > rsc->seqno = 1; > + rsc->layout = modifier_to_layout(handle->modifier); > + rsc->halign = TEXTURE_HALIGN_FOUR; > + Superfluous whitespace. > level->width = tmpl->width0; > level->height = tmpl->height0; > > - /* We will be using the RS to copy with this resource, so we must > - * ensure that it is appropriately aligned for the RS requirements. */ > - unsigned paddingX = ETNA_RS_WIDTH_MASK + 1; > - unsigned paddingY = (ETNA_RS_HEIGHT_MASK + 1) * screen->specs.pixel_pipes; > + /* Determine padding of the imported resource. */ > + unsigned paddingX = 0, paddingY = 0; > + etna_layout_multiple(rsc->layout, screen->specs.pixel_pipes, > + VIV_FEATURE(screen, chipMinorFeatures1, > TEXTURE_HALIGN), > + &paddingX, &paddingY, &rsc->halign); > + > + if (paddingY < 4 * screen->specs.pixel_pipes) > + paddingY = 4 * screen->specs.pixel_pipes; > > level->padded_width = align(level->width, paddingX); > level->padded_height = align(level->height, paddingY); > @@ -396,12 +431,21 @@ etna_resource_from_handle(struct pipe_screen *pscreen, > goto fail; > } > > - if (handle->type == DRM_API_HANDLE_TYPE_SHARED && tmpl->bind & > PIPE_BIND_RENDER_TARGET) { > - /* 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. */ > + if (rsc->layout == ETNA_LAYOUT_LINEAR) { > + /* > + * Both sampler and pixel pipes can't handle linear, create a > compatible > + * base resource, where we can attach the imported buffer as an > external > + * resource. > + */ > + struct pipe_resource tiled_templat = *tmpl; > + > + /* > + * Remove BIND_SCANOUT to avoid recursion, as etna_resource_create uses > + * this function to import the scanout buffer and get a tiled resource. > + */ > + tiled_templat.bind &= ~PIPE_BIND_SCANOUT; > > - ptiled = etna_resource_create(pscreen, tmpl); > + ptiled = etna_resource_create(pscreen, &tiled_templat); > if (!ptiled) > goto fail; > Reviewed-by: Philipp Zabel <p.za...@pengutronix.de> regards Philipp _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev