Checkpoint ttm addition to buffer objects.

This commit is contained in:
Thomas Hellstrom 2006-08-29 14:52:02 +02:00
parent 279e8d26c6
commit 0dedfc2cd0
5 changed files with 91 additions and 49 deletions

View file

@ -951,8 +951,9 @@ typedef struct drm_buffer_object{
atomic_t usage;
drm_ttm_object_t *ttm_object;
drm_ttm_backend_list_t *ttm_region;
void __user *user_pages;
unsigned long num_pages;
unsigned long buffer_start;
drm_bo_type_t type;
atomic_t mapped;
uint32_t flags;

View file

@ -141,8 +141,8 @@ static int drm_move_tt_to_local(drm_buffer_object_t *buf, int lazy)
drm_unbind_ttm_region(buf->ttm_region);
drm_mm_put_block(&bm->tt_manager, buf->tt);
buf->tt = NULL;
buf->flags &= ~(DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_UNCACHED);
buf->flags |= DRM_BO_FLAG_MEM_LOCAL;
buf->flags &= ~(DRM_BO_FLAG_MEM_TT);
buf->flags |= DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED;
return 0;
}
@ -531,9 +531,65 @@ static int drm_buffer_object_validate(drm_device_t *dev, drm_buffer_object_t *bo
return 0;
}
/*
* Call bo->mutex locked.
*/
static int drm_bo_add_ttm(drm_file_t *priv, drm_buffer_object_t *bo, uint32_t new_flags,
uint32_t ttm_handle)
{
drm_device_t *dev = bo->dev;
drm_ttm_object_t *to = NULL;
drm_ttm_t *ttm;
int ret=0;
uint32_t ttm_flags = 0;
bo->ttm_object = NULL;
bo->ttm_region = NULL;
switch(bo->type) {
case drm_bo_type_dc:
mutex_lock(&dev->struct_mutex);
ret = drm_ttm_object_create(dev, bo->num_pages*PAGE_SIZE,
ttm_flags, &to);
mutex_unlock(&dev->struct_mutex);
break;
case drm_bo_type_ttm:
mutex_lock(&dev->struct_mutex);
to = drm_lookup_ttm_object(priv, ttm_handle, 1);
mutex_unlock(&dev->struct_mutex);
if (!to)
ret = -EINVAL;
break;
case drm_bo_type_user:
break;
default:
ret = -EINVAL;
}
if (ret) {
return ret;
}
if (to) {
bo->ttm_object = to;
ttm = drm_ttm_from_object(to);
ret = drm_create_ttm_region(ttm, bo->buffer_start >> PAGE_SHIFT,
bo->num_pages,
new_flags & DRM_BO_FLAG_CACHED,
&bo->ttm_region);
if (ret) {
drm_ttm_object_deref_unlocked(dev, to);
}
}
return ret;
}
int drm_buffer_object_create(drm_file_t *priv,
int size,
unsigned long size,
drm_bo_type_t type,
uint32_t ttm_handle,
uint32_t mask,
@ -544,8 +600,18 @@ int drm_buffer_object_create(drm_file_t *priv,
drm_device_t *dev = priv->head->dev;
drm_buffer_object_t *bo;
int ret = 0;
uint32_t ttm_flags = 0;
drm_ttm_t *ttm;
uint32_t new_flags;
unsigned long num_pages;
if (buffer_start & ~PAGE_MASK) {
DRM_ERROR("Invalid buffer object start.\n");
return -EINVAL;
}
num_pages = (size + PAGE_SIZE -1) >> PAGE_SHIFT;
if (num_pages == 0) {
DRM_ERROR("Illegal buffer object size.\n");
return -EINVAL;
}
bo = drm_calloc(1, sizeof(*bo), DRM_MEM_BUFOBJ);
@ -561,50 +627,14 @@ int drm_buffer_object_create(drm_file_t *priv,
INIT_LIST_HEAD(&bo->head);
INIT_LIST_HEAD(&bo->ddestroy);
bo->dev = dev;
bo->type = type;
bo->num_pages = num_pages;
bo->buffer_start = buffer_start;
switch(type) {
case drm_bo_type_dc:
ret = drm_ttm_object_create(dev, size, ttm_flags, &bo->ttm_object);
if (ret)
goto out_err;
break;
case drm_bo_type_ttm:
if (buffer_start & ~PAGE_MASK) {
DRM_ERROR("Illegal buffer object start\n");
ret = -EINVAL;
}
bo->num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
if (!bo->num_pages) {
DRM_ERROR("Illegal buffer object size\n");
ret = -EINVAL;
goto out_err;
}
bo->ttm_object = drm_lookup_ttm_object(priv, ttm_handle, 1);
if (!bo->ttm_object) {
DRM_ERROR("Could not find buffer object TTM\n");
ret = -EINVAL;
goto out_err;
}
ttm = drm_ttm_from_object(bo->ttm_object);
ret = drm_create_ttm_region(ttm, buffer_start >> PAGE_SHIFT,
bo->num_pages, 0, &bo->ttm_region);
if (ret)
goto out_err;
break;
case drm_bo_type_user:
if (buffer_start & ~PAGE_MASK) {
DRM_ERROR("Illegal buffer object start\n");
ret = -EINVAL;
goto out_err;
}
bo->num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
bo->user_pages = (void __user *)buffer_start;
break;
default:
ret = -EINVAL;
ret = drm_bo_add_ttm(priv, bo, new_flags, ttm_handle);
if (ret)
goto out_err;
}
bo->mask = mask;
bo->mask_hint = hint;

View file

@ -784,6 +784,16 @@ void drm_ttm_object_deref_locked(drm_device_t *dev, drm_ttm_object_t *to)
}
}
void drm_ttm_object_deref_unlocked(drm_device_t *dev, drm_ttm_object_t *to)
{
if (atomic_dec_and_test(&to->usage)) {
mutex_lock(&dev->struct_mutex);
if (atomic_read(&to->usage) == 0)
drm_ttm_object_remove(dev, to);
mutex_unlock(&dev->struct_mutex);
}
}
/*
* dev->struct_mutex locked.

View file

@ -111,6 +111,7 @@ typedef struct drm_ttm_object {
extern int drm_ttm_object_create(struct drm_device *dev, unsigned long size,
uint32_t flags, drm_ttm_object_t **ttm_object);
extern void drm_ttm_object_deref_locked(struct drm_device *dev, drm_ttm_object_t *to);
extern void drm_ttm_object_deref_unlocked(struct drm_device *dev, drm_ttm_object_t *to);
extern drm_ttm_object_t *drm_lookup_ttm_object(drm_file_t *priv, uint32_t handle,
int check_owner);

View file

@ -686,7 +686,7 @@ typedef struct drm_ttm_arg {
#define DRM_BO_FLAG_NO_EVICT 0x00000010
#define DRM_BO_FLAG_SHADOW_VRAM 0x00000020
#define DRM_BO_FLAG_READ_LOCAL 0x00000040
#define DRM_BO_FLAG_UNCACHED 0x00000080
#define DRM_BO_FLAG_CACHED 0x00000080
#define DRM_BO_FLAG_SHAREABLE 0x00000100
#define DRM_BO_FLAG_MEM_TT 0x01000000