Add an accelerated buffer copy cleanup helper.

Export helper functions and make some important buffer-object functions non-static.
Add an i915 accelerated blit buffer move for pci memory buffers.
main
Thomas Hellstrom 2007-02-08 21:28:33 +01:00
parent a0ed808d05
commit b2bcbf874b
4 changed files with 177 additions and 54 deletions

View File

@ -1509,6 +1509,15 @@ extern int drm_fence_buffer_objects(drm_file_t * priv,
uint32_t fence_flags,
drm_fence_object_t *fence,
drm_fence_object_t **used_fence);
extern void drm_bo_add_to_lru(drm_buffer_object_t * bo,
drm_buffer_manager_t * bm);
extern int drm_bo_wait(drm_buffer_object_t * bo, int lazy, int ignore_signals,
int no_wait);
extern int drm_bo_mem_space(drm_device_t *dev,
drm_bo_mem_reg_t *mem,
int no_wait);
/*
* Buffer object memory move helpers.
* drm_bo_move.c
@ -1522,6 +1531,13 @@ extern int drm_bo_move_memcpy(drm_buffer_object_t *bo,
int evict,
int no_wait,
drm_bo_mem_reg_t *new_mem);
extern int drm_bo_move_accel_cleanup(drm_buffer_object_t *bo,
int evict,
int no_wait,
uint32_t fence_type,
uint32_t fence_flags,
drm_bo_mem_reg_t *new_mem);
extern void drm_core_ioremap(struct drm_map *map, struct drm_device *dev);
extern void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev);

View File

@ -56,8 +56,6 @@ static void drm_bo_destroy_locked(drm_buffer_object_t *bo);
static int drm_bo_setup_vm_locked(drm_buffer_object_t *bo);
static void drm_bo_takedown_vm_locked(drm_buffer_object_t *bo);
static void drm_bo_unmap_virtual(drm_buffer_object_t *bo);
static int drm_bo_mem_space(drm_device_t *dev, drm_bo_mem_reg_t *mem,
int no_wait);
static inline uint32_t drm_bo_type_flags(unsigned type)
{
@ -68,8 +66,8 @@ static inline uint32_t drm_bo_type_flags(unsigned type)
* bo locked. dev->struct_mutex locked.
*/
static void drm_bo_add_to_lru(drm_buffer_object_t * bo,
drm_buffer_manager_t * bm)
void drm_bo_add_to_lru(drm_buffer_object_t * bo,
drm_buffer_manager_t * bm)
{
struct list_head *list;
drm_mem_type_manager_t *man;
@ -206,8 +204,8 @@ static int drm_bo_handle_move_mem(drm_buffer_object_t *bo,
* Wait until the buffer is idle.
*/
static int drm_bo_wait(drm_buffer_object_t * bo, int lazy, int ignore_signals,
int no_wait)
int drm_bo_wait(drm_buffer_object_t * bo, int lazy, int ignore_signals,
int no_wait)
{
drm_fence_object_t *fence = bo->fence;
@ -697,9 +695,9 @@ static int drm_bo_mt_compatible(drm_mem_type_manager_t *man,
}
static int drm_bo_mem_space(drm_device_t *dev,
drm_bo_mem_reg_t *mem,
int no_wait)
int drm_bo_mem_space(drm_device_t *dev,
drm_bo_mem_reg_t *mem,
int no_wait)
{
drm_buffer_manager_t *bm= &dev->bm;
drm_mem_type_manager_t *man;
@ -777,6 +775,8 @@ static int drm_bo_mem_space(drm_device_t *dev,
ret = (has_eagain) ? -EAGAIN : -ENOMEM;
return ret;
}
EXPORT_SYMBOL(drm_bo_mem_space);
static int drm_bo_new_mask(drm_buffer_object_t *bo,
uint32_t new_mask, uint32_t hint)
@ -1439,50 +1439,6 @@ static int drm_bo_handle_wait(drm_file_t * priv, uint32_t handle,
return ret;
}
/*
* Transfer a buffer object's memory and LRU status to a newly
* created object. User-space references remains with the old
* object. Call bo->mutex locked.
*/
int drm_buffer_object_transfer(drm_buffer_object_t *bo,
drm_buffer_object_t **new_obj)
{
drm_buffer_object_t *fbo;
drm_device_t *dev = bo->dev;
drm_buffer_manager_t *bm = &dev->bm;
fbo = drm_ctl_calloc(1, sizeof(*bo), DRM_MEM_BUFOBJ);
if (!fbo)
return -ENOMEM;
*fbo = *bo;
mutex_init(&fbo->mutex);
mutex_lock(&fbo->mutex);
mutex_lock(&dev->struct_mutex);
INIT_LIST_HEAD(&fbo->ddestroy);
INIT_LIST_HEAD(&fbo->lru);
list_splice_init(&bo->lru, &fbo->lru);
bo->mem.mm_node = NULL;
bo->ttm = NULL;
bo->fence = NULL;
bo->mem.flags = 0;
fbo->mem.mm_node->private = (void *)fbo;
atomic_set(&fbo->usage, 1);
atomic_inc(&bm->count);
mutex_unlock(&dev->struct_mutex);
mutex_unlock(&fbo->mutex);
*new_obj = fbo;
return 0;
}
int drm_buffer_object_create(drm_file_t * priv,
unsigned long size,
drm_bo_type_t type,

View File

@ -73,6 +73,7 @@ int drm_bo_move_ttm(drm_buffer_object_t *bo,
DRM_FLAG_MASKED(save_flags, new_mem->flags, DRM_BO_MASK_MEMTYPE);
return 0;
}
EXPORT_SYMBOL(drm_bo_move_ttm);
/**
@ -267,3 +268,121 @@ out:
drm_mem_reg_iounmap(dev, &old_copy, old_iomap);
return ret;
}
EXPORT_SYMBOL(drm_bo_move_memcpy);
/*
* Transfer a buffer object's memory and LRU status to a newly
* created object. User-space references remains with the old
* object. Call bo->mutex locked.
*/
int drm_buffer_object_transfer(drm_buffer_object_t *bo,
drm_buffer_object_t **new_obj)
{
drm_buffer_object_t *fbo;
drm_device_t *dev = bo->dev;
drm_buffer_manager_t *bm = &dev->bm;
fbo = drm_ctl_calloc(1, sizeof(*bo), DRM_MEM_BUFOBJ);
if (!fbo)
return -ENOMEM;
*fbo = *bo;
mutex_init(&fbo->mutex);
mutex_lock(&fbo->mutex);
mutex_lock(&dev->struct_mutex);
INIT_LIST_HEAD(&fbo->ddestroy);
INIT_LIST_HEAD(&fbo->lru);
bo->mem.mm_node = NULL;
bo->ttm = NULL;
atomic_inc(&bo->fence->usage);
bo->mem.flags = 0;
fbo->mem.mm_node->private = (void *)fbo;
atomic_set(&fbo->usage, 1);
atomic_inc(&bm->count);
mutex_unlock(&dev->struct_mutex);
mutex_unlock(&fbo->mutex);
*new_obj = fbo;
return 0;
}
int drm_bo_move_accel_cleanup(drm_buffer_object_t *bo,
int evict,
int no_wait,
uint32_t fence_type,
uint32_t fence_flags,
drm_bo_mem_reg_t *new_mem)
{
drm_device_t *dev = bo->dev;
drm_mem_type_manager_t *man = &dev->bm.man[new_mem->mem_type];
drm_bo_mem_reg_t *old_mem = &bo->mem;
int ret;
uint32_t save_flags = old_mem->flags;
uint32_t save_mask = old_mem->mask;
drm_buffer_object_t *old_obj;
if (bo->fence)
drm_fence_usage_deref_unlocked(dev, bo->fence);
ret = drm_fence_object_create(dev, fence_type,
fence_flags | DRM_FENCE_FLAG_EMIT,
&bo->fence);
if (ret)
return ret;
if (evict) {
ret = drm_bo_wait(bo, 0, 1, 0);
if (ret)
return ret;
if (old_mem->mm_node) {
mutex_lock(&dev->struct_mutex);
drm_mm_put_block(old_mem->mm_node);
old_mem->mm_node = NULL;
mutex_unlock(&dev->struct_mutex);
}
if ((man->flags & _DRM_FLAG_MEMTYPE_FIXED) &&
(bo->ttm != NULL)) {
drm_ttm_unbind(bo->ttm);
drm_destroy_ttm(bo->ttm);
bo->ttm = NULL;
}
} else {
/* This should help pipeline ordinary buffer moves.
*
* Hang old buffer memory on a new buffer object,
* and leave it to be released when the blit
* operation has completed.
*/
ret = drm_buffer_object_transfer(bo, &old_obj);
if (ret)
return ret;
if (!(man->flags & _DRM_FLAG_MEMTYPE_FIXED))
old_obj->ttm = NULL;
else
bo->ttm = NULL;
atomic_inc(&old_obj->fence->usage);
mutex_lock(&dev->struct_mutex);
list_del(&old_obj->lru);
drm_bo_add_to_lru(old_obj, &old_obj->dev->bm);
drm_bo_usage_deref_locked(old_obj);
mutex_unlock(&dev->struct_mutex);
}
*old_mem = *new_mem;
new_mem->mm_node = NULL;
old_mem->mask = save_mask;
DRM_FLAG_MASKED(save_flags, new_mem->flags, DRM_BO_MASK_MEMTYPE);
return 0;
}
EXPORT_SYMBOL(drm_bo_move_accel_cleanup);

View File

@ -118,7 +118,7 @@ uint32_t i915_evict_flags(drm_device_t *dev, uint32_t type)
}
}
void i915_emit_copy_blit(drm_device_t *dev,
static void i915_emit_copy_blit(drm_device_t *dev,
uint32_t src_offset,
uint32_t dst_offset,
uint32_t pages,
@ -161,3 +161,35 @@ void i915_emit_copy_blit(drm_device_t *dev,
}
return;
}
static int drm_bo_move_blit(drm_buffer_object_t *bo,
int evict,
int no_wait,
drm_bo_mem_reg_t *new_mem)
{
drm_bo_mem_reg_t *old_mem = &bo->mem;
int dir = 0;
if ((old_mem->mem_type == new_mem->mem_type) &&
(new_mem->mm_node->start <
old_mem->mm_node->start + old_mem->mm_node->size)) {
dir = 1;
}
i915_emit_copy_blit(bo->dev,
old_mem->mm_node->start << PAGE_SHIFT,
new_mem->mm_node->start << PAGE_SHIFT,
new_mem->num_pages,
dir);
i915_emit_mi_flush(bo->dev, MI_READ_FLUSH | MI_EXE_FLUSH);
return drm_bo_move_accel_cleanup(bo, evict, no_wait,
DRM_FENCE_TYPE_EXE |
DRM_I915_FENCE_TYPE_RW,
DRM_I915_FENCE_FLAG_FLUSHED,
new_mem);
}