Buffer object mapping and mapping synchronization for multiple clients.

main
Thomas Hellstrom 2006-08-30 15:08:40 +02:00
parent e47a4fda2e
commit 14a835be61
5 changed files with 104 additions and 15 deletions

View File

@ -2606,10 +2606,10 @@ int drmBOCreate(int fd, drmTTM *ttm, unsigned long start, unsigned long size,
buf->flags = rep->flags;
buf->size = rep->size;
buf->offset = rep->offset;
buf->map_handle = rep->arg_handle;
buf->map_flags = rep->map_flags;
buf->map_virtual = NULL;
buf->map_count = 0;
buf->mapHandle = rep->arg_handle;
buf->mapFlags = rep->map_flags;
buf->mapVirtual = NULL;
buf->mapCount = 0;
buf->virtual = NULL;
buf->mask = rep->mask;
buf->hint = rep->hint;
@ -2666,13 +2666,14 @@ int drmBOReference(int fd, unsigned handle, drmBO *buf)
buf->flags = rep->flags;
buf->size = rep->size;
buf->offset = rep->offset;
buf->map_handle = rep->arg_handle;
buf->map_flags = rep->map_flags;
buf->map_virtual = NULL;
buf->map_count = 0;
buf->mapHandle = rep->arg_handle;
buf->mapFlags = rep->map_flags;
buf->mapVirtual = NULL;
buf->mapCount = 0;
buf->virtual = NULL;
buf->mask = rep->mask;
buf->hint = rep->hint;
buf->start = rep->buffer_start;
return 0;
}
@ -2699,6 +2700,92 @@ int drmBOUnReference(int fd, drmBO *buf)
return 0;
}
/*
*
*/
int drmBOMap(int fd, drmBO *buf, unsigned map_flags, void **address)
{
drm_bo_arg_t arg;
drm_bo_arg_request_t *req = &arg.req;
drm_bo_arg_reply_t *rep = &arg.rep;
int ret = 0;
/*
* Make sure we have a virtual address of the buffer.
*/
if (!buf->mapVirtual) {
if (buf->mapCount == 0) {
drmAddress virtual;
ret = drmMap(fd, buf->mapHandle, buf->size + buf->start, &virtual);
if (ret)
return ret;
++buf->mapCount;
buf->mapVirtual = virtual;
buf->virtual = ((char *) virtual) + buf->start;
fprintf(stderr,"Mapvirtual, virtual: 0x%08x 0x%08x\n",
buf->mapVirtual, buf->virtual);
}
}
req->handle = buf->handle;
req->mask = map_flags;
req->op = drm_bo_map;
req->next = 0;
/*
* May hang if the buffer object is busy.
* This IOCTL synchronizes the buffer.
*/
do {
ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg);
} while (ret != 0 && errno == EAGAIN);
if (ret || !rep->handled || rep->ret) {
if (--buf->mapCount == 0) {
(void )drmUnmap(buf->mapVirtual, buf->start + buf->size);
}
}
if (ret)
return ret;
if (!rep->handled)
return -EFAULT;
if (rep->ret)
return rep->ret;
*address = buf->virtual;
return 0;
}
int drmBOUnmap(int fd, drmBO *buf)
{
drm_bo_arg_t arg;
drm_bo_arg_request_t *req = &arg.req;
if (buf->mapCount == 0) {
return -EINVAL;
}
if (--buf->mapCount == 0) {
(void) drmUnmap(buf->mapVirtual, buf->start + buf->size);
}
req->handle = buf->handle;
req->op = drm_bo_unmap;
req->next = 0;
if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg)) {
return -errno;
}
return 0;
}
int drmMMInit(int fd, unsigned long vramPOffset, unsigned long vramPSize,
unsigned long ttPOffset, unsigned long ttPSize)
{

View File

@ -85,17 +85,17 @@ typedef struct _drmMMListHead
typedef struct _drmBO{
drm_bo_type_t type;
unsigned handle;
drm_handle_t map_handle;
drm_handle_t mapHandle;
unsigned flags;
unsigned mask;
unsigned hint;
unsigned map_flags;
unsigned mapFlags;
unsigned long size;
unsigned long offset;
unsigned long start;
void *virtual;
void *map_virtual;
int map_count;
void *mapVirtual;
int mapCount;
drmTTM *ttm;
} drmBO;

View File

@ -513,8 +513,11 @@ static int drm_buffer_object_unmap(drm_file_t * priv, uint32_t handle)
goto out;
}
DRM_ERROR("Removing ref object\n");
drm_remove_ref_object(priv, ro);
DRM_ERROR("Deregistering usage\n");
drm_bo_usage_deref_locked(dev, bo);
DRM_ERROR("Done\n");
out:
mutex_unlock(&dev->struct_mutex);
return ret;

View File

@ -108,9 +108,6 @@ static int drm_object_ref_action(drm_file_t * priv, drm_user_object_t * ro,
break;
default:
if (!ro->ref_struct_locked) {
DRM_ERROR("Register object called without register"
" capabilities\n");
ret = -EINVAL;
break;
} else {
ro->ref_struct_locked(priv, ro, action);
@ -164,6 +161,7 @@ int drm_add_ref_object(drm_file_t * priv, drm_user_object_t * referenced_object,
atomic_set(&item->refcount, 1);
item->hash.key = (unsigned long)referenced_object;
ret = drm_ht_insert_item(ht, &item->hash);
item->unref_action = ref_action;
if (ret)
goto out;

View File

@ -713,6 +713,7 @@ static void drm_vm_ttm_close(struct vm_area_struct *vma)
dev = ttm->dev;
mutex_lock(&dev->struct_mutex);
drm_ttm_delete_mm(ttm, vma->vm_mm);
list_del(&ttm_vma->head);
drm_free(ttm_vma, sizeof(*ttm_vma), DRM_MEM_VMAS);
if (atomic_dec_and_test(&ttm->vma_count)) {
if (ttm->destroy) {