radeonsi: create a new context for transcode with multiple video engines
authorLeo Liu <leo.liu@amd.com>
Thu, 13 Apr 2023 15:29:39 +0000 (11:29 -0400)
committerMarge Bot <emma+marge@anholt.net>
Mon, 17 Apr 2023 15:10:01 +0000 (15:10 +0000)
For CHIP_GFX1100, there are 2 VCN instances but using unified queue i.e.
decode and encode will go to HW via same ring type. With AMDGPU kernel
scheduler, since the trancode is sharing the same pipe context, so that
the gpu scheduler assign the decode and encode into the same VCN engine.
In order to use both engines with transcode case, the new pipe context will
be created when the case being detected, with that the transcode can be
load balanced with multiple VCN engines.

Signed-off-by: Leo Liu <leo.liu@amd.com>
Reviewed-by: Boyuan Zhang <Boyuan.Zhang@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22471>

src/gallium/drivers/radeonsi/radeon_vcn_enc.c
src/gallium/drivers/radeonsi/radeon_vcn_enc.h
src/gallium/drivers/radeonsi/si_pipe.h
src/gallium/drivers/radeonsi/si_uvd.c

index 80c4eb3..7a42948 100644 (file)
@@ -712,6 +712,9 @@ static void radeon_enc_destroy(struct pipe_video_codec *encoder)
 
    RADEON_ENC_DESTROY_VIDEO_BUFFER(enc->dpb);
    enc->ws->cs_destroy(&enc->cs);
+   if (enc->ectx)
+      enc->ectx->destroy(enc->ectx);
+
    FREE(enc);
 }
 
@@ -749,9 +752,15 @@ struct pipe_video_codec *radeon_create_encoder(struct pipe_context *context,
    if (!enc)
       return NULL;
 
+   if (sctx->vcn_has_ctx) {
+      enc->ectx = pipe_create_multimedia_context(context->screen);
+      if (!enc->ectx)
+         sctx->vcn_has_ctx = false;
+   }
+
    enc->alignment = 256;
    enc->base = *templ;
-   enc->base.context = context;
+   enc->base.context = (sctx->vcn_has_ctx)? enc->ectx : context;
    enc->base.destroy = radeon_enc_destroy;
    enc->base.begin_frame = radeon_enc_begin_frame;
    enc->base.encode_bitstream = radeon_enc_encode_bitstream;
@@ -763,7 +772,9 @@ struct pipe_video_codec *radeon_create_encoder(struct pipe_context *context,
    enc->screen = context->screen;
    enc->ws = ws;
 
-   if (!ws->cs_create(&enc->cs, sctx->ctx, AMD_IP_VCN_ENC, radeon_enc_cs_flush, enc, false)) {
+   if (!ws->cs_create(&enc->cs,
+       (sctx->vcn_has_ctx) ? ((struct si_context *)enc->ectx)->ctx : sctx->ctx,
+       AMD_IP_VCN_ENC, radeon_enc_cs_flush, enc, false)) {
       RVID_ERR("Can't get command submission context.\n");
       goto error;
    }
index 6853862..6d1ce80 100644 (file)
@@ -696,6 +696,8 @@ struct radeon_encoder {
    unsigned dpb_size;
    rvcn_enc_picture_info_t dpb_info[RENCODE_MAX_NUM_RECONSTRUCTED_PICTURES];
    unsigned max_ltr_idx;
+
+   struct pipe_context *ectx;
 };
 
 void radeon_enc_add_buffer(struct radeon_encoder *enc, struct pb_buffer *buf,
index 0bc0cd0..282135b 100644 (file)
@@ -1074,6 +1074,9 @@ struct si_context {
    /* if current tcs set by user */
    bool is_user_tcs;
 
+   /* video context */
+   bool vcn_has_ctx;
+
    /* shader information */
    uint64_t ps_inputs_read_or_disabled;
    struct si_vertex_elements *vertex_elements;
index 2a3ccf3..80c9374 100644 (file)
@@ -135,6 +135,9 @@ struct pipe_video_codec *si_uvd_create_decoder(struct pipe_context *context,
       }
    }
 
+   if (ctx->family == CHIP_GFX1100)
+      ctx->vcn_has_ctx = true;
+
    return (vcn) ? radeon_create_decoder(context, templ)
                 : si_common_uvd_create_decoder(context, templ, si_uvd_set_dtb);
 }