parent
ed9de124cc
commit
ec8c79b79d
340
libdrm/xf86drm.c
340
libdrm/xf86drm.c
|
@ -2501,7 +2501,9 @@ int drmResetList(drmBOList *list) {
|
|||
return drmAdjustListNodes(list);
|
||||
}
|
||||
|
||||
static int drmAddListItem(drmBOList *list, drmBO *item, drm_bo_arg_t *arg)
|
||||
static drmBONode *drmAddListItem(drmBOList *list, drmBO *item,
|
||||
unsigned long arg0,
|
||||
unsigned long arg1)
|
||||
{
|
||||
drmBONode *node;
|
||||
drmMMListHead *l;
|
||||
|
@ -2510,7 +2512,7 @@ static int drmAddListItem(drmBOList *list, drmBO *item, drm_bo_arg_t *arg)
|
|||
if (l == &list->free) {
|
||||
node = (drmBONode *) malloc(sizeof(*node));
|
||||
if (!node) {
|
||||
return -ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
list->numCurrent++;
|
||||
} else {
|
||||
|
@ -2518,11 +2520,43 @@ static int drmAddListItem(drmBOList *list, drmBO *item, drm_bo_arg_t *arg)
|
|||
node = DRMLISTENTRY(drmBONode, l, head);
|
||||
}
|
||||
node->buf = item;
|
||||
node->arg0 = arg0;
|
||||
node->arg1 = arg1;
|
||||
DRMLISTADD(&node->head, &list->list);
|
||||
list->numOnList++;
|
||||
return 0;
|
||||
return node;
|
||||
}
|
||||
|
||||
void *drmBOListIterator(drmBOList *list)
|
||||
{
|
||||
void *ret = list->list.next;
|
||||
|
||||
if (ret == &list->list)
|
||||
return NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *drmBOListNext(drmBOList *list, void *iterator)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
drmMMListHead *l = (drmMMListHead *) iterator;
|
||||
ret = l->next;
|
||||
if (ret == &list->list)
|
||||
return NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void drmBOListBuf(void *iterator, drmBO **buf)
|
||||
{
|
||||
drmBONode *node;
|
||||
drmMMListHead *l = (drmMMListHead *) iterator;
|
||||
node = DRMLISTENTRY(drmBONode, l, head);
|
||||
|
||||
*buf = node->buf;
|
||||
}
|
||||
|
||||
|
||||
int drmCreateBufList(int numTarget, drmBOList *list)
|
||||
{
|
||||
DRMINITLISTHEAD(&list->list);
|
||||
|
@ -2533,32 +2567,6 @@ int drmCreateBufList(int numTarget, drmBOList *list)
|
|||
return drmAdjustListNodes(list);
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepare list for IOCTL submission.
|
||||
*/
|
||||
|
||||
static drm_bo_arg_t *drmPrepareList(drmBOList *list)
|
||||
{
|
||||
drmMMListHead *cur, *next;
|
||||
drmBONode *first, *curNode, *nextNode;
|
||||
|
||||
cur = list->list.next;
|
||||
if (cur == &list->list)
|
||||
return NULL;
|
||||
|
||||
first = DRMLISTENTRY(drmBONode, cur, head);
|
||||
curNode = DRMLISTENTRY(drmBONode, cur, head);
|
||||
|
||||
for (next = cur->next; next != &list->list;
|
||||
cur = next, next = cur->next) {
|
||||
nextNode = DRMLISTENTRY(drmBONode, next, head);
|
||||
curNode->bo_arg.req.next = ((unsigned long) &nextNode->bo_arg.req);
|
||||
curNode = nextNode;
|
||||
}
|
||||
curNode->bo_arg.req.next = 0;
|
||||
return &first->bo_arg;
|
||||
}
|
||||
|
||||
int drmBOCreate(int fd, drmTTM *ttm, unsigned long start, unsigned long size,
|
||||
void *user_buffer, drm_bo_type_t type, unsigned mask,
|
||||
unsigned hint, drmBO *buf)
|
||||
|
@ -2567,6 +2575,7 @@ int drmBOCreate(int fd, drmTTM *ttm, unsigned long start, unsigned long size,
|
|||
drm_bo_arg_request_t *req = &arg.req;
|
||||
drm_bo_arg_reply_t *rep = &arg.rep;
|
||||
|
||||
arg.handled = 0;
|
||||
req->mask = mask;
|
||||
req->hint = hint;
|
||||
req->size = size;
|
||||
|
@ -2595,7 +2604,8 @@ int drmBOCreate(int fd, drmTTM *ttm, unsigned long start, unsigned long size,
|
|||
|
||||
if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg))
|
||||
return -errno;
|
||||
if (!rep->handled) {
|
||||
if (!arg.handled) {
|
||||
fprintf(stderr, "Not handled\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
if (rep->ret) {
|
||||
|
@ -2607,7 +2617,6 @@ int drmBOCreate(int fd, drmTTM *ttm, unsigned long start, unsigned long size,
|
|||
buf->size = rep->size;
|
||||
buf->offset = rep->offset;
|
||||
buf->mapHandle = rep->arg_handle;
|
||||
buf->mapFlags = rep->map_flags;
|
||||
buf->mapVirtual = NULL;
|
||||
buf->mapCount = 0;
|
||||
buf->virtual = NULL;
|
||||
|
@ -2623,13 +2632,14 @@ int drmBODestroy(int fd, drmBO *buf)
|
|||
drm_bo_arg_request_t *req = &arg.req;
|
||||
drm_bo_arg_reply_t *rep = &arg.rep;
|
||||
|
||||
arg.handled = 0;
|
||||
req->handle = buf->handle;
|
||||
req->op = drm_bo_destroy;
|
||||
req->next = 0;
|
||||
|
||||
if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg))
|
||||
return -errno;
|
||||
if (!rep->handled) {
|
||||
if (!arg.handled) {
|
||||
return -EFAULT;
|
||||
}
|
||||
if (rep->ret) {
|
||||
|
@ -2647,13 +2657,14 @@ int drmBOReference(int fd, unsigned handle, drmBO *buf)
|
|||
drm_bo_arg_request_t *req = &arg.req;
|
||||
drm_bo_arg_reply_t *rep = &arg.rep;
|
||||
|
||||
arg.handled = 0;
|
||||
req->handle = handle;
|
||||
req->op = drm_bo_reference;
|
||||
req->next = 0;
|
||||
|
||||
if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg))
|
||||
return -errno;
|
||||
if (!rep->handled) {
|
||||
if (!arg.handled) {
|
||||
return -EFAULT;
|
||||
}
|
||||
if (rep->ret) {
|
||||
|
@ -2666,7 +2677,6 @@ int drmBOReference(int fd, unsigned handle, drmBO *buf)
|
|||
buf->size = rep->size;
|
||||
buf->offset = rep->offset;
|
||||
buf->mapHandle = rep->arg_handle;
|
||||
buf->mapFlags = rep->map_flags;
|
||||
buf->mapVirtual = NULL;
|
||||
buf->mapCount = 0;
|
||||
buf->virtual = NULL;
|
||||
|
@ -2681,13 +2691,14 @@ int drmBOUnReference(int fd, drmBO *buf)
|
|||
drm_bo_arg_request_t *req = &arg.req;
|
||||
drm_bo_arg_reply_t *rep = &arg.rep;
|
||||
|
||||
arg.handled = 0;
|
||||
req->handle = buf->handle;
|
||||
req->op = drm_bo_unreference;
|
||||
req->next = 0;
|
||||
|
||||
if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg))
|
||||
return -errno;
|
||||
if (!rep->handled) {
|
||||
if (!arg.handled) {
|
||||
return -EFAULT;
|
||||
}
|
||||
if (rep->ret) {
|
||||
|
@ -2699,10 +2710,13 @@ int drmBOUnReference(int fd, drmBO *buf)
|
|||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* Flags can be DRM_BO_FLAG_READ, DRM_BO_FLAG_WRITE or'ed together
|
||||
* Hint currently be DRM_BO_HINT_DONT_BLOCK, which makes the
|
||||
* call return an -EBUSY if it can' immediately honor the mapping request.
|
||||
*/
|
||||
|
||||
int drmBOMap(int fd, drmBO *buf, unsigned mapFlags, void **address)
|
||||
int drmBOMap(int fd, drmBO *buf, unsigned mapFlags, unsigned mapHint,
|
||||
void **address)
|
||||
{
|
||||
|
||||
drm_bo_arg_t arg;
|
||||
|
@ -2714,6 +2728,7 @@ int drmBOMap(int fd, drmBO *buf, unsigned mapFlags, void **address)
|
|||
* Make sure we have a virtual address of the buffer.
|
||||
*/
|
||||
|
||||
fprintf(stderr, "Address is 0x%08x\n", address);
|
||||
if (!buf->mapVirtual) {
|
||||
if (buf->mapCount == 0) {
|
||||
drmAddress virtual;
|
||||
|
@ -2728,8 +2743,11 @@ int drmBOMap(int fd, drmBO *buf, unsigned mapFlags, void **address)
|
|||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "Address is 0x%08x\n", address);
|
||||
arg.handled = 0;
|
||||
req->handle = buf->handle;
|
||||
req->hint = mapFlags;
|
||||
req->mask = mapFlags;
|
||||
req->hint = mapHint;
|
||||
req->op = drm_bo_map;
|
||||
req->next = 0;
|
||||
|
||||
|
@ -2738,23 +2756,26 @@ int drmBOMap(int fd, drmBO *buf, unsigned mapFlags, void **address)
|
|||
* This IOCTL synchronizes the buffer.
|
||||
*/
|
||||
|
||||
fprintf(stderr, "Address is 0x%08x\n", address);
|
||||
do {
|
||||
ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg);
|
||||
} while (ret != 0 && errno == EAGAIN);
|
||||
|
||||
if (ret || !rep->handled || rep->ret) {
|
||||
fprintf(stderr, "Address is 0x%08x\n", address);
|
||||
if (ret || !arg.handled || rep->ret) {
|
||||
if (--buf->mapCount == 0) {
|
||||
(void )drmUnmap(buf->mapVirtual, buf->start + buf->size);
|
||||
}
|
||||
}
|
||||
if (ret)
|
||||
return ret;
|
||||
if (!rep->handled)
|
||||
if (!arg.handled)
|
||||
return -EFAULT;
|
||||
if (rep->ret)
|
||||
return rep->ret;
|
||||
|
||||
buf->mapFlags = mapFlags;
|
||||
fprintf(stderr, "Address is 0x%08x\n", address);
|
||||
*address = buf->virtual;
|
||||
|
||||
return 0;
|
||||
|
@ -2764,6 +2785,7 @@ int drmBOUnmap(int fd, drmBO *buf)
|
|||
{
|
||||
drm_bo_arg_t arg;
|
||||
drm_bo_arg_request_t *req = &arg.req;
|
||||
drm_bo_arg_reply_t *rep = &arg.rep;
|
||||
|
||||
if (buf->mapCount == 0) {
|
||||
return -EINVAL;
|
||||
|
@ -2773,6 +2795,7 @@ int drmBOUnmap(int fd, drmBO *buf)
|
|||
(void) drmUnmap(buf->mapVirtual, buf->start + buf->size);
|
||||
}
|
||||
|
||||
arg.handled = 0;
|
||||
req->handle = buf->handle;
|
||||
req->op = drm_bo_unmap;
|
||||
req->next = 0;
|
||||
|
@ -2780,10 +2803,247 @@ int drmBOUnmap(int fd, drmBO *buf)
|
|||
if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg)) {
|
||||
return -errno;
|
||||
}
|
||||
if (!arg.handled)
|
||||
return -EFAULT;
|
||||
if (rep->ret)
|
||||
return rep->ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drmBOValidate(int fd, drmBO *buf, unsigned flags, unsigned mask,
|
||||
unsigned hint)
|
||||
{
|
||||
drm_bo_arg_t arg;
|
||||
drm_bo_arg_request_t *req = &arg.req;
|
||||
drm_bo_arg_reply_t *rep = &arg.rep;
|
||||
int ret = 0;
|
||||
|
||||
arg.handled = 0;
|
||||
req->handle = buf->handle;
|
||||
req->mask = flags;
|
||||
req->hint = hint;
|
||||
req->arg_handle = mask; /* Encode mask in the arg_handle field :/ */
|
||||
req->op = drm_bo_validate;
|
||||
req->next = 0;
|
||||
|
||||
do{
|
||||
ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg);
|
||||
} while (ret && errno == -EAGAIN);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
if (!arg.handled)
|
||||
return -EFAULT;
|
||||
if (rep->ret)
|
||||
return rep->ret;
|
||||
|
||||
buf->offset = rep->offset;
|
||||
buf->flags = rep->flags;
|
||||
buf->mask = rep->mask;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int drmBOFence(int fd, drmBO *buf, unsigned flags, unsigned fenceHandle)
|
||||
{
|
||||
drm_bo_arg_t arg;
|
||||
drm_bo_arg_request_t *req = &arg.req;
|
||||
drm_bo_arg_reply_t *rep = &arg.rep;
|
||||
int ret = 0;
|
||||
|
||||
arg.handled = 0;
|
||||
req->handle = buf->handle;
|
||||
req->mask = flags;
|
||||
req->arg_handle = fenceHandle;
|
||||
req->op = drm_bo_validate;
|
||||
req->next = 0;
|
||||
|
||||
ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
if (!arg.handled)
|
||||
return -EFAULT;
|
||||
if (rep->ret)
|
||||
return rep->ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int drmAddValidateItem(drmBOList *list, drmBO *buf, unsigned flags,
|
||||
unsigned mask,
|
||||
int *newItem)
|
||||
{
|
||||
drmBONode *node, *cur;
|
||||
unsigned oldFlags, newFlags;
|
||||
drmMMListHead *l;
|
||||
|
||||
*newItem = 0;
|
||||
cur = NULL;
|
||||
|
||||
mask &= ~DRM_BO_MASK_MEM;
|
||||
|
||||
for (l = list->list.next; l != &list->list; l = l->next) {
|
||||
node = DRMLISTENTRY(drmBONode, l, head);
|
||||
if (node->buf == buf) {
|
||||
cur = node;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!cur) {
|
||||
cur = drmAddListItem(list, buf, flags, mask);
|
||||
if (!cur) {
|
||||
drmMsg("Out of memory creating validate list node.\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
*newItem = 1;
|
||||
cur->arg0 = flags;
|
||||
cur->arg1 = mask;
|
||||
} else {
|
||||
unsigned memFlags = cur->arg0 & DRM_BO_MASK_MEM;
|
||||
|
||||
if (!(memFlags & flags)) {
|
||||
drmMsg("Incompatible memory location requests "
|
||||
"on validate list.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if ((cur->arg1 | mask) & (cur->arg0 ^ flags)) {
|
||||
drmMsg("Incompatible buffer flag requests "
|
||||
" on validate list.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
cur->arg1 |= mask;
|
||||
cur->arg0 = (memFlags & flags) | ((cur->arg0 | flags) & cur->arg1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int drmBOValidateList(int fd, drmBOList *list)
|
||||
{
|
||||
|
||||
drmBONode *node;
|
||||
drmMMListHead *l;
|
||||
drm_bo_arg_t *arg, *first;
|
||||
drm_bo_arg_request_t *req;
|
||||
drm_bo_arg_reply_t *rep;
|
||||
drm_u64_t *prevNext = NULL;
|
||||
drmBO *buf;
|
||||
int ret;
|
||||
|
||||
first = NULL;
|
||||
|
||||
for (l = list->list.next; l != &list->list; l = l->next) {
|
||||
node = DRMLISTENTRY(drmBONode, l, head);
|
||||
|
||||
arg = &node->bo_arg;
|
||||
req = &arg->req;
|
||||
|
||||
if (!first)
|
||||
first = arg;
|
||||
|
||||
if (prevNext)
|
||||
*prevNext = (unsigned long) arg;
|
||||
|
||||
req->next = 0;
|
||||
prevNext = &req->next;
|
||||
arg->handled = 0;
|
||||
req->handle = node->buf->handle;
|
||||
req->op = drm_bo_validate;
|
||||
req->mask = node->arg0;
|
||||
req->hint = 0;
|
||||
req->arg_handle = node->arg1;
|
||||
}
|
||||
|
||||
if (!first)
|
||||
return 0;
|
||||
|
||||
do{
|
||||
ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg);
|
||||
} while (ret && errno == -EAGAIN);
|
||||
|
||||
if (ret)
|
||||
return -errno;
|
||||
|
||||
for (l = list->list.next; l != &list->list; l = l->next) {
|
||||
node = DRMLISTENTRY(drmBONode, l, head);
|
||||
|
||||
arg = &node->bo_arg;
|
||||
rep = &arg->rep;
|
||||
|
||||
if (!arg->handled)
|
||||
return -EFAULT;
|
||||
if (rep->ret)
|
||||
return rep->ret;
|
||||
|
||||
buf = node->buf;
|
||||
buf->offset = rep->offset;
|
||||
buf->flags = rep->flags;
|
||||
buf->mask = rep->mask;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int drmBOFenceList(int fd, drmBOList *list, unsigned fenceHandle)
|
||||
{
|
||||
|
||||
drmBONode *node;
|
||||
drmMMListHead *l;
|
||||
drm_bo_arg_t *arg, *first;
|
||||
drm_bo_arg_request_t *req;
|
||||
drm_bo_arg_reply_t *rep;
|
||||
drm_u64_t *prevNext = NULL;
|
||||
drmBO *buf;
|
||||
int ret;
|
||||
|
||||
first = NULL;
|
||||
|
||||
for (l = list->list.next; l != &list->list; l = l->next) {
|
||||
node = DRMLISTENTRY(drmBONode, l, head);
|
||||
|
||||
arg = &node->bo_arg;
|
||||
req = &arg->req;
|
||||
|
||||
if (!first)
|
||||
first = arg;
|
||||
|
||||
if (prevNext)
|
||||
*prevNext = (unsigned long) arg;
|
||||
|
||||
req->next = 0;
|
||||
prevNext = &req->next;
|
||||
arg->handled = 0;
|
||||
req->handle = node->buf->handle;
|
||||
req->op = drm_bo_fence;
|
||||
req->mask = node->arg0;
|
||||
req->arg_handle = fenceHandle;
|
||||
}
|
||||
|
||||
if (!first)
|
||||
return 0;
|
||||
|
||||
ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg);
|
||||
|
||||
if (ret)
|
||||
return -errno;
|
||||
|
||||
for (l = list->list.next; l != &list->list; l = l->next) {
|
||||
node = DRMLISTENTRY(drmBONode, l, head);
|
||||
|
||||
arg = &node->bo_arg;
|
||||
rep = &arg->rep;
|
||||
|
||||
if (!arg->handled)
|
||||
return -EFAULT;
|
||||
if (rep->ret)
|
||||
return rep->ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drmMMInit(int fd, unsigned long vramPOffset, unsigned long vramPSize,
|
||||
unsigned long ttPOffset, unsigned long ttPSize)
|
||||
|
|
|
@ -103,6 +103,8 @@ typedef struct _drmBONode {
|
|||
drmMMListHead head;
|
||||
drmBO *buf;
|
||||
drm_bo_arg_t bo_arg;
|
||||
unsigned long arg0;
|
||||
unsigned long arg1;
|
||||
} drmBONode;
|
||||
|
||||
typedef struct _drmBOList {
|
||||
|
|
|
@ -966,7 +966,6 @@ typedef struct drm_buffer_object{
|
|||
unsigned long offset;
|
||||
|
||||
atomic_t mapped;
|
||||
uint32_t map_flags;
|
||||
uint32_t flags;
|
||||
uint32_t mask;
|
||||
|
||||
|
|
|
@ -256,11 +256,11 @@ static int drm_bo_evict(drm_buffer_object_t * bo, int tt, int no_wait)
|
|||
int ret = 0;
|
||||
|
||||
/*
|
||||
* Someone might have taken out the buffer before we took the buffer mutex.
|
||||
* Someone might have modified the buffer before we took the buffer mutex.
|
||||
*/
|
||||
|
||||
mutex_lock(&bo->mutex);
|
||||
if (bo->unfenced)
|
||||
if (bo->unfenced || (bo->flags & DRM_BO_FLAG_NO_EVICT))
|
||||
goto out;
|
||||
if (tt && !bo->tt)
|
||||
goto out;
|
||||
|
@ -371,17 +371,46 @@ static int drm_move_local_to_tt(drm_buffer_object_t * bo, int no_wait)
|
|||
|
||||
static int drm_bo_new_flags(drm_bo_driver_t * driver,
|
||||
uint32_t flags, uint32_t new_mask, uint32_t hint,
|
||||
int init, uint32_t * n_flags)
|
||||
int init, uint32_t * n_flags,
|
||||
uint32_t *n_mask)
|
||||
{
|
||||
uint32_t new_flags;
|
||||
uint32_t new_flags = 0;
|
||||
uint32_t new_props;
|
||||
|
||||
if (!(flags & new_mask & DRM_BO_MASK_MEM) || init) {
|
||||
/*
|
||||
* First adjust the mask. Vram is not supported yet.
|
||||
*/
|
||||
|
||||
/*
|
||||
* We need to move memory. Default preferences are hard-coded
|
||||
* here.
|
||||
*/
|
||||
new_mask &= ~DRM_BO_FLAG_MEM_VRAM;
|
||||
|
||||
if (new_mask & DRM_BO_FLAG_BIND_CACHED) {
|
||||
if (((new_mask & DRM_BO_FLAG_MEM_TT) && !driver->cached_tt) &&
|
||||
((new_mask & DRM_BO_FLAG_MEM_VRAM) && !driver->cached_vram)) {
|
||||
new_mask &= ~DRM_BO_FLAG_BIND_CACHED;
|
||||
} else {
|
||||
if (!driver->cached_tt)
|
||||
new_flags &= DRM_BO_FLAG_MEM_TT;
|
||||
if (!driver->cached_vram)
|
||||
new_flags &= DRM_BO_FLAG_MEM_VRAM;
|
||||
}
|
||||
}
|
||||
|
||||
if ((new_mask & DRM_BO_FLAG_READ_CACHED) &&
|
||||
!(new_mask & DRM_BO_FLAG_BIND_CACHED)) {
|
||||
if ((new_mask & DRM_BO_FLAG_NO_EVICT) &&
|
||||
!(new_mask & DRM_BO_FLAG_MEM_LOCAL)) {
|
||||
DRM_ERROR("Cannot read cached from a pinned VRAM / TT buffer\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
new_mask &= ~(DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_MEM_VRAM);
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine new memory location:
|
||||
*/
|
||||
|
||||
|
||||
if (!(flags & new_mask & DRM_BO_MASK_MEM) || init) {
|
||||
|
||||
new_flags = new_mask & DRM_BO_MASK_MEM;
|
||||
|
||||
|
@ -421,17 +450,10 @@ static int drm_bo_new_flags(drm_bo_driver_t * driver,
|
|||
|
||||
new_flags |= new_mask & ~DRM_BO_MASK_MEM;
|
||||
|
||||
if (new_mask & DRM_BO_FLAG_BIND_CACHED) {
|
||||
new_flags |= DRM_BO_FLAG_CACHED;
|
||||
if (((new_flags & DRM_BO_FLAG_MEM_TT) && !driver->cached_tt) ||
|
||||
((new_flags & DRM_BO_FLAG_MEM_VRAM)
|
||||
&& !driver->cached_vram))
|
||||
new_flags &= ~DRM_BO_FLAG_CACHED;
|
||||
}
|
||||
|
||||
if ((new_flags & DRM_BO_FLAG_NO_EVICT) &&
|
||||
((flags ^ new_flags) & DRM_BO_FLAG_CACHED)) {
|
||||
if (flags & DRM_BO_FLAG_CACHED) {
|
||||
if (((flags ^ new_flags) & DRM_BO_FLAG_BIND_CACHED) &&
|
||||
(new_flags & DRM_BO_FLAG_NO_EVICT) &&
|
||||
(flags & (DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_MEM_VRAM))) {
|
||||
if (!(flags & DRM_BO_FLAG_CACHED)) {
|
||||
DRM_ERROR
|
||||
("Cannot change caching policy of pinned buffer\n");
|
||||
return -EINVAL;
|
||||
|
@ -441,6 +463,7 @@ static int drm_bo_new_flags(drm_bo_driver_t * driver,
|
|||
}
|
||||
|
||||
*n_flags = new_flags;
|
||||
*n_mask = new_mask;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -498,6 +521,12 @@ static int drm_bo_busy(drm_buffer_object_t * bo)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int drm_bo_read_cached(drm_buffer_object_t *bo) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Wait for buffer idle and register that we've mapped the buffer.
|
||||
* Mapping is registered as a drm_ref_object with type _DRM_REF_TYPE1,
|
||||
|
@ -505,11 +534,12 @@ static int drm_bo_busy(drm_buffer_object_t * bo)
|
|||
* unregistered.
|
||||
*/
|
||||
|
||||
static int drm_buffer_object_map(drm_file_t * priv, uint32_t handle, int wait)
|
||||
static int drm_buffer_object_map(drm_file_t * priv, uint32_t handle,
|
||||
uint32_t map_flags, int no_wait)
|
||||
{
|
||||
drm_buffer_object_t *bo;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
bo = drm_lookup_buffer_object(priv, handle, 1);
|
||||
|
@ -526,14 +556,46 @@ static int drm_buffer_object_map(drm_file_t * priv, uint32_t handle, int wait)
|
|||
* be done without the bo->mutex held.
|
||||
*/
|
||||
|
||||
if (atomic_inc_and_test(&bo->mapped)) {
|
||||
ret = drm_bo_wait(bo, 0, !wait);
|
||||
if (ret) {
|
||||
atomic_dec(&bo->mapped);
|
||||
goto out;
|
||||
while(1) {
|
||||
if (atomic_inc_and_test(&bo->mapped)) {
|
||||
ret = drm_bo_wait(bo, 0, no_wait);
|
||||
if (ret) {
|
||||
atomic_dec(&bo->mapped);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((map_flags & DRM_BO_FLAG_READ) &&
|
||||
(bo->flags & DRM_BO_FLAG_READ_CACHED) &&
|
||||
(!(bo->flags & DRM_BO_FLAG_CACHED))) {
|
||||
|
||||
drm_bo_read_cached(bo);
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
if ((map_flags & DRM_BO_FLAG_READ) &&
|
||||
(bo->flags & DRM_BO_FLAG_READ_CACHED) &&
|
||||
(!(bo->flags & DRM_BO_FLAG_CACHED))) {
|
||||
|
||||
/*
|
||||
* We are already mapped with different flags.
|
||||
* need to wait for unmap.
|
||||
*/
|
||||
|
||||
if (no_wait) {
|
||||
ret = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
DRM_WAIT_ON(ret, bo->validate_queue, 3 * DRM_HZ,
|
||||
atomic_read(&bo->mapped) == -1);
|
||||
if (ret == -EINTR)
|
||||
ret = -EAGAIN;
|
||||
if (ret)
|
||||
goto out;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
ret = drm_add_ref_object(priv, &bo->base, _DRM_REF_TYPE1);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
|
@ -729,7 +791,7 @@ static int drm_buffer_object_validate(drm_buffer_object_t * bo,
|
|||
*/
|
||||
|
||||
static int drm_bo_add_ttm(drm_file_t * priv, drm_buffer_object_t * bo,
|
||||
uint32_t mask, uint32_t ttm_handle)
|
||||
uint32_t ttm_handle)
|
||||
{
|
||||
drm_device_t *dev = bo->dev;
|
||||
drm_ttm_object_t *to = NULL;
|
||||
|
@ -774,7 +836,7 @@ static int drm_bo_add_ttm(drm_file_t * priv, drm_buffer_object_t * bo,
|
|||
ttm = drm_ttm_from_object(to);
|
||||
ret = drm_create_ttm_region(ttm, bo->buffer_start >> PAGE_SHIFT,
|
||||
bo->num_pages,
|
||||
mask & DRM_BO_FLAG_BIND_CACHED,
|
||||
bo->mask & DRM_BO_FLAG_BIND_CACHED,
|
||||
&bo->ttm_region);
|
||||
if (ret) {
|
||||
drm_ttm_object_deref_unlocked(dev, to);
|
||||
|
@ -827,17 +889,19 @@ int drm_buffer_object_create(drm_file_t * priv,
|
|||
bo->buffer_start = buffer_start;
|
||||
|
||||
ret = drm_bo_new_flags(dev->driver->bo_driver, bo->flags, mask, hint,
|
||||
1, &new_flags);
|
||||
1, &new_flags, &bo->mask);
|
||||
if (ret)
|
||||
goto out_err;
|
||||
ret = drm_bo_add_ttm(priv, bo, mask, ttm_handle);
|
||||
ret = drm_bo_add_ttm(priv, bo, ttm_handle);
|
||||
if (ret)
|
||||
goto out_err;
|
||||
|
||||
bo->mask = mask;
|
||||
|
||||
#if 0
|
||||
ret = drm_buffer_object_validate(bo, new_flags, 0,
|
||||
hint & DRM_BO_HINT_DONT_BLOCK);
|
||||
#else
|
||||
bo->flags = new_flags;
|
||||
#endif
|
||||
if (ret)
|
||||
goto out_err;
|
||||
|
||||
|
@ -886,7 +950,6 @@ static void drm_bo_fill_rep_arg(const drm_buffer_object_t * bo,
|
|||
rep->arg_handle = 0;
|
||||
}
|
||||
|
||||
rep->map_flags = bo->map_flags;
|
||||
rep->mask = bo->mask;
|
||||
rep->buffer_start = bo->buffer_start;
|
||||
}
|
||||
|
@ -902,9 +965,15 @@ int drm_bo_ioctl(DRM_IOCTL_ARGS)
|
|||
drm_buffer_object_t *entry;
|
||||
|
||||
do {
|
||||
DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
|
||||
DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data,
|
||||
sizeof(arg));
|
||||
|
||||
if (arg.handled) {
|
||||
data = req->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
rep.ret = 0;
|
||||
rep.handled = 0;
|
||||
switch (req->op) {
|
||||
case drm_bo_create:{
|
||||
unsigned long buffer_start = req->buffer_start;
|
||||
|
@ -937,8 +1006,9 @@ int drm_bo_ioctl(DRM_IOCTL_ARGS)
|
|||
break;
|
||||
case drm_bo_map:
|
||||
rep.ret = drm_buffer_object_map(priv, req->handle,
|
||||
!(req->hint &
|
||||
DRM_BO_HINT_DONT_BLOCK));
|
||||
req->mask,
|
||||
req->hint &
|
||||
DRM_BO_HINT_DONT_BLOCK);
|
||||
break;
|
||||
case drm_bo_destroy:
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
|
@ -976,16 +1046,25 @@ int drm_bo_ioctl(DRM_IOCTL_ARGS)
|
|||
rep.ret = -EINVAL;
|
||||
}
|
||||
next = req->next;
|
||||
rep.handled = 1;
|
||||
|
||||
/*
|
||||
* A signal interrupted us. Make sure the ioctl is restartable.
|
||||
*/
|
||||
|
||||
if (rep.ret == -EAGAIN)
|
||||
return -EAGAIN;
|
||||
|
||||
arg.handled = 1;
|
||||
arg.rep = rep;
|
||||
DRM_COPY_TO_USER_IOCTL((void __user *)data, arg, sizeof(arg));
|
||||
data = next;
|
||||
|
||||
} while (data);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void drm_bo_clean_mm(drm_file_t * priv)
|
||||
{
|
||||
}
|
||||
|
@ -1008,10 +1087,12 @@ int drm_mm_init_ioctl(DRM_IOCTL_ARGS)
|
|||
|
||||
switch (arg.req.op) {
|
||||
case mm_init:
|
||||
#if 0
|
||||
if (bm->initialized) {
|
||||
DRM_ERROR("Memory manager already initialized\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
mutex_init(&bm->mutex);
|
||||
mutex_lock(&bm->mutex);
|
||||
bm->has_vram = 0;
|
||||
|
|
|
@ -688,22 +688,28 @@ typedef struct drm_ttm_arg {
|
|||
#define DRM_BO_FLAG_WRITE 0x00000002
|
||||
#define DRM_BO_FLAG_EXE 0x00000004
|
||||
|
||||
/*
|
||||
* Status flags. Can be read to determine the actual state of a buffer.
|
||||
*/
|
||||
|
||||
/* Pinned buffer. */
|
||||
#define DRM_BO_FLAG_NO_EVICT 0x00000010
|
||||
#define DRM_BO_FLAG_NO_EVICT 0x00000001
|
||||
/* Always keep a system memory shadow to a vram buffer */
|
||||
#define DRM_BO_FLAG_SHADOW_VRAM 0x00000020
|
||||
#define DRM_BO_FLAG_SHADOW_VRAM 0x00000002
|
||||
/* When mapped for reading, make sure the buffer is cached even
|
||||
if it means moving the buffer to system memory */
|
||||
#define DRM_BO_FLAG_READ_CACHED 0x00000040
|
||||
/* The buffer is currently cached */
|
||||
#define DRM_BO_FLAG_CACHED 0x00000080
|
||||
/* The buffer is shareable with other processes */
|
||||
#define DRM_BO_FLAG_SHAREABLE 0x00000100
|
||||
#define DRM_BO_FLAG_SHAREABLE 0x00000004
|
||||
/* When there is a choice between VRAM and TT, prefer VRAM.
|
||||
The default behaviour is to prefer TT. */
|
||||
#define DRM_BO_FLAG_PREFER_VRAM 0x00000200
|
||||
#define DRM_BO_FLAG_CACHED 0x00000008
|
||||
/* The buffer is shareable with other processes */
|
||||
|
||||
|
||||
#define DRM_BO_FLAG_READ_CACHED 0x00001000
|
||||
/* The buffer is currently cached */
|
||||
#define DRM_BO_FLAG_PREFER_VRAM 0x00002000
|
||||
/* Bind this buffer cached if the hardware supports it. */
|
||||
#define DRM_BO_FLAG_BIND_CACHED 0x00000400
|
||||
#define DRM_BO_FLAG_BIND_CACHED 0x00004000
|
||||
|
||||
/* Translation table aperture */
|
||||
#define DRM_BO_FLAG_MEM_TT 0x01000000
|
||||
|
@ -750,21 +756,22 @@ typedef struct drm_bo_arg_request {
|
|||
|
||||
typedef struct drm_bo_arg_reply {
|
||||
int ret;
|
||||
int handled;
|
||||
unsigned handle;
|
||||
unsigned flags;
|
||||
drm_u64_t size;
|
||||
drm_u64_t offset;
|
||||
unsigned arg_handle;
|
||||
unsigned map_flags;
|
||||
unsigned mask;
|
||||
drm_u64_t buffer_start;
|
||||
}drm_bo_arg_reply_t;
|
||||
|
||||
|
||||
typedef union drm_bo_arg{
|
||||
drm_bo_arg_request_t req;
|
||||
drm_bo_arg_reply_t rep;
|
||||
typedef struct drm_bo_arg{
|
||||
int handled;
|
||||
union {
|
||||
drm_bo_arg_request_t req;
|
||||
drm_bo_arg_reply_t rep;
|
||||
};
|
||||
} drm_bo_arg_t;
|
||||
|
||||
typedef union drm_mm_init_arg{
|
||||
|
|
Loading…
Reference in New Issue