[PATCH 4/4] drm/amdgpu: fix VCE buffer placement restrictions

Alex Deucher alexdeucher at gmail.com
Fri Nov 17 15:57:32 UTC 2017


On Fri, Nov 17, 2017 at 5:12 AM, Christian König
<ckoenig.leichtzumerken at gmail.com> wrote:
> Turned out that VCE still has a placement restriction that BOs can't
> cross a 4GB boundary.
>
> Fix this by adding a command submission parser prepass to correctly
> place the buffers.
>
> Signed-off-by: Christian König <christian.koenig at amd.com>

Acked-by: Alex Deucher <alexander.deucher at amd.com>


> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c | 90 ++++++++++++++++++++++++++++++++-
>  1 file changed, 88 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
> index 92477e67087c..2843e5b728e5 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
> @@ -543,6 +543,43 @@ int amdgpu_vce_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
>         return r;
>  }
>
> +static int amdgpu_vce_validate_bo(struct amdgpu_cs_parser *p, uint32_t ib_idx,
> +                                 int lo, int hi, unsigned size, int32_t index)
> +{
> +       int64_t offset = ((uint64_t)size) * ((uint64_t)index);
> +       struct amdgpu_bo_va_mapping *mapping;
> +       unsigned i, fpfn, lpfn;
> +       struct amdgpu_bo *bo;
> +       uint64_t addr;
> +       int r;
> +
> +       addr = ((uint64_t)amdgpu_get_ib_value(p, ib_idx, lo)) |
> +              ((uint64_t)amdgpu_get_ib_value(p, ib_idx, hi)) << 32;
> +       if (index >= 0) {
> +               addr += offset;
> +               fpfn = PAGE_ALIGN(offset) >> PAGE_SHIFT;
> +               lpfn = 0x100000000ULL >> PAGE_SHIFT;
> +       } else {
> +               fpfn = 0;
> +               lpfn = (0x100000000ULL - PAGE_ALIGN(offset)) >> PAGE_SHIFT;
> +       }
> +
> +       r = amdgpu_cs_find_mapping(p, addr, &bo, &mapping);
> +       if (r) {
> +               DRM_ERROR("Can't find BO for addr 0x%010Lx %d %d %d %d\n",
> +                         addr, lo, hi, size, index);
> +               return r;
> +       }
> +
> +       for (i = 0; i < bo->placement.num_placement; ++i) {
> +               bo->placements[i].fpfn = max(bo->placements[i].fpfn, fpfn);
> +               bo->placements[i].lpfn = bo->placements[i].fpfn ?
> +                       min(bo->placements[i].fpfn, lpfn) : lpfn;
> +       }
> +       return ttm_bo_validate(&bo->tbo, &bo->placement, false, false);
> +}
> +
> +
>  /**
>   * amdgpu_vce_cs_reloc - command submission relocation
>   *
> @@ -648,12 +685,13 @@ int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx)
>         uint32_t allocated = 0;
>         uint32_t tmp, handle = 0;
>         uint32_t *size = &tmp;
> -       int i, r = 0, idx = 0;
> +       unsigned idx;
> +       int i, r = 0;
>
>         p->job->vm = NULL;
>         ib->gpu_addr = amdgpu_sa_bo_gpu_addr(ib->sa_bo);
>
> -       while (idx < ib->length_dw) {
> +       for (idx = 0; idx < ib->length_dw;) {
>                 uint32_t len = amdgpu_get_ib_value(p, ib_idx, idx);
>                 uint32_t cmd = amdgpu_get_ib_value(p, ib_idx, idx + 1);
>
> @@ -664,6 +702,54 @@ int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx)
>                 }
>
>                 switch (cmd) {
> +               case 0x00000002: /* task info */
> +                       fb_idx = amdgpu_get_ib_value(p, ib_idx, idx + 6);
> +                       bs_idx = amdgpu_get_ib_value(p, ib_idx, idx + 7);
> +                       break;
> +
> +               case 0x03000001: /* encode */
> +                       r = amdgpu_vce_validate_bo(p, ib_idx, idx + 10,
> +                                                  idx + 9, 0, 0);
> +                       if (r)
> +                               goto out;
> +
> +                       r = amdgpu_vce_validate_bo(p, ib_idx, idx + 12,
> +                                                  idx + 11, 0, 0);
> +                       if (r)
> +                               goto out;
> +                       break;
> +
> +               case 0x05000001: /* context buffer */
> +                       r = amdgpu_vce_validate_bo(p, ib_idx, idx + 3,
> +                                                  idx + 2, 0, 0);
> +                       if (r)
> +                               goto out;
> +                       break;
> +
> +               case 0x05000004: /* video bitstream buffer */
> +                       tmp = amdgpu_get_ib_value(p, ib_idx, idx + 4);
> +                       r = amdgpu_vce_validate_bo(p, ib_idx, idx + 3, idx + 2,
> +                                                  tmp, bs_idx);
> +                       if (r)
> +                               goto out;
> +                       break;
> +
> +               case 0x05000005: /* feedback buffer */
> +                       r = amdgpu_vce_validate_bo(p, ib_idx, idx + 3, idx + 2,
> +                                                  4096, fb_idx);
> +                       if (r)
> +                               goto out;
> +                       break;
> +               }
> +
> +               idx += len / 4;
> +       }
> +
> +       for (idx = 0; idx < ib->length_dw;) {
> +               uint32_t len = amdgpu_get_ib_value(p, ib_idx, idx);
> +               uint32_t cmd = amdgpu_get_ib_value(p, ib_idx, idx + 1);
> +
> +               switch (cmd) {
>                 case 0x00000001: /* session */
>                         handle = amdgpu_get_ib_value(p, ib_idx, idx + 2);
>                         session_idx = amdgpu_vce_validate_handle(p, handle,
> --
> 2.11.0
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx


More information about the amd-gfx mailing list