From ad609bf55a87200ab11ad7cf31420dcfd8dfc141 Mon Sep 17 00:00:00 2001 From: Bas Nieuwenhuizen Date: Mon, 25 May 2020 15:53:59 +0200 Subject: [PATCH] frontend/dri: Implement mapping individual planes. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit It is kinda surprising that image2 = fromPlanar(image, 2, NULL) mapImage(..., image2, ...) does not map the third plane. This implements that behavior in the case where the DRI frontend lowers the multi-planar textures. In the case it doesn't this would need driver support. AFAIU at least etnaviv is impacted, and while it looks possible, I don't have the etnaviv knowledge to implement it. Instead of silently returning weird results (either always plane 0 or possibly something interleaved) this adds an error return on mapping multi-planar textures otherwise. Reviewed-by: Marek Olšák Reviewed-by: Eric Anholt Part-of: --- src/gallium/frontends/dri/dri2.c | 19 ++++++++++++++++--- src/gallium/frontends/dri/dri_screen.h | 1 + 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/gallium/frontends/dri/dri2.c b/src/gallium/frontends/dri/dri2.c index bfbaa1bd84a..9facc47d1da 100644 --- a/src/gallium/frontends/dri/dri2.c +++ b/src/gallium/frontends/dri/dri2.c @@ -801,6 +801,7 @@ dri2_create_image_from_winsys(__DRIscreen *_screen, img->layer = 0; img->use = 0; img->loader_private = loaderPrivate; + img->lowered_yuv = use_lowered; return img; } @@ -1010,6 +1011,7 @@ dri2_create_image_common(__DRIscreen *_screen, img->dri_fourcc = map->dri_fourcc; img->dri_components = 0; img->use = use; + img->lowered_yuv = false; img->loader_private = loaderPrivate; return img; @@ -1260,6 +1262,7 @@ dri2_dup_image(__DRIimage *image, void *loaderPrivate) /* This should be 0 for sub images, but dup is also used for base images. */ img->dri_components = image->dri_components; img->loader_private = loaderPrivate; + img->lowered_yuv = image->lowered_yuv; return img; } @@ -1542,20 +1545,30 @@ dri2_map_image(__DRIcontext *context, __DRIimage *image, struct dri_context *ctx = dri_context(context); struct pipe_context *pipe = ctx->st->pipe; enum pipe_transfer_usage pipe_access = 0; + struct pipe_resource *resource = image->texture; struct pipe_transfer *trans; void *map; if (!image || !data || *data) return NULL; + if (image->lowered_yuv) { + unsigned plane = image->plane; + if (plane >= dri2_get_mapping_by_format(image->dri_format)->nplanes) + return NULL; + + while (plane--) + resource = resource->next; + } else if (dri2_get_mapping_by_format(image->dri_format)->nplanes > 1) + return NULL; + if (flags & __DRI_IMAGE_TRANSFER_READ) pipe_access |= PIPE_TRANSFER_READ; if (flags & __DRI_IMAGE_TRANSFER_WRITE) pipe_access |= PIPE_TRANSFER_WRITE; - map = pipe_transfer_map(pipe, image->texture, - 0, 0, pipe_access, x0, y0, width, height, - &trans); + map = pipe_transfer_map(pipe, resource, 0, 0, pipe_access, x0, y0, + width, height, &trans); if (map) { *data = trans; *stride = trans->stride; diff --git a/src/gallium/frontends/dri/dri_screen.h b/src/gallium/frontends/dri/dri_screen.h index e330aa1f2ac..d6f7850a264 100644 --- a/src/gallium/frontends/dri/dri_screen.h +++ b/src/gallium/frontends/dri/dri_screen.h @@ -106,6 +106,7 @@ struct __DRIimageRec { uint32_t dri_components; unsigned use; unsigned plane; + bool lowered_yuv; void *loader_private; -- 2.30.2