diff options
Diffstat (limited to 'libdrm')
-rw-r--r-- | libdrm/xf86drm.c | 135 | ||||
-rw-r--r-- | libdrm/xf86mm.h | 105 |
2 files changed, 239 insertions, 1 deletions
diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index 3731ee12..6de6c06f 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -65,6 +65,8 @@ # define _DRM_FREE free # include "drm.h" #endif +#include "xf86mm.h" + /* Not all systems have MAP_FAILED defined */ #ifndef MAP_FAILED @@ -2384,7 +2386,7 @@ int drmTTMCreate(int fd, drmTTM *ttm, unsigned long size, unsigned flags) int drmTTMDestroy(int fd, const drmTTM *ttm) { - drm_ttm_arg_t arg; + drm_ttm_arg_t arg; arg.op = drm_ttm_destroy; arg.handle = ttm->handle; @@ -2425,4 +2427,135 @@ drm_handle_t drmTTMMapHandle(int fd, const drmTTM *ttm) (void) fd; return ttm->user_token; } + +static int drmAdjustListNodes(DrmBufList *list) +{ + DrmBufNode *node; + DrmMMListHead *l; + int ret = 0; + + while(list->numCurrent < list->numTarget) { + node = (DrmBufNode *) malloc(sizeof(*node)); + if (!node) { + ret = -ENOMEM; + break; + } + list->numCurrent++; + DRMLISTADD(&node->head, &list->free); + } + + while(list->numCurrent > list->numTarget) { + l = list->free.next; + if (l == &list->free) + break; + DRMLISTDEL(l); + node = DRMLISTENTRY(DrmBufNode, l, head); + free(node); + list->numCurrent--; + } + return ret; +} + +static void drmFreeList(DrmBufList *list) +{ + DrmBufNode *node; + DrmMMListHead *l; + int ret = 0; + + l = list->list.next; + while(l != &list->list) { + DRMLISTDEL(l); + node = DRMLISTENTRY(DrmBufNode, l, head); + free(node); + l = list->free.next; + list->numCurrent--; + list->numOnList--; + } + + l = list->free.next; + while(l != &list->free) { + DRMLISTDEL(l); + node = DRMLISTENTRY(DrmBufNode, l, head); + free(node); + l = list->free.next; + list->numCurrent--; + } +} + +int drmResetList(DrmBufList *list) { + + DrmMMListHead *l; + int ret; + + ret = drmAdjustListNodes(list); + if (ret) + return ret; + + l = list->list.next; + while(l != &list->list) { + DRMLISTDEL(l); + DRMLISTADD(l, &list->free); + list->numOnList--; + } + return drmAdjustListNodes(list); +} + +static int drmAddListItem(DrmBufList *list, DrmBuf *item, drm_bo_arg_t *arg) +{ + DrmBufNode *node; + DrmMMListHead *l; + + l = list->free.next; + if (l == &list->free) { + node = (DrmBufNode *) malloc(sizeof(*node)); + if (!node) { + return -ENOMEM; + } + list->numCurrent++; + } else { + DRMLISTDEL(l); + node = DRMLISTENTRY(DrmBufNode, l, head); + } + node->buf = item; + DRMLISTADD(&node->head, &list->list); + list->numOnList++; + return 0; +} + +int drmCreateBufList(int numTarget, DrmBufList *list) +{ + DRMINITLISTHEAD(&list->list); + DRMINITLISTHEAD(&list->free); + list->numTarget = numTarget; + list->numCurrent = 0; + list->numOnList = 0; + return drmAdjustListNodes(list); +} + +/* + * Prepare list for IOCTL submission. + */ + +static drm_bo_arg_t *drmPrepareList(DrmBufList *list) +{ + DrmMMListHead *cur, *next; + DrmBufNode *first, *curNode, *nextNode; + + cur = list->list.next; + if (cur == &list->list) + return NULL; + + first = DRMLISTENTRY(DrmBufNode, cur, head); + curNode = DRMLISTENTRY(DrmBufNode, cur, head); + + for (next = cur->next; next != &list->list; + cur = next, next = cur->next) { + nextNode = DRMLISTENTRY(DrmBufNode, 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; +} + #endif diff --git a/libdrm/xf86mm.h b/libdrm/xf86mm.h new file mode 100644 index 00000000..5fb78723 --- /dev/null +++ b/libdrm/xf86mm.h @@ -0,0 +1,105 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND. USA. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ + +#ifndef _XF86MM_H_ +#define _XF86MM_H_ +#include <stddef.h> + + +/* + * List macros heavily inspired by the Linux kernel + * list handling. No list looping yet. + */ + +typedef struct _drmMMListHead +{ + struct _drmMMListHead *prev; + struct _drmMMListHead *next; +} DrmMMListHead; + +#define DRMINITLISTHEAD(__item) \ + do{ \ + (__item)->prev = (__item); \ + (__item)->next = (__item); \ + } while (0) + +#define DRMLISTADD(__item, __list) \ + do { \ + (__item)->prev = (__list); \ + (__item)->next = (__list)->next; \ + (__list)->next->prev = (__item); \ + (__list)->next = (__item); \ + } while (0) + +#define DRMLISTADDTAIL(__item, __list) \ + do { \ + (__item)->next = (__list); \ + (__item)->prev = (__list)->prev; \ + (__list)->prev->next = (__item); \ + (__list)->prev = (__item); \ + } while(0) + +#define DRMLISTDEL(__item) \ + do { \ + (__item)->prev->next = (__item)->next; \ + (__item)->next->prev = (__item)->prev; \ + } while(0) + +#define DRMLISTDELINIT(__item) \ + do { \ + (__item)->prev->next = (__item)->next; \ + (__item)->next->prev = (__item)->prev; \ + (__item)->next = (__item); \ + (__item)->prev = (__item); \ + } while(0) + +#define DRMLISTENTRY(__type, __item, __field) \ + ((__type *)(((char *) (__item)) - offsetof(__type, __field))) + + +typedef struct _DrmBuf{ + unsigned handle; +} DrmBuf; + + +typedef struct _DrmBufNode { + DrmMMListHead head; + DrmBuf *buf; + drm_bo_arg_t bo_arg; +} DrmBufNode; + +typedef struct _DrmMMBufList { + unsigned numTarget; + unsigned numCurrent; + unsigned numOnList; + DrmMMListHead list; + DrmMMListHead free; +} DrmBufList; + + +#endif |