[PATCH 4/8] etnaviv: add 2D GPU YUV->RGB blitter
Philipp Zabel
p.zabel at pengutronix.de
Mon Apr 15 10:54:42 UTC 2019
On Fri, 2019-04-12 at 19:38 +0200, Lucas Stach wrote:
> This adds a blit path using the 2D GPU for a linear YUV to tiled RGB
> blit. This allows to implement importing of planar YUV textures with
> a single copy.
>
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> ---
> src/gallium/drivers/etnaviv/Makefile.sources | 2 +
> src/gallium/drivers/etnaviv/etnaviv_2d.c | 164 ++
> src/gallium/drivers/etnaviv/etnaviv_2d.h | 37 +
> src/gallium/drivers/etnaviv/hw/state_2d.xml.h | 1499 +++++++++++++++++
> src/gallium/drivers/etnaviv/meson.build | 3 +
> 5 files changed, 1705 insertions(+)
> create mode 100644 src/gallium/drivers/etnaviv/etnaviv_2d.c
> create mode 100644 src/gallium/drivers/etnaviv/etnaviv_2d.h
> create mode 100644 src/gallium/drivers/etnaviv/hw/state_2d.xml.h
>
> diff --git a/src/gallium/drivers/etnaviv/Makefile.sources b/src/gallium/drivers/etnaviv/Makefile.sources
> index 01e7e49a38ad..36dd7d1b6aa4 100644
> --- a/src/gallium/drivers/etnaviv/Makefile.sources
> +++ b/src/gallium/drivers/etnaviv/Makefile.sources
> @@ -3,11 +3,13 @@ C_SOURCES := \
> hw/common.xml.h \
> hw/common_3d.xml.h \
> hw/isa.xml.h \
> + hw/state_2d.xml.h \
> hw/state_3d.xml.h \
> hw/state_blt.xml.h \
> hw/state.xml.h \
> hw/texdesc_3d.xml.h \
> \
> + etnaviv_2d.c \
> etnaviv_asm.c \
> etnaviv_asm.h \
> etnaviv_blend.c \
> diff --git a/src/gallium/drivers/etnaviv/etnaviv_2d.c b/src/gallium/drivers/etnaviv/etnaviv_2d.c
> new file mode 100644
> index 000000000000..457fa4e0cbd0
> --- /dev/null
> +++ b/src/gallium/drivers/etnaviv/etnaviv_2d.c
> @@ -0,0 +1,164 @@
> +/*
> + * Copyright (c) 2018 Etnaviv Project
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sub license,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the
> + * next paragraph) shall be included in all copies or substantial portions
> + * of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> + * DEALINGS IN THE SOFTWARE.
> + */
> +
> +#include "etnaviv_2d.h"
> +#include "etnaviv_context.h"
> +#include "etnaviv_emit.h"
> +#include "etnaviv_screen.h"
> +
> +#include "pipe/p_state.h"
> +#include "util/u_format.h"
> +
> +#include "hw/state_2d.xml.h"
> +
> +#include <assert.h>
> +
> +#define EMIT_STATE(state_name, src_value) \
> + etna_coalsence_emit(stream, &coalesce, VIVS_##state_name, src_value)
> +
> +#define EMIT_STATE_RELOC(state_name, src_value) \
> + etna_coalsence_emit_reloc(stream, &coalesce, VIVS_##state_name, src_value)
> +
> +bool etna_try_2d_blit(struct pipe_context *pctx,
> + const struct pipe_blit_info *blit_info)
> +{
> + struct etna_context *ctx = etna_context(pctx);
> + struct etna_cmd_stream *stream = ctx->stream2d;
> + struct etna_coalesce coalesce;
> + struct etna_reloc ry, ru, rv, rdst;
> + struct pipe_resource *res_y, *res_u, *res_v, *res_dst;
> + uint32_t src_format;
> +
> + assert(util_format_is_yuv(blit_info->src.format));
> + assert(blit_info->dst.format == PIPE_FORMAT_R8G8B8A8_UNORM);
> +
> + if (!stream)
> + return FALSE;
> +
> + switch (blit_info->src.format) {
> + case PIPE_FORMAT_NV12:
> + src_format = DE_FORMAT_NV12;
> + break;
> + case PIPE_FORMAT_YUYV:
> + src_format = DE_FORMAT_YUY2;
> + break;
> + default:
> + return FALSE;
> + }
> +
> + res_y = blit_info->src.resource;
> + res_u = res_y->next ? res_y->next : res_y;
> + res_v = res_u->next ? res_u->next : res_u;
> +
> + ry.bo = etna_resource(res_y)->bo;
> + ry.offset = etna_resource(res_y)->levels[blit_info->src.level].offset;
> + ru.bo = etna_resource(res_u)->bo;
> + ru.offset = etna_resource(res_u)->levels[blit_info->src.level].offset;
> + rv.bo = etna_resource(res_v)->bo;
> + rv.offset = etna_resource(res_v)->levels[blit_info->src.level].offset;
> +
> + ry.flags = ru.flags = rv.flags = ETNA_RELOC_READ;
> +
> + res_dst = blit_info->dst.resource;
> + rdst.bo = etna_resource(res_dst)->bo;
> + rdst.flags = ETNA_RELOC_WRITE;
> + rdst.offset = 0;
> +
> + etna_coalesce_start(stream, &coalesce);
> +
> + EMIT_STATE_RELOC(DE_SRC_ADDRESS, &ry);
> + EMIT_STATE(DE_SRC_STRIDE, etna_resource(res_y)->levels[0].stride);
> +
> + EMIT_STATE_RELOC(DE_UPLANE_ADDRESS, &ru);
> + EMIT_STATE(DE_UPLANE_STRIDE, etna_resource(res_u)->levels[0].stride);
> + EMIT_STATE_RELOC(DE_VPLANE_ADDRESS, &rv);
> + EMIT_STATE(DE_VPLANE_STRIDE, etna_resource(res_v)->levels[0].stride);
> +
> + /* Source configuration */
> + EMIT_STATE(DE_SRC_ROTATION_CONFIG, 0);
> + EMIT_STATE(DE_SRC_CONFIG,
> + VIVS_DE_SRC_CONFIG_SOURCE_FORMAT(src_format) |
> + VIVS_DE_SRC_CONFIG_SWIZZLE(DE_SWIZZLE_ARGB));
> + EMIT_STATE(DE_SRC_ORIGIN, 0);
> + EMIT_STATE(DE_SRC_SIZE, 0);
> + EMIT_STATE(DE_SRC_COLOR_BG, 0);
> + EMIT_STATE(DE_SRC_COLOR_FG, 0);
> + EMIT_STATE(DE_STRETCH_FACTOR_LOW,
> + VIVS_DE_STRETCH_FACTOR_LOW_X(1 << 16));
> + EMIT_STATE(DE_STRETCH_FACTOR_HIGH,
> + VIVS_DE_STRETCH_FACTOR_HIGH_Y(1 << 16));
> +
> + /* Destination address and stride */
> + EMIT_STATE_RELOC(DE_DEST_ADDRESS, &rdst);
> + EMIT_STATE(DE_DEST_STRIDE, etna_resource(res_dst)->levels[0].stride);
> +
> + /* Drawing engine configuration */
> + EMIT_STATE(DE_DEST_ROTATION_CONFIG, 0);
> + EMIT_STATE(DE_DEST_CONFIG,
> + VIVS_DE_DEST_CONFIG_FORMAT(DE_FORMAT_A8R8G8B8) |
> + VIVS_DE_DEST_CONFIG_COMMAND_BIT_BLT |
> + VIVS_DE_DEST_CONFIG_SWIZZLE(DE_SWIZZLE_ABGR) |
> + VIVS_DE_DEST_CONFIG_TILED_ENABLE);
> + EMIT_STATE(DE_ROP,
> + VIVS_DE_ROP_ROP_FG(0xcc) | VIVS_DE_ROP_ROP_BG(0xcc) |
> + VIVS_DE_ROP_TYPE_ROP4);
> + EMIT_STATE(DE_CLIP_TOP_LEFT,
> + VIVS_DE_CLIP_TOP_LEFT_X(0) |
> + VIVS_DE_CLIP_TOP_LEFT_Y(0));
> + EMIT_STATE(DE_CLIP_BOTTOM_RIGHT,
> + VIVS_DE_CLIP_BOTTOM_RIGHT_X(blit_info->dst.box.width) |
> + VIVS_DE_CLIP_BOTTOM_RIGHT_Y(blit_info->dst.box.height));
> + EMIT_STATE(DE_CONFIG, 0);
> + EMIT_STATE(DE_SRC_ORIGIN_FRACTION, 0);
> + EMIT_STATE(DE_ALPHA_CONTROL, 0);
> + EMIT_STATE(DE_ALPHA_MODES, 0);
> + EMIT_STATE(DE_DEST_ROTATION_HEIGHT, 0);
> + EMIT_STATE(DE_SRC_ROTATION_HEIGHT, 0);
> + EMIT_STATE(DE_ROT_ANGLE, 0);
> +
> + etna_coalesce_end(stream, &coalesce);
> +
> + etna_cmd_stream_emit(stream, VIV_FE_DRAW_2D_HEADER_OP_DRAW_2D |
> + VIV_FE_DRAW_2D_HEADER_COUNT(1));
> + etna_cmd_stream_emit(stream, 0xdeadbeef);
> +
> + etna_cmd_stream_emit(stream, VIV_FE_DRAW_2D_TOP_LEFT_X(0) |
> + VIV_FE_DRAW_2D_TOP_LEFT_Y(0));
> + etna_cmd_stream_emit(stream,
> + VIV_FE_DRAW_2D_BOTTOM_RIGHT_X(blit_info->dst.box.width) |
> + VIV_FE_DRAW_2D_BOTTOM_RIGHT_Y(blit_info->dst.box.height));
> +
> + etna_set_state(stream, 1, 0);
> + etna_set_state(stream, 1, 0);
> + etna_set_state(stream, 1, 0);
> +
> + etna_set_state(stream, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_PE2D);
> +
> + /* Flush now, this avoid the need to track cross-dependencies between
> + * 2D and 3D GPU. The 3D GPU will only read from the 2D prepared buffers,
> + * so the kernel is taking care of any needed synchronization.
> + */
> + etna_cmd_stream_flush(ctx->stream2d);
This could be:
etna_cmd_stream_flush(stream);
regards
Philipp
More information about the etnaviv
mailing list