Part of buffer object libdrm interface.

main
Thomas Hellstrom 2006-08-29 21:57:37 +02:00
parent 23f01c9fe8
commit de144ba23c
4 changed files with 196 additions and 36 deletions

View File

@ -2381,6 +2381,8 @@ int drmTTMCreate(int fd, drmTTM *ttm, unsigned long size, unsigned flags)
ttm->user_token = (drm_handle_t) arg.user_token;
ttm->flags = arg.flags;
ttm->size = arg.size;
ttm->virtual = NULL;
ttm->mapCount = 0;
return 0;
}
@ -2428,14 +2430,14 @@ drm_handle_t drmTTMMapHandle(int fd, const drmTTM *ttm)
return ttm->user_token;
}
static int drmAdjustListNodes(DrmBufList *list)
static int drmAdjustListNodes(drmBOList *list)
{
DrmBufNode *node;
DrmMMListHead *l;
drmBONode *node;
drmMMListHead *l;
int ret = 0;
while(list->numCurrent < list->numTarget) {
node = (DrmBufNode *) malloc(sizeof(*node));
node = (drmBONode *) malloc(sizeof(*node));
if (!node) {
ret = -ENOMEM;
break;
@ -2449,23 +2451,23 @@ static int drmAdjustListNodes(DrmBufList *list)
if (l == &list->free)
break;
DRMLISTDEL(l);
node = DRMLISTENTRY(DrmBufNode, l, head);
node = DRMLISTENTRY(drmBONode, l, head);
free(node);
list->numCurrent--;
}
return ret;
}
static void drmFreeList(DrmBufList *list)
static void drmFreeList(drmBOList *list)
{
DrmBufNode *node;
DrmMMListHead *l;
drmBONode *node;
drmMMListHead *l;
int ret = 0;
l = list->list.next;
while(l != &list->list) {
DRMLISTDEL(l);
node = DRMLISTENTRY(DrmBufNode, l, head);
node = DRMLISTENTRY(drmBONode, l, head);
free(node);
l = list->free.next;
list->numCurrent--;
@ -2475,16 +2477,16 @@ static void drmFreeList(DrmBufList *list)
l = list->free.next;
while(l != &list->free) {
DRMLISTDEL(l);
node = DRMLISTENTRY(DrmBufNode, l, head);
node = DRMLISTENTRY(drmBONode, l, head);
free(node);
l = list->free.next;
list->numCurrent--;
}
}
int drmResetList(DrmBufList *list) {
int drmResetList(drmBOList *list) {
DrmMMListHead *l;
drmMMListHead *l;
int ret;
ret = drmAdjustListNodes(list);
@ -2500,21 +2502,21 @@ int drmResetList(DrmBufList *list) {
return drmAdjustListNodes(list);
}
static int drmAddListItem(DrmBufList *list, DrmBuf *item, drm_bo_arg_t *arg)
static int drmAddListItem(drmBOList *list, drmBO *item, drm_bo_arg_t *arg)
{
DrmBufNode *node;
DrmMMListHead *l;
drmBONode *node;
drmMMListHead *l;
l = list->free.next;
if (l == &list->free) {
node = (DrmBufNode *) malloc(sizeof(*node));
node = (drmBONode *) malloc(sizeof(*node));
if (!node) {
return -ENOMEM;
}
list->numCurrent++;
} else {
DRMLISTDEL(l);
node = DRMLISTENTRY(DrmBufNode, l, head);
node = DRMLISTENTRY(drmBONode, l, head);
}
node->buf = item;
DRMLISTADD(&node->head, &list->list);
@ -2522,7 +2524,7 @@ static int drmAddListItem(DrmBufList *list, DrmBuf *item, drm_bo_arg_t *arg)
return 0;
}
int drmCreateBufList(int numTarget, DrmBufList *list)
int drmCreateBufList(int numTarget, drmBOList *list)
{
DRMINITLISTHEAD(&list->list);
DRMINITLISTHEAD(&list->free);
@ -2536,21 +2538,21 @@ int drmCreateBufList(int numTarget, DrmBufList *list)
* Prepare list for IOCTL submission.
*/
static drm_bo_arg_t *drmPrepareList(DrmBufList *list)
static drm_bo_arg_t *drmPrepareList(drmBOList *list)
{
DrmMMListHead *cur, *next;
DrmBufNode *first, *curNode, *nextNode;
drmMMListHead *cur, *next;
drmBONode *first, *curNode, *nextNode;
cur = list->list.next;
if (cur == &list->list)
return NULL;
first = DRMLISTENTRY(DrmBufNode, cur, head);
curNode = DRMLISTENTRY(DrmBufNode, cur, head);
first = DRMLISTENTRY(drmBONode, cur, head);
curNode = DRMLISTENTRY(drmBONode, cur, head);
for (next = cur->next; next != &list->list;
cur = next, next = cur->next) {
nextNode = DRMLISTENTRY(DrmBufNode, next, head);
nextNode = DRMLISTENTRY(drmBONode, next, head);
curNode->bo_arg.req.next = ((unsigned long) &nextNode->bo_arg.req);
curNode = nextNode;
}
@ -2558,4 +2560,143 @@ static drm_bo_arg_t *drmPrepareList(DrmBufList *list)
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)
{
drm_bo_arg_t arg;
drm_bo_arg_request_t *req = &arg.req;
drm_bo_arg_reply_t *rep = &arg.rep;
req->mask = mask;
req->hint = hint;
req->size = size;
req->type = type;
buf->ttm = NULL;
switch(type) {
case drm_bo_type_ttm:
req->arg_handle = ttm->handle;
req->buffer_start = start;
buf->ttm = ttm;
break;
case drm_bo_type_dc:
break;
case drm_bo_type_user:
req->buffer_start = (unsigned long) user_buffer;
buf->virtual = user_buffer;
break;
default:
return -EINVAL;
}
req->op = drm_bo_create;
req->next = 0;
if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg))
return -errno;
if (!rep->handled) {
return -EFAULT;
}
if (rep->ret) {
return rep->ret;
}
buf->handle = rep->handle;
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->virtual = NULL;
buf->mask = rep->mask;
buf->hint = rep->hint;
buf->start = rep->buffer_start;
return 0;
}
int drmBODestroy(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;
req->handle = buf->handle;
req->op = drm_bo_destroy;
req->next = 0;
if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg))
return -errno;
if (!rep->handled) {
return -EFAULT;
}
if (rep->ret) {
return rep->ret;
}
buf->handle = 0;
return 0;
}
int drmBOReference(int fd, unsigned handle, drmBO *buf)
{
drm_bo_arg_t arg;
drm_bo_arg_request_t *req = &arg.req;
drm_bo_arg_reply_t *rep = &arg.rep;
req->handle = handle;
req->op = drm_bo_reference;
req->next = 0;
if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg))
return -errno;
if (!rep->handled) {
return -EFAULT;
}
if (rep->ret) {
return rep->ret;
}
buf->handle = rep->handle;
buf->type = drm_bo_type_dc;
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->virtual = NULL;
buf->mask = rep->mask;
buf->hint = rep->hint;
return 0;
}
int drmBOUnReference(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;
req->handle = buf->handle;
req->op = drm_bo_unreference;
req->next = 0;
if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg))
return -errno;
if (!rep->handled) {
return -EFAULT;
}
if (rep->ret) {
return rep->ret;
}
buf->handle = 0;
return 0;
}
#endif

View File

@ -292,6 +292,8 @@ typedef struct _drmTTM{
drm_handle_t user_token;
unsigned flags;
unsigned long size;
void *virtual;
int mapCount;
} drmTTM;
#define __drm_dummy_lock(lock) (*(__volatile__ unsigned int *)lock)

View File

@ -29,7 +29,7 @@
#ifndef _XF86MM_H_
#define _XF86MM_H_
#include <stddef.h>
#include "xf86drm.h"
/*
* List macros heavily inspired by the Linux kernel
@ -40,7 +40,7 @@ typedef struct _drmMMListHead
{
struct _drmMMListHead *prev;
struct _drmMMListHead *next;
} DrmMMListHead;
} drmMMListHead;
#define DRMINITLISTHEAD(__item) \
do{ \
@ -82,24 +82,37 @@ typedef struct _drmMMListHead
((__type *)(((char *) (__item)) - offsetof(__type, __field)))
typedef struct _DrmBuf{
typedef struct _drmBO{
drm_bo_type_t type;
unsigned handle;
} DrmBuf;
drm_handle_t map_handle;
unsigned flags;
unsigned mask;
unsigned hint;
unsigned map_flags;
unsigned long size;
unsigned long offset;
unsigned long start;
void *virtual;
void *map_virtual;
int map_count;
drmTTM *ttm;
} drmBO;
typedef struct _DrmBufNode {
DrmMMListHead head;
DrmBuf *buf;
typedef struct _drmBONode {
drmMMListHead head;
drmBO *buf;
drm_bo_arg_t bo_arg;
} DrmBufNode;
} drmBONode;
typedef struct _DrmMMBufList {
typedef struct _drmBOList {
unsigned numTarget;
unsigned numCurrent;
unsigned numOnList;
DrmMMListHead list;
DrmMMListHead free;
} DrmBufList;
drmMMListHead list;
drmMMListHead free;
} drmBOList;
#endif

View File

@ -736,6 +736,9 @@ typedef struct drm_bo_arg_reply {
drm_u64_t offset;
unsigned arg_handle;
unsigned map_flags;
unsigned mask;
unsigned hint;
drm_u64_t buffer_start;
}drm_bo_arg_reply_t;
@ -813,6 +816,7 @@ typedef union drm_bo_arg{
#ifdef __linux__
#define DRM_IOCTL_FENCE DRM_IOWR(0x3b, drm_fence_arg_t)
#define DRM_IOCTL_TTM DRM_IOWR(0x3c, drm_ttm_arg_t)
#define DRM_IOCTL_BUFOBJ DRM_IOWR(0x3d, drm_bo_arg_t)
#endif
/*@}*/