mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 09:08:10 +02:00
radeonsi/vcn: Don't reuse context with multiple VCN instances
Kernel does VCN instance scheduling per context, so when we have multiple instances we should use new context to be able to utilize all of them. Another issue is with AV1, VCN 3 and VCN 4 only support AV1 on first instance. Kernel parses IBs and switches to first instance when it detects AV1, but this only works for first submitted IB in context. The CS would be rejected if we first decode/encode other codecs, kernel schedules on second instance (default) and then we try to decode/encode AV1. Cc: mesa-stable Reviewed-by: Leo Liu <leo.liu@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31249>
This commit is contained in:
parent
cf536f63d1
commit
712e49f137
3 changed files with 40 additions and 8 deletions
|
|
@ -2414,6 +2414,8 @@ static void radeon_dec_destroy(struct pipe_video_codec *decoder)
|
|||
|
||||
dec->ws->fence_reference(dec->ws, &dec->prev_fence, NULL);
|
||||
dec->ws->cs_destroy(&dec->cs);
|
||||
if (dec->ectx)
|
||||
dec->ectx->destroy(dec->ectx);
|
||||
|
||||
if (dec->stream_type == RDECODE_CODEC_JPEG) {
|
||||
for (i = 0; i < dec->njctx; i++) {
|
||||
|
|
@ -2762,8 +2764,14 @@ struct pipe_video_codec *radeon_create_decoder(struct pipe_context *context,
|
|||
if (!dec)
|
||||
return NULL;
|
||||
|
||||
if (sctx->vcn_has_ctx) {
|
||||
dec->ectx = pipe_create_multimedia_context(context->screen);
|
||||
if (!dec->ectx)
|
||||
sctx->vcn_has_ctx = false;
|
||||
}
|
||||
|
||||
dec->base = *templ;
|
||||
dec->base.context = context;
|
||||
dec->base.context = (sctx->vcn_has_ctx) ? dec->ectx : context;
|
||||
dec->base.width = width;
|
||||
dec->base.height = height;
|
||||
dec->max_width = width;
|
||||
|
|
@ -2792,7 +2800,9 @@ struct pipe_video_codec *radeon_create_decoder(struct pipe_context *context,
|
|||
dec->sq.ib_total_size_in_dw = NULL;
|
||||
dec->sq.ib_checksum = NULL;
|
||||
|
||||
if (!ws->cs_create(&dec->cs, sctx->ctx, ring, NULL, NULL)) {
|
||||
if (!ws->cs_create(&dec->cs,
|
||||
(sctx->vcn_has_ctx) ? ((struct si_context *)dec->ectx)->ctx : sctx->ctx,
|
||||
ring, NULL, NULL)) {
|
||||
RVID_ERR("Can't get command submission context.\n");
|
||||
goto error;
|
||||
}
|
||||
|
|
@ -3056,6 +3066,8 @@ struct pipe_video_codec *radeon_create_decoder(struct pipe_context *context,
|
|||
|
||||
error:
|
||||
dec->ws->cs_destroy(&dec->cs);
|
||||
if (dec->ectx)
|
||||
dec->ectx->destroy(dec->ectx);
|
||||
|
||||
if (dec->stream_type == RDECODE_CODEC_JPEG) {
|
||||
for (i = 0; i < dec->njctx; i++) {
|
||||
|
|
|
|||
|
|
@ -140,6 +140,8 @@ struct radeon_decoder {
|
|||
struct pipe_fence_handle *destroy_fence;
|
||||
bool dpb_use_surf;
|
||||
uint64_t dpb_modifier;
|
||||
|
||||
struct pipe_context *ectx;
|
||||
};
|
||||
|
||||
void send_cmd_dec(struct radeon_decoder *dec, struct pipe_video_buffer *target,
|
||||
|
|
|
|||
|
|
@ -97,6 +97,20 @@ static void si_vce_get_buffer(struct pipe_resource *resource, struct pb_buffer_l
|
|||
*surface = &res->surface;
|
||||
}
|
||||
|
||||
static bool si_vcn_need_context(struct si_context *ctx)
|
||||
{
|
||||
/* Kernel does VCN instance scheduling per context, so when we have
|
||||
* multiple instances we should use new context to be able to utilize
|
||||
* all of them.
|
||||
* Another issue is with AV1, VCN 3 and VCN 4 only support AV1 on
|
||||
* first instance. Kernel parses IBs and switches to first instance when
|
||||
* it detects AV1, but this only works for first submitted IB in context.
|
||||
* The CS would be rejected if we first decode/encode other codecs, kernel
|
||||
* schedules on second instance (default) and then we try to decode/encode AV1.
|
||||
*/
|
||||
return ctx->screen->info.ip[AMD_IP_VCN_ENC].num_instances > 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* creates an UVD compatible decoder
|
||||
*/
|
||||
|
|
@ -105,10 +119,13 @@ struct pipe_video_codec *si_uvd_create_decoder(struct pipe_context *context,
|
|||
{
|
||||
struct si_context *ctx = (struct si_context *)context;
|
||||
bool vcn = ctx->vcn_ip_ver >= VCN_1_0_0;
|
||||
struct pipe_video_codec *codec = NULL;
|
||||
|
||||
if (templ->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) {
|
||||
if (vcn) {
|
||||
return radeon_create_encoder(context, templ, ctx->ws, si_vce_get_buffer);
|
||||
codec = radeon_create_encoder(context, templ, ctx->ws, si_vce_get_buffer);
|
||||
ctx->vcn_has_ctx = si_vcn_need_context(ctx);
|
||||
return codec;
|
||||
} else {
|
||||
if (u_reduce_video_profile(templ->profile) == PIPE_VIDEO_FORMAT_HEVC)
|
||||
return radeon_uvd_create_encoder(context, templ, ctx->ws, si_vce_get_buffer);
|
||||
|
|
@ -119,9 +136,10 @@ struct pipe_video_codec *si_uvd_create_decoder(struct pipe_context *context,
|
|||
templ->entrypoint == PIPE_VIDEO_ENTRYPOINT_PROCESSING)
|
||||
return si_vpe_create_processor(context, templ);
|
||||
|
||||
if (ctx->vcn_ip_ver == VCN_4_0_0)
|
||||
ctx->vcn_has_ctx = true;
|
||||
|
||||
return (vcn) ? radeon_create_decoder(context, templ)
|
||||
: si_common_uvd_create_decoder(context, templ, si_uvd_set_dtb);
|
||||
if (vcn) {
|
||||
codec = radeon_create_decoder(context, templ);
|
||||
ctx->vcn_has_ctx = si_vcn_need_context(ctx);
|
||||
return codec;
|
||||
}
|
||||
return si_common_uvd_create_decoder(context, templ, si_uvd_set_dtb);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue