[PATCH] drm/amdgpu: support more AV1 encoding requests
Christian König
ckoenig.leichtzumerken at gmail.com
Thu Feb 23 06:47:48 UTC 2023
Am 23.02.23 um 00:11 schrieb David (Ming Qiang) Wu:
> Ensuring accurate IB package searching and covers
> more corners for AV1 encoding requests.
That at least looks much cleaner now. Do we already have the Mesa
patches ready which use this?
Regards,
Christian.
>
> Signed-off-by: David (Ming Qiang) Wu <David.Wu3 at amd.com>
> Reviewed-by: Ruijing Dong <ruijing.dong at amd.com>
> ---
> drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c | 81 +++++++++++++++++++++++++--
> 1 file changed, 75 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c
> index 22a41766a8c7..8235ff3820ed 100644
> --- a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c
> @@ -1726,6 +1726,7 @@ static int vcn_v4_0_dec_msg(struct amdgpu_cs_parser *p, struct amdgpu_job *job,
>
> #define RADEON_VCN_ENGINE_TYPE_ENCODE (0x00000002)
> #define RADEON_VCN_ENGINE_TYPE_DECODE (0x00000003)
> +#define RADEON_VCN_ENGINE_TYPE_ENCODE_QUEUE (0x00000004)
>
> #define RADEON_VCN_ENGINE_INFO (0x30000001)
> #define RADEON_VCN_ENGINE_INFO_MAX_OFFSET 16
> @@ -1733,21 +1734,86 @@ static int vcn_v4_0_dec_msg(struct amdgpu_cs_parser *p, struct amdgpu_job *job,
> #define RENCODE_ENCODE_STANDARD_AV1 2
> #define RENCODE_IB_PARAM_SESSION_INIT 0x00000003
> #define RENCODE_IB_PARAM_SESSION_INIT_MAX_OFFSET 64
> +#define RENCODE_IB_ENC_QUE_INSTRUCTION (0x32000001)
> +#define RENCODE_IB_ENC_QUE_INSTRUCTION_MAX_OFFSET 64
>
> /* return the offset in ib if id is found, -1 otherwise
> * to speed up the searching we only search upto max_offset
> */
> -static int vcn_v4_0_enc_find_ib_param(struct amdgpu_ib *ib, uint32_t id, int max_offset)
> +static int vcn_v4_0_enc_find_ib_param(uint32_t *ptr, int size, uint32_t id, int max_offset)
> {
> int i;
>
> - for (i = 0; i < ib->length_dw && i < max_offset && ib->ptr[i] >= 8; i += ib->ptr[i]/4) {
> - if (ib->ptr[i + 1] == id)
> + for (i = 0; i < size && i < max_offset && ptr[i] >= 8; i += ptr[i] / 4) {
> + if (ptr[i + 1] == id)
> return i;
> }
> return -1;
> }
>
> +static int vcn_v4_0_enc_queue_msg(struct amdgpu_cs_parser *p,
> + struct amdgpu_job *job,
> + struct amdgpu_ib *ib)
> +{
> + struct ttm_operation_ctx ctx = { false, false };
> + struct amdgpu_bo_va_mapping *map;
> + struct amdgpu_bo *bo;
> + uint64_t start, end;
> + int i;
> + void *ptr;
> + int r;
> + int data_size = 0;
> + uint64_t addr;
> + uint32_t *msg;
> +
> + i = vcn_v4_0_enc_find_ib_param(ib->ptr, ib->length_dw, RENCODE_IB_ENC_QUE_INSTRUCTION,
> + RENCODE_IB_ENC_QUE_INSTRUCTION_MAX_OFFSET);
> + if (i >= 0) {
> + addr = ((uint64_t)ib->ptr[i + 3]) << 32 | ib->ptr[i + 2];
> + data_size = ib->ptr[i + 4];
> + }
> +
> + if (!data_size) /* did not find */
> + return 0;
> +
> + addr &= AMDGPU_GMC_HOLE_MASK;
> + r = amdgpu_cs_find_mapping(p, addr, &bo, &map);
> + if (r) {
> + DRM_ERROR("Can't find BO for addr 0x%08llx\n", addr);
> + return r;
> + }
> +
> + start = map->start * AMDGPU_GPU_PAGE_SIZE;
> + end = (map->last + 1) * AMDGPU_GPU_PAGE_SIZE;
> + if (addr & 0x7) {
> + DRM_ERROR("VCN messages must be 8 byte aligned!\n");
> + return -EINVAL;
> + }
> +
> + bo->flags |= AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
> + amdgpu_bo_placement_from_domain(bo, bo->allowed_domains);
> + r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
> + if (r) {
> + DRM_ERROR("Failed validating the VCN message BO (%d)!\n", r);
> + return r;
> + }
> +
> + r = amdgpu_bo_kmap(bo, &ptr);
> + if (r) {
> + DRM_ERROR("Failed mapping the VCN message (%d)!\n", r);
> + return r;
> + }
> +
> + msg = ptr + addr - start; /* IB with SESSION_INIT */
> + i = vcn_v4_0_enc_find_ib_param(msg, data_size, RENCODE_IB_PARAM_SESSION_INIT,
> + RENCODE_IB_PARAM_SESSION_INIT_MAX_OFFSET);
> + if (i >= 0 && msg[i + 2] == RENCODE_ENCODE_STANDARD_AV1)
> + r = vcn_v4_0_limit_sched(p, job);
> +
> + amdgpu_bo_kunmap(bo);
> + return r;
> +}
> +
> static int vcn_v4_0_ring_patch_cs_in_place(struct amdgpu_cs_parser *p,
> struct amdgpu_job *job,
> struct amdgpu_ib *ib)
> @@ -1763,12 +1829,13 @@ static int vcn_v4_0_ring_patch_cs_in_place(struct amdgpu_cs_parser *p,
> return 0;
>
> /* RADEON_VCN_ENGINE_INFO is at the top of ib block */
> - idx = vcn_v4_0_enc_find_ib_param(ib, RADEON_VCN_ENGINE_INFO,
> + idx = vcn_v4_0_enc_find_ib_param(ib->ptr, ib->length_dw, RADEON_VCN_ENGINE_INFO,
> RADEON_VCN_ENGINE_INFO_MAX_OFFSET);
> if (idx < 0) /* engine info is missing */
> return 0;
>
> val = amdgpu_ib_get_value(ib, idx + 2); /* RADEON_VCN_ENGINE_TYPE */
> +
> if (val == RADEON_VCN_ENGINE_TYPE_DECODE) {
> decode_buffer = (struct amdgpu_vcn_decode_buffer *)&ib->ptr[idx + 6];
>
> @@ -1779,10 +1846,12 @@ static int vcn_v4_0_ring_patch_cs_in_place(struct amdgpu_cs_parser *p,
> decode_buffer->msg_buffer_address_lo;
> return vcn_v4_0_dec_msg(p, job, addr);
> } else if (val == RADEON_VCN_ENGINE_TYPE_ENCODE) {
> - idx = vcn_v4_0_enc_find_ib_param(ib, RENCODE_IB_PARAM_SESSION_INIT,
> - RENCODE_IB_PARAM_SESSION_INIT_MAX_OFFSET);
> + idx = vcn_v4_0_enc_find_ib_param(ib->ptr, ib->length_dw,
> + RENCODE_IB_PARAM_SESSION_INIT, RENCODE_IB_PARAM_SESSION_INIT_MAX_OFFSET);
> if (idx >= 0 && ib->ptr[idx + 2] == RENCODE_ENCODE_STANDARD_AV1)
> return vcn_v4_0_limit_sched(p, job);
> + } else if (val == RADEON_VCN_ENGINE_TYPE_ENCODE_QUEUE) {
> + return vcn_v4_0_enc_queue_msg(p, job, ib);
> }
> return 0;
> }
More information about the amd-gfx
mailing list