00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include <xf86drm.h>
00034 #include <stdlib.h>
00035 #include <stdio.h>
00036 #include "pipe/p_thread.h"
00037 #include "errno.h"
00038 #include "ws_dri_bufmgr.h"
00039 #include "string.h"
00040 #include "pipe/p_debug.h"
00041 #include "ws_dri_bufpool.h"
00042 #include "ws_dri_fencemgr.h"
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 pipe_static_mutex(bmMutex);
00055 pipe_static_condvar(bmCond);
00056
00057 static int kernelReaders = 0;
00058 static int num_buffers = 0;
00059 static int num_user_buffers = 0;
00060
00061 static drmBO *drmBOListBuf(void *iterator)
00062 {
00063 drmBONode *node;
00064 drmMMListHead *l = (drmMMListHead *) iterator;
00065 node = DRMLISTENTRY(drmBONode, l, head);
00066 return node->buf;
00067 }
00068
00069 static void *drmBOListIterator(drmBOList *list)
00070 {
00071 void *ret = list->list.next;
00072
00073 if (ret == &list->list)
00074 return NULL;
00075 return ret;
00076 }
00077
00078 static void *drmBOListNext(drmBOList *list, void *iterator)
00079 {
00080 void *ret;
00081
00082 drmMMListHead *l = (drmMMListHead *) iterator;
00083 ret = l->next;
00084 if (ret == &list->list)
00085 return NULL;
00086 return ret;
00087 }
00088
00089 static drmBONode *drmAddListItem(drmBOList *list, drmBO *item,
00090 uint64_t arg0,
00091 uint64_t arg1)
00092 {
00093 drmBONode *node;
00094 drmMMListHead *l;
00095
00096 l = list->free.next;
00097 if (l == &list->free) {
00098 node = (drmBONode *) malloc(sizeof(*node));
00099 if (!node) {
00100 return NULL;
00101 }
00102 list->numCurrent++;
00103 }
00104 else {
00105 DRMLISTDEL(l);
00106 node = DRMLISTENTRY(drmBONode, l, head);
00107 }
00108 node->buf = item;
00109 node->arg0 = arg0;
00110 node->arg1 = arg1;
00111 DRMLISTADD(&node->head, &list->list);
00112 list->numOnList++;
00113 return node;
00114 }
00115
00116 static int drmAddValidateItem(drmBOList *list, drmBO *buf, uint64_t flags,
00117 uint64_t mask, int *newItem)
00118 {
00119 drmBONode *node, *cur;
00120 drmMMListHead *l;
00121
00122 *newItem = 0;
00123 cur = NULL;
00124
00125 for (l = list->list.next; l != &list->list; l = l->next) {
00126 node = DRMLISTENTRY(drmBONode, l, head);
00127 if (node->buf == buf) {
00128 cur = node;
00129 break;
00130 }
00131 }
00132 if (!cur) {
00133 cur = drmAddListItem(list, buf, flags, mask);
00134 if (!cur) {
00135 return -ENOMEM;
00136 }
00137 *newItem = 1;
00138 cur->arg0 = flags;
00139 cur->arg1 = mask;
00140 }
00141 else {
00142 uint64_t memFlags = cur->arg0 & flags & DRM_BO_MASK_MEM;
00143 uint64_t accFlags = (cur->arg0 | flags) & ~DRM_BO_MASK_MEM;
00144
00145 if (mask & cur->arg1 & ~DRM_BO_MASK_MEM & (cur->arg0 ^ flags)) {
00146 return -EINVAL;
00147 }
00148
00149 cur->arg1 |= mask;
00150 cur->arg0 = (cur->arg0 & ~mask) | ((memFlags | accFlags) & mask);
00151
00152 if (((cur->arg1 & DRM_BO_MASK_MEM) != 0) &&
00153 (cur->arg0 & DRM_BO_MASK_MEM) == 0) {
00154 return -EINVAL;
00155 }
00156 }
00157 return 0;
00158 }
00159
00160 static void drmBOFreeList(drmBOList *list)
00161 {
00162 drmBONode *node;
00163 drmMMListHead *l;
00164
00165 l = list->list.next;
00166 while(l != &list->list) {
00167 DRMLISTDEL(l);
00168 node = DRMLISTENTRY(drmBONode, l, head);
00169 free(node);
00170 l = list->list.next;
00171 list->numCurrent--;
00172 list->numOnList--;
00173 }
00174
00175 l = list->free.next;
00176 while(l != &list->free) {
00177 DRMLISTDEL(l);
00178 node = DRMLISTENTRY(drmBONode, l, head);
00179 free(node);
00180 l = list->free.next;
00181 list->numCurrent--;
00182 }
00183 }
00184
00185 static int drmAdjustListNodes(drmBOList *list)
00186 {
00187 drmBONode *node;
00188 drmMMListHead *l;
00189 int ret = 0;
00190
00191 while(list->numCurrent < list->numTarget) {
00192 node = (drmBONode *) malloc(sizeof(*node));
00193 if (!node) {
00194 ret = -ENOMEM;
00195 break;
00196 }
00197 list->numCurrent++;
00198 DRMLISTADD(&node->head, &list->free);
00199 }
00200
00201 while(list->numCurrent > list->numTarget) {
00202 l = list->free.next;
00203 if (l == &list->free)
00204 break;
00205 DRMLISTDEL(l);
00206 node = DRMLISTENTRY(drmBONode, l, head);
00207 free(node);
00208 list->numCurrent--;
00209 }
00210 return ret;
00211 }
00212
00213 static int drmBOCreateList(int numTarget, drmBOList *list)
00214 {
00215 DRMINITLISTHEAD(&list->list);
00216 DRMINITLISTHEAD(&list->free);
00217 list->numTarget = numTarget;
00218 list->numCurrent = 0;
00219 list->numOnList = 0;
00220 return drmAdjustListNodes(list);
00221 }
00222
00223 static int drmBOResetList(drmBOList *list)
00224 {
00225 drmMMListHead *l;
00226 int ret;
00227
00228 ret = drmAdjustListNodes(list);
00229 if (ret)
00230 return ret;
00231
00232 l = list->list.next;
00233 while (l != &list->list) {
00234 DRMLISTDEL(l);
00235 DRMLISTADD(l, &list->free);
00236 list->numOnList--;
00237 l = list->list.next;
00238 }
00239 return drmAdjustListNodes(list);
00240 }
00241
00242 void driWriteLockKernelBO(void)
00243 {
00244 pipe_mutex_lock(bmMutex);
00245 while(kernelReaders != 0)
00246 pipe_condvar_wait(bmCond, bmMutex);
00247 }
00248
00249 void driWriteUnlockKernelBO(void)
00250 {
00251 pipe_mutex_unlock(bmMutex);
00252 }
00253
00254 void driReadLockKernelBO(void)
00255 {
00256 pipe_mutex_lock(bmMutex);
00257 kernelReaders++;
00258 pipe_mutex_unlock(bmMutex);
00259 }
00260
00261 void driReadUnlockKernelBO(void)
00262 {
00263 pipe_mutex_lock(bmMutex);
00264 if (--kernelReaders == 0)
00265 pipe_condvar_broadcast(bmCond);
00266 pipe_mutex_unlock(bmMutex);
00267 }
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277 typedef struct _DriBufferObject
00278 {
00279 DriBufferPool *pool;
00280 pipe_mutex mutex;
00281 int refCount;
00282 const char *name;
00283 uint64_t flags;
00284 unsigned hint;
00285 unsigned alignment;
00286 unsigned createdByReference;
00287 void *private;
00288
00289 unsigned userBuffer;
00290 void *userData;
00291 unsigned userSize;
00292 } DriBufferObject;
00293
00294 typedef struct _DriBufferList {
00295 drmBOList drmBuffers;
00296 drmBOList driBuffers;
00297 } DriBufferList;
00298
00299
00300 void
00301 bmError(int val, const char *file, const char *function, int line)
00302 {
00303 printf("Fatal video memory manager error \"%s\".\n"
00304 "Check kernel logs or set the LIBGL_DEBUG\n"
00305 "environment variable to \"verbose\" for more info.\n"
00306 "Detected in file %s, line %d, function %s.\n",
00307 strerror(-val), file, line, function);
00308 #ifndef NDEBUG
00309 abort();
00310 #else
00311 abort();
00312 #endif
00313 }
00314
00315 extern drmBO *
00316 driBOKernel(struct _DriBufferObject *buf)
00317 {
00318 drmBO *ret;
00319
00320 driReadLockKernelBO();
00321 pipe_mutex_lock(buf->mutex);
00322 assert(buf->private != NULL);
00323 ret = buf->pool->kernel(buf->pool, buf->private);
00324 if (!ret)
00325 BM_CKFATAL(-EINVAL);
00326 pipe_mutex_unlock(buf->mutex);
00327 driReadUnlockKernelBO();
00328
00329 return ret;
00330 }
00331
00332 void
00333 driBOWaitIdle(struct _DriBufferObject *buf, int lazy)
00334 {
00335
00336
00337
00338
00339
00340
00341 pipe_mutex_lock(buf->mutex);
00342 BM_CKFATAL(buf->pool->waitIdle(buf->pool, buf->private, &buf->mutex, lazy));
00343 pipe_mutex_unlock(buf->mutex);
00344 }
00345
00346 void *
00347 driBOMap(struct _DriBufferObject *buf, unsigned flags, unsigned hint)
00348 {
00349 void *virtual;
00350 int retval;
00351
00352 if (buf->userBuffer) {
00353 return buf->userData;
00354 }
00355
00356 pipe_mutex_lock(buf->mutex);
00357 assert(buf->private != NULL);
00358 retval = buf->pool->map(buf->pool, buf->private, flags, hint,
00359 &buf->mutex, &virtual);
00360 pipe_mutex_unlock(buf->mutex);
00361
00362 return retval == 0 ? virtual : NULL;
00363 }
00364
00365 void
00366 driBOUnmap(struct _DriBufferObject *buf)
00367 {
00368 if (buf->userBuffer)
00369 return;
00370
00371 assert(buf->private != NULL);
00372 pipe_mutex_lock(buf->mutex);
00373 BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private));
00374 pipe_mutex_unlock(buf->mutex);
00375 }
00376
00377 unsigned long
00378 driBOOffset(struct _DriBufferObject *buf)
00379 {
00380 unsigned long ret;
00381
00382 assert(buf->private != NULL);
00383
00384 pipe_mutex_lock(buf->mutex);
00385 ret = buf->pool->offset(buf->pool, buf->private);
00386 pipe_mutex_unlock(buf->mutex);
00387 return ret;
00388 }
00389
00390 unsigned long
00391 driBOPoolOffset(struct _DriBufferObject *buf)
00392 {
00393 unsigned long ret;
00394
00395 assert(buf->private != NULL);
00396
00397 pipe_mutex_lock(buf->mutex);
00398 ret = buf->pool->poolOffset(buf->pool, buf->private);
00399 pipe_mutex_unlock(buf->mutex);
00400 return ret;
00401 }
00402
00403 uint64_t
00404 driBOFlags(struct _DriBufferObject *buf)
00405 {
00406 uint64_t ret;
00407
00408 assert(buf->private != NULL);
00409
00410 driReadLockKernelBO();
00411 pipe_mutex_lock(buf->mutex);
00412 ret = buf->pool->flags(buf->pool, buf->private);
00413 pipe_mutex_unlock(buf->mutex);
00414 driReadUnlockKernelBO();
00415 return ret;
00416 }
00417
00418 struct _DriBufferObject *
00419 driBOReference(struct _DriBufferObject *buf)
00420 {
00421 pipe_mutex_lock(buf->mutex);
00422 if (++buf->refCount == 1) {
00423 pipe_mutex_unlock(buf->mutex);
00424 BM_CKFATAL(-EINVAL);
00425 }
00426 pipe_mutex_unlock(buf->mutex);
00427 return buf;
00428 }
00429
00430 void
00431 driBOUnReference(struct _DriBufferObject *buf)
00432 {
00433 int tmp;
00434
00435 if (!buf)
00436 return;
00437
00438 pipe_mutex_lock(buf->mutex);
00439 tmp = --buf->refCount;
00440 if (!tmp) {
00441 pipe_mutex_unlock(buf->mutex);
00442 if (buf->private) {
00443 if (buf->createdByReference)
00444 buf->pool->unreference(buf->pool, buf->private);
00445 else
00446 buf->pool->destroy(buf->pool, buf->private);
00447 }
00448 if (buf->userBuffer)
00449 num_user_buffers--;
00450 else
00451 num_buffers--;
00452 free(buf);
00453 } else
00454 pipe_mutex_unlock(buf->mutex);
00455
00456 }
00457
00458
00459 int
00460 driBOData(struct _DriBufferObject *buf,
00461 unsigned size, const void *data,
00462 DriBufferPool *newPool,
00463 uint64_t flags)
00464 {
00465 void *virtual = NULL;
00466 int newBuffer;
00467 int retval = 0;
00468 struct _DriBufferPool *pool;
00469
00470 assert(!buf->userBuffer);
00471
00472 pipe_mutex_lock(buf->mutex);
00473 pool = buf->pool;
00474
00475 if (pool == NULL && newPool != NULL) {
00476 buf->pool = newPool;
00477 pool = newPool;
00478 }
00479 if (newPool == NULL)
00480 newPool = pool;
00481
00482 if (!pool->create) {
00483 assert((size_t)"driBOData called on invalid buffer\n" & 0);
00484 BM_CKFATAL(-EINVAL);
00485 }
00486
00487 newBuffer = (!buf->private || pool != newPool ||
00488 pool->size(pool, buf->private) < size);
00489
00490 if (!flags)
00491 flags = buf->flags;
00492
00493 if (newBuffer) {
00494
00495 if (buf->createdByReference) {
00496 assert((size_t)"driBOData requiring resizing called on shared buffer.\n" & 0);
00497 BM_CKFATAL(-EINVAL);
00498 }
00499
00500 if (buf->private)
00501 buf->pool->destroy(buf->pool, buf->private);
00502
00503 pool = newPool;
00504 buf->pool = newPool;
00505 buf->private = pool->create(pool, size, flags, DRM_BO_HINT_DONT_FENCE,
00506 buf->alignment);
00507 if (!buf->private)
00508 retval = -ENOMEM;
00509
00510 if (retval == 0)
00511 retval = pool->map(pool, buf->private,
00512 DRM_BO_FLAG_WRITE,
00513 DRM_BO_HINT_DONT_BLOCK, &buf->mutex, &virtual);
00514 } else if (pool->map(pool, buf->private, DRM_BO_FLAG_WRITE,
00515 DRM_BO_HINT_DONT_BLOCK, &buf->mutex, &virtual)) {
00516
00517
00518
00519
00520 void *newBuf;
00521
00522 newBuf = pool->create(pool, size, flags, DRM_BO_HINT_DONT_FENCE,
00523 buf->alignment);
00524 if (newBuf) {
00525 buf->pool->destroy(buf->pool, buf->private);
00526 buf->private = newBuf;
00527 }
00528
00529 retval = pool->map(pool, buf->private,
00530 DRM_BO_FLAG_WRITE, 0, &buf->mutex, &virtual);
00531 } else {
00532 uint64_t flag_diff = flags ^ buf->flags;
00533
00534
00535
00536
00537
00538 if (flag_diff){
00539 assert(pool->setStatus != NULL);
00540 BM_CKFATAL(pool->unmap(pool, buf->private));
00541 BM_CKFATAL(pool->setStatus(pool, buf->private, flag_diff,
00542 buf->flags));
00543 if (!data)
00544 goto out;
00545
00546 retval = pool->map(pool, buf->private,
00547 DRM_BO_FLAG_WRITE, 0, &buf->mutex, &virtual);
00548 }
00549 }
00550
00551 if (retval == 0) {
00552 if (data)
00553 memcpy(virtual, data, size);
00554
00555 BM_CKFATAL(pool->unmap(pool, buf->private));
00556 }
00557
00558 out:
00559 pipe_mutex_unlock(buf->mutex);
00560
00561 return retval;
00562 }
00563
00564 void
00565 driBOSubData(struct _DriBufferObject *buf,
00566 unsigned long offset, unsigned long size, const void *data)
00567 {
00568 void *virtual;
00569
00570 assert(!buf->userBuffer);
00571
00572 pipe_mutex_lock(buf->mutex);
00573 if (size && data) {
00574 BM_CKFATAL(buf->pool->map(buf->pool, buf->private,
00575 DRM_BO_FLAG_WRITE, 0, &buf->mutex,
00576 &virtual));
00577 memcpy((unsigned char *) virtual + offset, data, size);
00578 BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private));
00579 }
00580 pipe_mutex_unlock(buf->mutex);
00581 }
00582
00583 void
00584 driBOGetSubData(struct _DriBufferObject *buf,
00585 unsigned long offset, unsigned long size, void *data)
00586 {
00587 void *virtual;
00588
00589 assert(!buf->userBuffer);
00590
00591 pipe_mutex_lock(buf->mutex);
00592 if (size && data) {
00593 BM_CKFATAL(buf->pool->map(buf->pool, buf->private,
00594 DRM_BO_FLAG_READ, 0, &buf->mutex, &virtual));
00595 memcpy(data, (unsigned char *) virtual + offset, size);
00596 BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private));
00597 }
00598 pipe_mutex_unlock(buf->mutex);
00599 }
00600
00601 void
00602 driBOSetReferenced(struct _DriBufferObject *buf,
00603 unsigned long handle)
00604 {
00605 pipe_mutex_lock(buf->mutex);
00606 if (buf->private != NULL) {
00607 assert((size_t)"Invalid buffer for setReferenced\n" & 0);
00608 BM_CKFATAL(-EINVAL);
00609
00610 }
00611 if (buf->pool->reference == NULL) {
00612 assert((size_t)"Invalid buffer pool for setReferenced\n" & 0);
00613 BM_CKFATAL(-EINVAL);
00614 }
00615 buf->private = buf->pool->reference(buf->pool, handle);
00616 if (!buf->private) {
00617 assert((size_t)"Invalid buffer pool for setStatic\n" & 0);
00618 BM_CKFATAL(-ENOMEM);
00619 }
00620 buf->createdByReference = TRUE;
00621 buf->flags = buf->pool->kernel(buf->pool, buf->private)->flags;
00622 pipe_mutex_unlock(buf->mutex);
00623 }
00624
00625 int
00626 driGenBuffers(struct _DriBufferPool *pool,
00627 const char *name,
00628 unsigned n,
00629 struct _DriBufferObject *buffers[],
00630 unsigned alignment, uint64_t flags, unsigned hint)
00631 {
00632 struct _DriBufferObject *buf;
00633 int i;
00634
00635 flags = (flags) ? flags : DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_MEM_VRAM |
00636 DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE;
00637
00638 ++num_buffers;
00639
00640 assert(pool);
00641
00642 for (i = 0; i < n; ++i) {
00643 buf = (struct _DriBufferObject *) calloc(1, sizeof(*buf));
00644 if (!buf)
00645 return -ENOMEM;
00646
00647 pipe_mutex_init(buf->mutex);
00648 pipe_mutex_lock(buf->mutex);
00649 buf->refCount = 1;
00650 buf->flags = flags;
00651 buf->hint = hint;
00652 buf->name = name;
00653 buf->alignment = alignment;
00654 buf->pool = pool;
00655 buf->createdByReference = 0;
00656 pipe_mutex_unlock(buf->mutex);
00657 buffers[i] = buf;
00658 }
00659 return 0;
00660 }
00661
00662 void
00663 driGenUserBuffer(struct _DriBufferPool *pool,
00664 const char *name,
00665 struct _DriBufferObject **buffers,
00666 void *ptr, unsigned bytes)
00667 {
00668 const unsigned alignment = 1, flags = 0, hint = 0;
00669
00670 --num_buffers;
00671 driGenBuffers(pool, name, 1, buffers, alignment, flags, hint);
00672 ++num_user_buffers;
00673
00674 (*buffers)->userBuffer = 1;
00675 (*buffers)->userData = ptr;
00676 (*buffers)->userSize = bytes;
00677 }
00678
00679 void
00680 driDeleteBuffers(unsigned n, struct _DriBufferObject *buffers[])
00681 {
00682 int i;
00683
00684 for (i = 0; i < n; ++i) {
00685 driBOUnReference(buffers[i]);
00686 }
00687 }
00688
00689
00690 void
00691 driInitBufMgr(int fd)
00692 {
00693 ;
00694 }
00695
00696
00697
00698
00699
00700 struct _DriBufferList *
00701 driBOCreateList(int target)
00702 {
00703 struct _DriBufferList *list = calloc(sizeof(*list), 1);
00704
00705 BM_CKFATAL(drmBOCreateList(target, &list->drmBuffers));
00706 BM_CKFATAL(drmBOCreateList(target, &list->driBuffers));
00707 return list;
00708 }
00709
00710 int
00711 driBOResetList(struct _DriBufferList * list)
00712 {
00713 int ret;
00714 ret = drmBOResetList(&list->drmBuffers);
00715 if (ret)
00716 return ret;
00717 ret = drmBOResetList(&list->driBuffers);
00718 return ret;
00719 }
00720
00721 void
00722 driBOFreeList(struct _DriBufferList * list)
00723 {
00724 drmBOFreeList(&list->drmBuffers);
00725 drmBOFreeList(&list->driBuffers);
00726 free(list);
00727 }
00728
00729
00730
00731
00732
00733
00734 static drmBONode *
00735 driAddListItem(drmBOList * list, drmBO * item,
00736 uint64_t arg0, uint64_t arg1)
00737 {
00738 drmBONode *node;
00739 drmMMListHead *l;
00740
00741 l = list->free.next;
00742 if (l == &list->free) {
00743 node = (drmBONode *) malloc(sizeof(*node));
00744 if (!node) {
00745 return NULL;
00746 }
00747 list->numCurrent++;
00748 } else {
00749 DRMLISTDEL(l);
00750 node = DRMLISTENTRY(drmBONode, l, head);
00751 }
00752 memset(&node->bo_arg, 0, sizeof(node->bo_arg));
00753 node->buf = item;
00754 node->arg0 = arg0;
00755 node->arg1 = arg1;
00756 DRMLISTADDTAIL(&node->head, &list->list);
00757 list->numOnList++;
00758 return node;
00759 }
00760
00761
00762
00763
00764
00765
00766 static int
00767 driAddValidateItem(drmBOList * list, drmBO * buf, uint64_t flags,
00768 uint64_t mask, int *itemLoc,
00769 struct _drmBONode **pnode)
00770 {
00771 drmBONode *node, *cur;
00772 drmMMListHead *l;
00773 int count = 0;
00774
00775 cur = NULL;
00776
00777 for (l = list->list.next; l != &list->list; l = l->next) {
00778 node = DRMLISTENTRY(drmBONode, l, head);
00779 if (node->buf == buf) {
00780 cur = node;
00781 break;
00782 }
00783 count++;
00784 }
00785 if (!cur) {
00786 cur = driAddListItem(list, buf, flags, mask);
00787 if (!cur)
00788 return -ENOMEM;
00789
00790 cur->arg0 = flags;
00791 cur->arg1 = mask;
00792 } else {
00793 uint64_t memFlags = cur->arg0 & flags & DRM_BO_MASK_MEM;
00794 uint64_t accFlags = (cur->arg0 | flags) & ~DRM_BO_MASK_MEM;
00795
00796 if (mask & cur->arg1 & ~DRM_BO_MASK_MEM & (cur->arg0 ^ flags)) {
00797 return -EINVAL;
00798 }
00799
00800 cur->arg1 |= mask;
00801 cur->arg0 = (cur->arg0 & ~mask) | ((memFlags | accFlags) & mask);
00802
00803 if (((cur->arg1 & DRM_BO_MASK_MEM) != 0) &&
00804 (cur->arg0 & DRM_BO_MASK_MEM) == 0) {
00805 return -EINVAL;
00806 }
00807 }
00808 *itemLoc = count;
00809 *pnode = cur;
00810 return 0;
00811 }
00812
00813
00814 void
00815 driBOAddListItem(struct _DriBufferList * list, struct _DriBufferObject *buf,
00816 uint64_t flags, uint64_t mask, int *itemLoc,
00817 struct _drmBONode **node)
00818 {
00819 int newItem;
00820
00821 pipe_mutex_lock(buf->mutex);
00822 BM_CKFATAL(driAddValidateItem(&list->drmBuffers,
00823 buf->pool->kernel(buf->pool, buf->private),
00824 flags, mask, itemLoc, node));
00825 BM_CKFATAL(drmAddValidateItem(&list->driBuffers, (drmBO *) buf,
00826 flags, mask, &newItem));
00827 if (newItem)
00828 buf->refCount++;
00829
00830 pipe_mutex_unlock(buf->mutex);
00831 }
00832
00833 drmBOList *driGetdrmBOList(struct _DriBufferList *list)
00834 {
00835 driWriteLockKernelBO();
00836 return &list->drmBuffers;
00837 }
00838
00839 void driPutdrmBOList(struct _DriBufferList *list)
00840 {
00841 driWriteUnlockKernelBO();
00842 }
00843
00844
00845 void
00846 driBOFence(struct _DriBufferObject *buf, struct _DriFenceObject *fence)
00847 {
00848 pipe_mutex_lock(buf->mutex);
00849 if (buf->pool->fence)
00850 BM_CKFATAL(buf->pool->fence(buf->pool, buf->private, fence));
00851 pipe_mutex_unlock(buf->mutex);
00852
00853 }
00854
00855 void
00856 driBOUnrefUserList(struct _DriBufferList *list)
00857 {
00858 struct _DriBufferObject *buf;
00859 void *curBuf;
00860
00861 curBuf = drmBOListIterator(&list->driBuffers);
00862 while (curBuf) {
00863 buf = (struct _DriBufferObject *)drmBOListBuf(curBuf);
00864 driBOUnReference(buf);
00865 curBuf = drmBOListNext(&list->driBuffers, curBuf);
00866 }
00867 }
00868
00869 struct _DriFenceObject *
00870 driBOFenceUserList(struct _DriFenceMgr *mgr,
00871 struct _DriBufferList *list, const char *name,
00872 drmFence *kFence)
00873 {
00874 struct _DriFenceObject *fence;
00875 struct _DriBufferObject *buf;
00876 void *curBuf;
00877
00878 fence = driFenceCreate(mgr, kFence->fence_class, kFence->type,
00879 kFence, sizeof(*kFence));
00880 curBuf = drmBOListIterator(&list->driBuffers);
00881
00882
00883
00884
00885
00886 while (curBuf) {
00887 buf = (struct _DriBufferObject *) drmBOListBuf(curBuf);
00888 driBOFence(buf, fence);
00889 driBOUnReference(buf);
00890 curBuf = drmBOListNext(&list->driBuffers, curBuf);
00891 }
00892
00893 driBOResetList(list);
00894 return fence;
00895 }
00896
00897 void
00898 driBOValidateUserList(struct _DriBufferList * list)
00899 {
00900 void *curBuf;
00901 struct _DriBufferObject *buf;
00902
00903 curBuf = drmBOListIterator(&list->driBuffers);
00904
00905
00906
00907
00908
00909 while (curBuf) {
00910 buf = (struct _DriBufferObject *) drmBOListBuf(curBuf);
00911 pipe_mutex_lock(buf->mutex);
00912 if (buf->pool->validate)
00913 BM_CKFATAL(buf->pool->validate(buf->pool, buf->private, &buf->mutex));
00914 pipe_mutex_unlock(buf->mutex);
00915 curBuf = drmBOListNext(&list->driBuffers, curBuf);
00916 }
00917 }
00918
00919
00920 void
00921 driPoolTakeDown(struct _DriBufferPool *pool)
00922 {
00923 pool->takeDown(pool);
00924
00925 }
00926
00927 unsigned long
00928 driBOSize(struct _DriBufferObject *buf)
00929 {
00930 unsigned long size;
00931
00932 pipe_mutex_lock(buf->mutex);
00933 size = buf->pool->size(buf->pool, buf->private);
00934 pipe_mutex_unlock(buf->mutex);
00935
00936 return size;
00937
00938 }
00939
00940 drmBOList *driBOGetDRMBuffers(struct _DriBufferList *list)
00941 {
00942 return &list->drmBuffers;
00943 }
00944
00945 drmBOList *driBOGetDRIBuffers(struct _DriBufferList *list)
00946 {
00947 return &list->driBuffers;
00948 }
00949