[PATCH 8/8] etnaviv: handle YUV textures with the 2D GPU

Philipp Zabel p.zabel at pengutronix.de
Mon Apr 15 12:43:48 UTC 2019


On Fri, 2019-04-12 at 19:38 +0200, Lucas Stach wrote:
> This allows color space conversion and tiling in a single step, as
> well as handling multi-planar formats like NV12, which are really
> useful when dealing with hardware video decoders.
> 
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> ---
>  .../drivers/etnaviv/etnaviv_clear_blit.c      |  2 +-
>  src/gallium/drivers/etnaviv/etnaviv_format.c  |  5 +++-
>  .../drivers/etnaviv/etnaviv_resource.c        | 16 ++++++++----
>  src/gallium/drivers/etnaviv/etnaviv_rs.c      |  5 ++++
>  src/gallium/drivers/etnaviv/etnaviv_screen.c  |  5 +++-
>  src/gallium/drivers/etnaviv/etnaviv_texture.c | 25 ++++++++++++++++---
>  6 files changed, 46 insertions(+), 12 deletions(-)
> 
> diff --git a/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c b/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c
> index 45c30cbf5076..5214162d8798 100644
> --- a/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c
> +++ b/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c
> @@ -159,7 +159,7 @@ etna_copy_resource(struct pipe_context *pctx, struct pipe_resource *dst,
>     struct etna_resource *src_priv = etna_resource(src);
>     struct etna_resource *dst_priv = etna_resource(dst);
>  
> -   assert(src->format == dst->format);
> +   assert(src->format == dst->format || util_format_is_yuv(src->format));
>     assert(src->array_size == dst->array_size);
>     assert(last_level <= dst->last_level && last_level <= src->last_level);
>  
> diff --git a/src/gallium/drivers/etnaviv/etnaviv_format.c b/src/gallium/drivers/etnaviv/etnaviv_format.c
> index 29e81c4a8b04..0879ddd6a6c8 100644
> --- a/src/gallium/drivers/etnaviv/etnaviv_format.c
> +++ b/src/gallium/drivers/etnaviv/etnaviv_format.c
> @@ -282,8 +282,11 @@ static struct etna_format formats[PIPE_FORMAT_COUNT] = {
>     _T(ASTC_12x12_SRGB, ASTC_SRGB8_ALPHA8_12x12 | ASTC_FORMAT,          SWIZ(X, Y, Z, W), NONE, NONE),
>  
>     /* YUV */
> -   _T(YUYV, YUY2, SWIZ(X, Y, Z, W), YUY2, NONE),
> +   _T(YUYV, X8B8G8R8, SWIZ(X, Y, Z, W), NONE, NONE),
>     _T(UYVY, UYVY, SWIZ(X, Y, Z, W), NONE, NONE),
> +
> +   /* multi-planar YUV */
> +   _T(NV12, X8B8G8R8, SWIZ(X, Y, Z, W), NONE, NONE),
>  };
>  
>  uint32_t
> diff --git a/src/gallium/drivers/etnaviv/etnaviv_resource.c b/src/gallium/drivers/etnaviv/etnaviv_resource.c
> index 650c8e7eb7f5..5ba3eba5bd33 100644
> --- a/src/gallium/drivers/etnaviv/etnaviv_resource.c
> +++ b/src/gallium/drivers/etnaviv/etnaviv_resource.c
> @@ -560,6 +560,17 @@ etna_resource_from_handle(struct pipe_screen *pscreen,
>                                                                    level->padded_height);
>     level->size = level->layer_stride;
>  
> +   rsc->pending_ctx = _mesa_set_create(NULL, _mesa_hash_pointer,
> +                                       _mesa_key_pointer_equal);
> +   if (!rsc->pending_ctx)
> +      goto fail;
> +
> +   /* YUV resources are handled by the 2D GPU, so the below constraint checks
> +    * are invalid.
> +    */
> +   if (util_format_is_yuv(tmpl->format))
> +      return prsc;
> +
>     /* The DDX must give us a BO which conforms to our padding size.
>      * The stride of the BO must be greater or equal to our padded
>      * stride. The size of the BO must accomodate the padded height. */
> @@ -576,11 +587,6 @@ etna_resource_from_handle(struct pipe_screen *pscreen,
>        goto fail;
>     }
>  
> -   rsc->pending_ctx = _mesa_set_create(NULL, _mesa_hash_pointer,
> -                                       _mesa_key_pointer_equal);
> -   if (!rsc->pending_ctx)
> -      goto fail;
> -
>     if (rsc->layout == ETNA_LAYOUT_LINEAR) {
>        /*
>         * Both sampler and pixel pipes can't handle linear, create a compatible
> diff --git a/src/gallium/drivers/etnaviv/etnaviv_rs.c b/src/gallium/drivers/etnaviv/etnaviv_rs.c
> index fcc2342aedc3..22d07d8f9726 100644
> --- a/src/gallium/drivers/etnaviv/etnaviv_rs.c
> +++ b/src/gallium/drivers/etnaviv/etnaviv_rs.c
> @@ -26,6 +26,7 @@
>  
>  #include "etnaviv_rs.h"
>  
> +#include "etnaviv_2d.h"
>  #include "etnaviv_clear_blit.h"
>  #include "etnaviv_context.h"
>  #include "etnaviv_emit.h"
> @@ -775,6 +776,10 @@ etna_blit_rs(struct pipe_context *pctx, const struct pipe_blit_info *blit_info)
>        return;
>     }
>  
> +   if (util_format_is_yuv(blit_info->src.format) &&
> +       etna_try_2d_blit(pctx, blit_info))
> +      return;
> +
>     if (etna_try_rs_blit(pctx, blit_info))
>        return;
>  
> diff --git a/src/gallium/drivers/etnaviv/etnaviv_screen.c b/src/gallium/drivers/etnaviv/etnaviv_screen.c
> index 0dea6056c75a..b0630e27b507 100644
> --- a/src/gallium/drivers/etnaviv/etnaviv_screen.c
> +++ b/src/gallium/drivers/etnaviv/etnaviv_screen.c
> @@ -535,6 +535,9 @@ gpu_supports_texure_format(struct etna_screen *screen, uint32_t fmt,
>        supported = screen->specs.tex_astc;
>     }
>  
> +   if (util_format_is_yuv(format))
> +      supported = !!screen->gpu2d;

Isn't screen->gpu2d == NULL for devices with combined 2D/3D core?
It looks to me like this should check pipe2d, or chipFeatures_PIPE_2D.

regards
Philipp


More information about the etnaviv mailing list