[Mesa-dev] [PATCH 8/8] gallium/radeon: do not reallocate user memory buffers

Marek Olšák maraeo at gmail.com
Wed Jan 13 08:45:25 PST 2016


Patches 3-8:

Reviewed-by: Marek Olšák <marek.olsak at amd.com>

Marek

On Tue, Jan 12, 2016 at 5:06 PM, Nicolai Hähnle <nhaehnle at gmail.com> wrote:
> From: Nicolai Hähnle <nicolai.haehnle at amd.com>
>
> The whole point of AMD_pinned_memory is that applications don't have to map
> buffers via OpenGL - but they're still allowed to, so make sure we don't break
> the link between buffer object and user memory unless explicitly instructed
> to.
> ---
>  src/gallium/drivers/radeon/r600_buffer_common.c | 31 ++++++++++++++++++-------
>  src/gallium/drivers/radeon/radeon_winsys.h      |  8 +++++++
>  src/gallium/winsys/amdgpu/drm/amdgpu_bo.c       |  6 +++++
>  src/gallium/winsys/radeon/drm/radeon_drm_bo.c   |  6 +++++
>  4 files changed, 43 insertions(+), 8 deletions(-)
>
> diff --git a/src/gallium/drivers/radeon/r600_buffer_common.c b/src/gallium/drivers/radeon/r600_buffer_common.c
> index 09755e0..6592c5b 100644
> --- a/src/gallium/drivers/radeon/r600_buffer_common.c
> +++ b/src/gallium/drivers/radeon/r600_buffer_common.c
> @@ -209,11 +209,15 @@ static void r600_buffer_destroy(struct pipe_screen *screen,
>         FREE(rbuffer);
>  }
>
> -void r600_invalidate_resource(struct pipe_context *ctx,
> -                             struct pipe_resource *resource)
> +static bool
> +r600_do_invalidate_resource(struct r600_common_context *rctx,
> +                           struct r600_resource *rbuffer)
>  {
> -       struct r600_common_context *rctx = (struct r600_common_context*)ctx;
> -        struct r600_resource *rbuffer = r600_resource(resource);
> +       /* In AMD_pinned_memory, the user pointer association only gets
> +        * broken when the buffer is explicitly re-allocated.
> +        */
> +       if (rctx->ws->buffer_is_user_ptr(rbuffer->buf))
> +               return false;
>
>         /* Check if mapping this buffer would cause waiting for the GPU. */
>         if (r600_rings_is_buffer_referenced(rctx, rbuffer->buf, RADEON_USAGE_READWRITE) ||
> @@ -222,6 +226,17 @@ void r600_invalidate_resource(struct pipe_context *ctx,
>         } else {
>                 util_range_set_empty(&rbuffer->valid_buffer_range);
>         }
> +
> +       return true;
> +}
> +
> +void r600_invalidate_resource(struct pipe_context *ctx,
> +                             struct pipe_resource *resource)
> +{
> +       struct r600_common_context *rctx = (struct r600_common_context*)ctx;
> +       struct r600_resource *rbuffer = r600_resource(resource);
> +
> +       (void)r600_do_invalidate_resource(rctx, rbuffer);
>  }
>
>  static void *r600_buffer_get_transfer(struct pipe_context *ctx,
> @@ -291,10 +306,10 @@ static void *r600_buffer_transfer_map(struct pipe_context *ctx,
>             !(usage & PIPE_TRANSFER_UNSYNCHRONIZED)) {
>                 assert(usage & PIPE_TRANSFER_WRITE);
>
> -               r600_invalidate_resource(ctx, resource);
> -
> -               /* At this point, the buffer is always idle. */
> -               usage |= PIPE_TRANSFER_UNSYNCHRONIZED;
> +               if (r600_do_invalidate_resource(rctx, rbuffer)) {
> +                       /* At this point, the buffer is always idle. */
> +                       usage |= PIPE_TRANSFER_UNSYNCHRONIZED;
> +               }
>         }
>         else if ((usage & PIPE_TRANSFER_DISCARD_RANGE) &&
>                  !(usage & PIPE_TRANSFER_UNSYNCHRONIZED) &&
> diff --git a/src/gallium/drivers/radeon/radeon_winsys.h b/src/gallium/drivers/radeon/radeon_winsys.h
> index 4af6a18..ad30474 100644
> --- a/src/gallium/drivers/radeon/radeon_winsys.h
> +++ b/src/gallium/drivers/radeon/radeon_winsys.h
> @@ -530,6 +530,14 @@ struct radeon_winsys {
>                                           void *pointer, unsigned size);
>
>      /**
> +     * Whether the buffer was created from a user pointer.
> +     *
> +     * \param buf       A winsys buffer object
> +     * \return          whether \p buf was created via buffer_from_ptr
> +     */
> +    bool (*buffer_is_user_ptr)(struct pb_buffer *buf);
> +
> +    /**
>       * Get a winsys handle from a winsys buffer. The internal structure
>       * of the handle is platform-specific and only a winsys should access it.
>       *
> diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c b/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c
> index a844773..82c803b 100644
> --- a/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c
> +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c
> @@ -686,6 +686,11 @@ error:
>      return NULL;
>  }
>
> +static bool amdgpu_bo_is_user_ptr(struct pb_buffer *buf)
> +{
> +   return ((struct amdgpu_winsys_bo*)buf)->user_ptr != NULL;
> +}
> +
>  static uint64_t amdgpu_bo_get_va(struct pb_buffer *buf)
>  {
>     return ((struct amdgpu_winsys_bo*)buf)->va;
> @@ -701,6 +706,7 @@ void amdgpu_bo_init_functions(struct amdgpu_winsys *ws)
>     ws->base.buffer_create = amdgpu_bo_create;
>     ws->base.buffer_from_handle = amdgpu_bo_from_handle;
>     ws->base.buffer_from_ptr = amdgpu_bo_from_ptr;
> +   ws->base.buffer_is_user_ptr = amdgpu_bo_is_user_ptr;
>     ws->base.buffer_get_handle = amdgpu_bo_get_handle;
>     ws->base.buffer_get_virtual_address = amdgpu_bo_get_va;
>     ws->base.buffer_get_initial_domain = amdgpu_bo_get_initial_domain;
> diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
> index ee61e54..2196b7b 100644
> --- a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
> +++ b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
> @@ -1052,6 +1052,11 @@ static boolean radeon_winsys_bo_get_handle(struct pb_buffer *buffer,
>      return TRUE;
>  }
>
> +static bool radeon_winsys_bo_is_user_ptr(struct pb_buffer *buf)
> +{
> +   return ((struct radeon_bo*)buf)->user_ptr != NULL;
> +}
> +
>  static uint64_t radeon_winsys_bo_va(struct pb_buffer *buf)
>  {
>      return ((struct radeon_bo*)buf)->va;
> @@ -1067,6 +1072,7 @@ void radeon_drm_bo_init_functions(struct radeon_drm_winsys *ws)
>      ws->base.buffer_create = radeon_winsys_bo_create;
>      ws->base.buffer_from_handle = radeon_winsys_bo_from_handle;
>      ws->base.buffer_from_ptr = radeon_winsys_bo_from_ptr;
> +    ws->base.buffer_is_user_ptr = radeon_winsys_bo_is_user_ptr;
>      ws->base.buffer_get_handle = radeon_winsys_bo_get_handle;
>      ws->base.buffer_get_virtual_address = radeon_winsys_bo_va;
>      ws->base.buffer_get_initial_domain = radeon_bo_get_initial_domain;
> --
> 2.5.0
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list