diff options
Diffstat (limited to 'src/gallium')
-rw-r--r-- | src/gallium/winsys/radeon/drm/radeon_drm_bo.c | 29 | ||||
-rw-r--r-- | src/gallium/winsys/radeon/drm/radeon_drm_bo.h | 1 |
2 files changed, 24 insertions, 6 deletions
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c index e4009be816c..ac37b24b6bb 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c @@ -351,14 +351,11 @@ void *radeon_bo_do_map(struct radeon_bo *bo) if (bo->user_ptr) return bo->user_ptr; - /* Return the pointer if it's already mapped. */ - if (bo->ptr) - return bo->ptr; - /* Map the buffer. */ pipe_mutex_lock(bo->map_mutex); - /* Return the pointer if it's already mapped (in case of a race). */ + /* Return the pointer if it's already mapped. */ if (bo->ptr) { + bo->map_count++; pipe_mutex_unlock(bo->map_mutex); return bo->ptr; } @@ -383,6 +380,7 @@ void *radeon_bo_do_map(struct radeon_bo *bo) return NULL; } bo->ptr = ptr; + bo->map_count = 1; pipe_mutex_unlock(bo->map_mutex); return bo->ptr; @@ -467,7 +465,26 @@ static void *radeon_bo_map(struct radeon_winsys_cs_handle *buf, static void radeon_bo_unmap(struct radeon_winsys_cs_handle *_buf) { - /* NOP */ + struct radeon_bo *bo = (struct radeon_bo*)_buf; + + if (bo->user_ptr) + return; + + pipe_mutex_lock(bo->map_mutex); + if (!bo->ptr) { + pipe_mutex_unlock(bo->map_mutex); + return; /* it's not been mapped */ + } + + assert(bo->map_count); + if (--bo->map_count) { + pipe_mutex_unlock(bo->map_mutex); + return; /* it's been mapped multiple times */ + } + + os_munmap(bo->ptr, bo->base.size); + bo->ptr = NULL; + pipe_mutex_unlock(bo->map_mutex); } static void radeon_bo_get_base_buffer(struct pb_buffer *buf, diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_bo.h b/src/gallium/winsys/radeon/drm/radeon_drm_bo.h index 0255313af7a..f8f50cc5d5b 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_bo.h +++ b/src/gallium/winsys/radeon/drm/radeon_drm_bo.h @@ -54,6 +54,7 @@ struct radeon_bo { void *ptr; pipe_mutex map_mutex; + unsigned map_count; uint32_t handle; uint32_t flink_name; |