Patches 3-8: Reviewed-by: Marek Olšák <marek.ol...@amd.com>
Marek On Tue, Jan 12, 2016 at 5:06 PM, Nicolai Hähnle <nhaeh...@gmail.com> wrote: > From: Nicolai Hähnle <nicolai.haeh...@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@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev