Buffer object mapping and mapping synchronization for multiple clients.
parent
e47a4fda2e
commit
14a835be61
103
libdrm/xf86drm.c
103
libdrm/xf86drm.c
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue