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 <[email protected]> --- .../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; + if (!supported) return false; @@ -658,7 +661,7 @@ etna_screen_query_dmabuf_modifiers(struct pipe_screen *pscreen, if (modifiers) modifiers[num_modifiers] = supported_modifiers[i]; if (external_only) - external_only[num_modifiers] = util_format_is_yuv(format) ? 1 : 0; + external_only[num_modifiers] = 0; num_modifiers++; } diff --git a/src/gallium/drivers/etnaviv/etnaviv_texture.c b/src/gallium/drivers/etnaviv/etnaviv_texture.c index c4d533240547..16c3314a1df0 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_texture.c +++ b/src/gallium/drivers/etnaviv/etnaviv_texture.c @@ -164,6 +164,9 @@ etna_update_sampler_source(struct pipe_sampler_view *view, int num) static bool etna_resource_sampler_compatible(struct etna_resource *res) { + if (util_format_is_yuv(res->base.format)) + return false; + if (util_format_is_compressed(res->base.format)) return true; @@ -194,19 +197,33 @@ etna_resource_sampler_compatible(struct etna_resource *res) struct etna_resource * etna_texture_handle_incompatible(struct pipe_context *pctx, struct pipe_resource *prsc) { + struct etna_screen *screen = etna_screen(pctx->screen); struct etna_resource *res = etna_resource(prsc); + if (!etna_resource_sampler_compatible(res)) { /* The original resource is not compatible with the sampler. * Allocate an appropriately tiled texture. */ if (!res->texture) { struct pipe_resource templat = *prsc; + unsigned int layout = ETNA_LAYOUT_TILED; + enum etna_resource_addressing_mode mode = ETNA_ADDRESSING_MODE_TILED; templat.bind &= ~(PIPE_BIND_DEPTH_STENCIL | PIPE_BIND_RENDER_TARGET | PIPE_BIND_BLENDABLE); - res->texture = - etna_resource_alloc(pctx->screen, ETNA_LAYOUT_TILED, - ETNA_ADDRESSING_MODE_TILED, - DRM_FORMAT_MOD_LINEAR, &templat); + + if (util_format_is_yuv(prsc->format)) { + templat.format = PIPE_FORMAT_R8G8B8A8_UNORM; + /* If the 2D GPU does not support tiling the blit destination + prefer a linear texture to avoid a double blit when possible. */ + if (!VIV_2D_FEATURE(screen, chipMinorFeatures2, 2D_TILING) && + VIV_FEATURE(screen, chipMinorFeatures1, LINEAR_TEXTURE_SUPPORT)) { + layout = ETNA_LAYOUT_LINEAR; + mode = ETNA_ADDRESSING_MODE_LINEAR; + } + } + + res->texture = etna_resource_alloc(pctx->screen, layout, mode, + DRM_FORMAT_MOD_LINEAR, &templat); } if (!res->texture) { -- 2.20.1 _______________________________________________ mesa-dev mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-dev
