1 /**************************************************************************
3 * Copyright 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
5 * Copyright 2009 Vmware, Inc., Palo Alto, CA., USA
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the
10 * "Software"), to deal in the Software without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sub license, and/or sell copies of the Software, and to
13 * permit persons to whom the Software is furnished to do so, subject to
14 * the following conditions:
16 * The above copyright notice and this permission notice (including the
17 * next paragraph) shall be included in all copies or substantial portions
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
23 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
24 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
25 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
26 * USE OR OTHER DEALINGS IN THE SOFTWARE.
28 **************************************************************************/
30 * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
31 * Keith Whitwell <keithw-at-tungstengraphics-dot-com>
41 #include "wsbm_pool.h"
42 #include "wsbm_manager.h"
43 #include "wsbm_fencemgr.h"
44 #include "wsbm_driver.h"
45 #include "wsbm_priv.h"
46 #include "wsbm_util.h"
47 #include "wsbm_atomic.h"
50 #define WSBM_BODATA_SIZE_ACCEPT 4096
52 #define WSBM_BUFFER_COMPLEX 0
53 #define WSBM_BUFFER_SIMPLE 1
54 #define WSBM_BUFFER_REF 2
64 struct _WsbmListHead list;
65 struct _WsbmListHead free;
66 struct _WsbmListHead *hashTable;
69 struct _WsbmBufferObject
71 /* Left to the client to protect this data for now. */
73 struct _WsbmAtomic refCount;
74 struct _WsbmBufStorage *storage;
79 struct _WsbmBufferPool *pool;
82 struct _WsbmBufferList
86 struct _ValidateList kernelBuffers; /* List of kernel buffers needing validation */
87 struct _ValidateList userBuffers; /* List of user-space buffers needing validation */
90 static struct _WsbmMutex bmMutex;
91 static struct _WsbmCond bmCond;
92 static int initialized = 0;
93 static void *commonData = NULL;
95 static int kernelReaders = 0;
96 static int kernelLocked = 0;
99 wsbmInit(struct _WsbmThreadFuncs *tf, struct _WsbmVNodeFuncs *vf)
103 wsbmCurThreadFunc = tf;
104 wsbmCurVNodeFunc = vf;
106 ret = WSBM_MUTEX_INIT(&bmMutex);
109 ret = WSBM_COND_INIT(&bmCond);
111 WSBM_MUTEX_FREE(&bmMutex);
120 wsbmCommonDataSet(void *d)
126 wsbmCommonDataGet(void)
132 wsbmIsInitialized(void)
142 WSBM_COND_FREE(&bmCond);
143 WSBM_MUTEX_FREE(&bmMutex);
146 static struct _ValidateNode *
147 validateListAddNode(struct _ValidateList *list, void *item,
148 uint32_t hash, uint64_t flags, uint64_t mask)
150 struct _ValidateNode *node;
151 struct _WsbmListHead *l;
152 struct _WsbmListHead *hashHead;
155 if (l == &list->free) {
156 node = wsbmVNodeFuncs()->alloc(wsbmVNodeFuncs(), 0);
163 node = WSBMLISTENTRY(l, struct _ValidateNode, head);
166 node->set_flags = flags & mask;
167 node->clr_flags = (~flags) & mask;
168 node->listItem = list->numOnList;
169 WSBMLISTADDTAIL(&node->head, &list->list);
171 hashHead = list->hashTable + hash;
172 WSBMLISTADDTAIL(&node->hashHead, hashHead);
178 wsbmHashFunc(uint8_t * key, uint32_t len, uint32_t mask)
182 for (hash = 0, i = 0; i < len; ++i) {
184 hash += (hash << 10);
189 hash ^= (hash >> 11);
190 hash += (hash << 15);
196 validateFreeList(struct _ValidateList *list)
198 struct _ValidateNode *node;
199 struct _WsbmListHead *l;
202 while (l != &list->list) {
204 node = WSBMLISTENTRY(l, struct _ValidateNode, head);
206 WSBMLISTDEL(&node->hashHead);
207 node->func->free(node);
214 while (l != &list->free) {
216 node = WSBMLISTENTRY(l, struct _ValidateNode, head);
218 node->func->free(node);
222 free(list->hashTable);
226 validateListAdjustNodes(struct _ValidateList *list)
228 struct _ValidateNode *node;
229 struct _WsbmListHead *l;
232 while (list->numCurrent < list->numTarget) {
233 node = wsbmVNodeFuncs()->alloc(wsbmVNodeFuncs(), list->driverData);
239 WSBMLISTADD(&node->head, &list->free);
242 while (list->numCurrent > list->numTarget) {
244 if (l == &list->free)
247 node = WSBMLISTENTRY(l, struct _ValidateNode, head);
249 node->func->free(node);
256 wsbmPot(unsigned int val)
258 unsigned int shift = 0;
259 while(val > (1 << shift))
268 validateCreateList(int numTarget, struct _ValidateList *list, int driverData)
271 unsigned int shift = wsbmPot(numTarget);
274 list->hashSize = (1 << shift);
275 list->hashMask = list->hashSize - 1;
277 list->hashTable = malloc(list->hashSize * sizeof(*list->hashTable));
278 if (!list->hashTable)
281 for (i = 0; i < list->hashSize; ++i)
282 WSBMINITLISTHEAD(&list->hashTable[i]);
284 WSBMINITLISTHEAD(&list->list);
285 WSBMINITLISTHEAD(&list->free);
286 list->numTarget = numTarget;
287 list->numCurrent = 0;
289 list->driverData = driverData;
290 ret = validateListAdjustNodes(list);
292 free(list->hashTable);
298 validateResetList(struct _ValidateList *list)
300 struct _WsbmListHead *l;
301 struct _ValidateNode *node;
304 ret = validateListAdjustNodes(list);
309 while (l != &list->list) {
311 node = WSBMLISTENTRY(l, struct _ValidateNode, head);
313 WSBMLISTDEL(&node->hashHead);
314 WSBMLISTADD(l, &list->free);
318 return validateListAdjustNodes(list);
322 wsbmWriteLockKernelBO(void)
324 WSBM_MUTEX_LOCK(&bmMutex);
325 while (kernelReaders != 0)
326 WSBM_COND_WAIT(&bmCond, &bmMutex);
331 wsbmWriteUnlockKernelBO(void)
334 WSBM_MUTEX_UNLOCK(&bmMutex);
338 wsbmReadLockKernelBO(void)
340 WSBM_MUTEX_LOCK(&bmMutex);
341 if (kernelReaders++ == 0)
343 WSBM_MUTEX_UNLOCK(&bmMutex);
347 wsbmReadUnlockKernelBO(void)
349 WSBM_MUTEX_LOCK(&bmMutex);
350 if (--kernelReaders == 0) {
352 WSBM_COND_BROADCAST(&bmCond);
354 WSBM_MUTEX_UNLOCK(&bmMutex);
358 wsbmBOWaitIdle(struct _WsbmBufferObject *buf, int lazy)
360 struct _WsbmBufStorage *storage;
362 storage = buf->storage;
366 (void)storage->pool->waitIdle(storage, lazy);
370 wsbmBOMap(struct _WsbmBufferObject *buf, unsigned mode)
372 struct _WsbmBufStorage *storage = buf->storage;
376 retval = storage->pool->map(storage, mode, &virtual);
378 return (retval == 0) ? virtual : NULL;
382 wsbmBOUnmap(struct _WsbmBufferObject *buf)
384 struct _WsbmBufStorage *storage = buf->storage;
389 storage->pool->unmap(storage);
393 wsbmBOSyncForCpu(struct _WsbmBufferObject *buf, unsigned mode)
395 struct _WsbmBufStorage *storage = buf->storage;
397 return storage->pool->syncforcpu(storage, mode);
401 wsbmBOReleaseFromCpu(struct _WsbmBufferObject *buf, unsigned mode)
403 struct _WsbmBufStorage *storage = buf->storage;
405 storage->pool->releasefromcpu(storage, mode);
409 wsbmBOOffsetHint(struct _WsbmBufferObject *buf)
411 struct _WsbmBufStorage *storage = buf->storage;
413 return storage->pool->offset(storage);
417 wsbmBOPoolOffset(struct _WsbmBufferObject *buf)
419 struct _WsbmBufStorage *storage = buf->storage;
421 return storage->pool->poolOffset(storage);
425 wsbmBOPlacementHint(struct _WsbmBufferObject * buf)
427 struct _WsbmBufStorage *storage = buf->storage;
429 assert(buf->storage != NULL);
431 return storage->pool->placement(storage);
434 struct _WsbmBufferObject *
435 wsbmBOReference(struct _WsbmBufferObject *buf)
437 if (buf->bufferType == WSBM_BUFFER_SIMPLE) {
438 wsbmAtomicInc(&buf->storage->refCount);
440 wsbmAtomicInc(&buf->refCount);
446 wsbmBOSetStatus(struct _WsbmBufferObject *buf,
447 uint32_t setFlags, uint32_t clrFlags)
449 struct _WsbmBufStorage *storage = buf->storage;
454 if (storage->pool->setStatus == NULL)
457 return storage->pool->setStatus(storage, setFlags, clrFlags);
461 wsbmBOUnreference(struct _WsbmBufferObject **p_buf)
463 struct _WsbmBufferObject *buf = *p_buf;
470 if (buf->bufferType == WSBM_BUFFER_SIMPLE) {
471 struct _WsbmBufStorage *dummy = buf->storage;
473 wsbmBufStorageUnref(&dummy);
477 if (wsbmAtomicDecZero(&buf->refCount)) {
478 wsbmBufStorageUnref(&buf->storage);
484 wsbmBOData(struct _WsbmBufferObject *buf,
485 unsigned size, const void *data,
486 struct _WsbmBufferPool *newPool, uint32_t placement)
488 void *virtual = NULL;
491 struct _WsbmBufStorage *storage;
493 uint32_t placement_diff;
494 struct _WsbmBufferPool *curPool;
496 if (buf->bufferType == WSBM_BUFFER_SIMPLE)
499 storage = buf->storage;
507 newBuffer = (!storage || storage->pool != newPool ||
508 storage->pool->size(storage) < size ||
509 storage->pool->size(storage) >
510 size + WSBM_BODATA_SIZE_ACCEPT);
513 placement = buf->placement;
516 if (buf->bufferType == WSBM_BUFFER_REF)
519 wsbmBufStorageUnref(&buf->storage);
523 buf->placement = placement;
529 newPool->create(newPool, size, placement, buf->alignment);
535 buf->placement = placement;
537 } else if (wsbmAtomicRead(&storage->onList) ||
538 0 != storage->pool->syncforcpu(storage, WSBM_SYNCCPU_WRITE |
539 WSBM_SYNCCPU_DONT_BLOCK)) {
541 * Buffer is busy. need to create a new one.
544 struct _WsbmBufStorage *tmp_storage;
546 curPool = storage->pool;
549 curPool->create(curPool, size, placement, buf->alignment);
552 wsbmBufStorageUnref(&buf->storage);
553 buf->storage = tmp_storage;
554 buf->placement = placement;
556 retval = curPool->syncforcpu(storage, WSBM_SYNCCPU_WRITE);
564 placement_diff = placement ^ buf->placement;
567 * We might need to change buffer placement.
570 storage = buf->storage;
571 curPool = storage->pool;
573 if (placement_diff) {
574 assert(curPool->setStatus != NULL);
575 curPool->releasefromcpu(storage, WSBM_SYNCCPU_WRITE);
576 retval = curPool->setStatus(storage,
577 placement_diff & placement,
578 placement_diff & ~placement);
582 buf->placement = placement;
587 retval = curPool->syncforcpu(buf->storage, WSBM_SYNCCPU_WRITE);
594 storage = buf->storage;
595 curPool = storage->pool;
598 retval = curPool->map(storage, WSBM_ACCESS_WRITE, &virtual);
601 memcpy(virtual, data, size);
602 curPool->unmap(storage);
608 curPool->releasefromcpu(storage, WSBM_SYNCCPU_WRITE);
613 static struct _WsbmBufStorage *
614 wsbmStorageClone(struct _WsbmBufferObject *buf)
616 struct _WsbmBufStorage *storage = buf->storage;
617 struct _WsbmBufferPool *pool = storage->pool;
619 return pool->create(pool, pool->size(storage), buf->placement,
623 struct _WsbmBufferObject *
624 wsbmBOClone(struct _WsbmBufferObject *buf,
625 int (*accelCopy) (struct _WsbmBufferObject *,
626 struct _WsbmBufferObject *))
628 struct _WsbmBufferObject *newBuf;
631 newBuf = malloc(sizeof(*newBuf));
636 newBuf->storage = wsbmStorageClone(buf);
637 if (!newBuf->storage)
640 wsbmAtomicSet(&newBuf->refCount, 1);
641 if (!accelCopy || accelCopy(newBuf, buf) != 0) {
643 struct _WsbmBufferPool *pool = buf->storage->pool;
644 struct _WsbmBufStorage *storage = buf->storage;
645 struct _WsbmBufStorage *newStorage = newBuf->storage;
649 ret = pool->syncforcpu(storage, WSBM_SYNCCPU_READ);
652 ret = pool->map(storage, WSBM_ACCESS_READ, &virtual);
655 ret = pool->map(newStorage, WSBM_ACCESS_WRITE, &nVirtual);
659 memcpy(nVirtual, virtual, pool->size(storage));
660 pool->unmap(newBuf->storage);
661 pool->unmap(buf->storage);
662 pool->releasefromcpu(storage, WSBM_SYNCCPU_READ);
667 buf->pool->unmap(buf->storage);
669 buf->pool->releasefromcpu(buf->storage, WSBM_SYNCCPU_READ);
671 wsbmBufStorageUnref(&newBuf->storage);
678 wsbmBOSubData(struct _WsbmBufferObject *buf,
679 unsigned long offset, unsigned long size, const void *data,
680 int (*accelCopy) (struct _WsbmBufferObject *,
681 struct _WsbmBufferObject *))
685 if (buf->bufferType == WSBM_BUFFER_SIMPLE)
690 struct _WsbmBufStorage *storage = buf->storage;
691 struct _WsbmBufferPool *pool = storage->pool;
693 ret = pool->syncforcpu(storage, WSBM_SYNCCPU_WRITE);
697 if (wsbmAtomicRead(&storage->onList)) {
699 struct _WsbmBufferObject *newBuf;
702 * Another context has this buffer on its validate list.
703 * This should be a very rare situation, but it can be valid,
704 * and therefore we must deal with it by cloning the storage.
707 pool->releasefromcpu(storage, WSBM_SYNCCPU_WRITE);
708 newBuf = wsbmBOClone(buf, accelCopy);
711 * If clone fails we have the choice of either bailing.
712 * (The other context will be happy), or go on and update
713 * the old buffer anyway. (We will be happy). We choose the
718 storage = newBuf->storage;
719 wsbmAtomicInc(&storage->refCount);
720 wsbmBufStorageUnref(&buf->storage);
721 buf->storage = storage;
722 wsbmBOUnreference(&newBuf);
723 pool = storage->pool;
726 ret = pool->syncforcpu(storage, WSBM_SYNCCPU_WRITE);
731 ret = pool->map(storage, WSBM_ACCESS_WRITE, &virtual);
733 pool->releasefromcpu(storage, WSBM_SYNCCPU_WRITE);
737 memcpy((unsigned char *)virtual + offset, data, size);
738 pool->unmap(storage);
739 pool->releasefromcpu(storage, WSBM_SYNCCPU_WRITE);
746 wsbmBOGetSubData(struct _WsbmBufferObject *buf,
747 unsigned long offset, unsigned long size, void *data)
753 struct _WsbmBufStorage *storage = buf->storage;
754 struct _WsbmBufferPool *pool = storage->pool;
756 ret = pool->syncforcpu(storage, WSBM_SYNCCPU_READ);
759 ret = pool->map(storage, WSBM_ACCESS_READ, &virtual);
761 pool->releasefromcpu(storage, WSBM_SYNCCPU_WRITE);
764 memcpy(data, (unsigned char *)virtual + offset, size);
765 pool->unmap(storage);
766 pool->releasefromcpu(storage, WSBM_SYNCCPU_WRITE);
773 wsbmBOSetReferenced(struct _WsbmBufferObject *buf, unsigned long handle)
777 wsbmBufStorageUnref(&buf->storage);
778 if (buf->pool->createByReference == NULL) {
782 buf->storage = buf->pool->createByReference(buf->pool, handle);
787 buf->bufferType = WSBM_BUFFER_REF;
793 wsbmBOFreeSimple(void *ptr)
798 struct _WsbmBufferObject *
799 wsbmBOCreateSimple(struct _WsbmBufferPool *pool,
802 unsigned alignment, size_t extra_size, size_t * offset)
804 struct _WsbmBufferObject *buf;
805 struct _WsbmBufStorage *storage;
807 *offset = (sizeof(*buf) + 15) & ~15;
810 extra_size += *offset - sizeof(*buf);
813 buf = (struct _WsbmBufferObject *)calloc(1, sizeof(*buf) + extra_size);
817 storage = pool->create(pool, size, placement, alignment);
821 storage->destroyContainer = &wsbmBOFreeSimple;
822 storage->destroyArg = buf;
824 buf->storage = storage;
825 buf->alignment = alignment;
827 buf->placement = placement;
828 buf->bufferType = WSBM_BUFFER_SIMPLE;
838 wsbmGenBuffers(struct _WsbmBufferPool *pool,
840 struct _WsbmBufferObject *buffers[],
841 unsigned alignment, uint32_t placement)
843 struct _WsbmBufferObject *buf;
846 placement = (placement) ? placement :
847 WSBM_PL_FLAG_SYSTEM | WSBM_PL_FLAG_CACHED;
849 for (i = 0; i < n; ++i) {
850 buf = (struct _WsbmBufferObject *)calloc(1, sizeof(*buf));
854 wsbmAtomicSet(&buf->refCount, 1);
855 buf->placement = placement;
856 buf->alignment = alignment;
858 buf->bufferType = WSBM_BUFFER_COMPLEX;
865 wsbmDeleteBuffers(unsigned n, struct _WsbmBufferObject *buffers[])
869 for (i = 0; i < n; ++i) {
870 wsbmBOUnreference(&buffers[i]);
875 * Note that lists are per-context and don't need mutex protection.
878 struct _WsbmBufferList *
879 wsbmBOCreateList(int target, int hasKernelBuffers)
881 struct _WsbmBufferList *list = calloc(sizeof(*list), 1);
884 list->hasKernelBuffers = hasKernelBuffers;
885 if (hasKernelBuffers) {
886 ret = validateCreateList(target, &list->kernelBuffers, 0);
891 ret = validateCreateList(target, &list->userBuffers, 1);
893 validateFreeList(&list->kernelBuffers);
901 wsbmBOResetList(struct _WsbmBufferList *list)
905 if (list->hasKernelBuffers) {
906 ret = validateResetList(&list->kernelBuffers);
910 ret = validateResetList(&list->userBuffers);
915 wsbmBOFreeList(struct _WsbmBufferList *list)
917 if (list->hasKernelBuffers)
918 validateFreeList(&list->kernelBuffers);
919 validateFreeList(&list->userBuffers);
924 wsbmAddValidateItem(struct _ValidateList *list, void *buf, uint64_t flags,
925 uint64_t mask, int *itemLoc,
926 struct _ValidateNode **pnode, int *newItem)
928 struct _ValidateNode *node, *cur;
929 struct _WsbmListHead *l;
930 struct _WsbmListHead *hashHead;
933 uint32_t key = (unsigned long) buf;
936 hash = wsbmHashFunc((uint8_t *) &key, 4, list->hashMask);
937 hashHead = list->hashTable + hash;
940 for (l = hashHead->next; l != hashHead; l = l->next) {
942 node = WSBMLISTENTRY(l, struct _ValidateNode, hashHead);
944 if (node->buf == buf) {
951 cur = validateListAddNode(list, buf, hash, flags, mask);
955 cur->func->clear(cur);
957 uint64_t set_flags = flags & mask;
958 uint64_t clr_flags = (~flags) & mask;
960 if (((cur->clr_flags | clr_flags) & WSBM_PL_MASK_MEM) ==
963 * No available memory type left. Bail.
968 if ((cur->set_flags | set_flags) &
969 (cur->clr_flags | clr_flags) & ~WSBM_PL_MASK_MEM) {
971 * Conflicting flags. Bail.
976 cur->set_flags &= ~(clr_flags & WSBM_PL_MASK_MEM);
977 cur->set_flags |= (set_flags & ~WSBM_PL_MASK_MEM);
978 cur->clr_flags |= clr_flags;
980 *itemLoc = cur->listItem;
987 wsbmBOAddListItem(struct _WsbmBufferList *list,
988 struct _WsbmBufferObject *buf,
989 uint64_t flags, uint64_t mask, int *itemLoc,
990 struct _ValidateNode **node)
993 struct _WsbmBufStorage *storage = buf->storage;
996 struct _ValidateNode *dummyNode;
998 if (list->hasKernelBuffers) {
999 ret = wsbmAddValidateItem(&list->kernelBuffers,
1000 storage->pool->kernel(storage),
1001 flags, mask, itemLoc, node, &dummy);
1009 ret = wsbmAddValidateItem(&list->userBuffers, storage,
1010 flags, mask, &dummy, &dummyNode, &newItem);
1015 wsbmAtomicInc(&storage->refCount);
1016 wsbmAtomicInc(&storage->onList);
1024 wsbmBOFence(struct _WsbmBufferObject *buf, struct _WsbmFenceObject *fence)
1026 struct _WsbmBufStorage *storage;
1028 storage = buf->storage;
1029 if (storage->pool->fence)
1030 storage->pool->fence(storage, fence);
1035 wsbmBOOnList(const struct _WsbmBufferObject *buf)
1037 if (buf->storage == NULL)
1039 return wsbmAtomicRead(&buf->storage->onList);
1043 wsbmBOUnrefUserList(struct _WsbmBufferList *list)
1045 struct _WsbmBufStorage *storage;
1048 curBuf = validateListIterator(&list->userBuffers);
1051 storage = (struct _WsbmBufStorage *)(validateListNode(curBuf)->buf);
1052 wsbmAtomicDec(&storage->onList);
1053 wsbmBufStorageUnref(&storage);
1054 curBuf = validateListNext(&list->userBuffers, curBuf);
1057 return wsbmBOResetList(list);
1062 wsbmBOFenceUserList(struct _WsbmBufferList *list,
1063 struct _WsbmFenceObject *fence)
1065 struct _WsbmBufStorage *storage;
1068 curBuf = validateListIterator(&list->userBuffers);
1071 * User-space fencing callbacks.
1075 storage = (struct _WsbmBufStorage *)(validateListNode(curBuf)->buf);
1077 storage->pool->fence(storage, fence);
1078 wsbmAtomicDec(&storage->onList);
1079 wsbmBufStorageUnref(&storage);
1080 curBuf = validateListNext(&list->userBuffers, curBuf);
1083 return wsbmBOResetList(list);
1087 wsbmBOValidateUserList(struct _WsbmBufferList *list)
1090 struct _WsbmBufStorage *storage;
1091 struct _ValidateNode *node;
1094 curBuf = validateListIterator(&list->userBuffers);
1097 * User-space validation callbacks.
1101 node = validateListNode(curBuf);
1102 storage = (struct _WsbmBufStorage *)node->buf;
1103 if (storage->pool->validate) {
1104 ret = storage->pool->validate(storage, node->set_flags,
1109 curBuf = validateListNext(&list->userBuffers, curBuf);
1115 wsbmBOUnvalidateUserList(struct _WsbmBufferList *list)
1118 struct _WsbmBufStorage *storage;
1119 struct _ValidateNode *node;
1121 curBuf = validateListIterator(&list->userBuffers);
1124 * User-space validation callbacks.
1128 node = validateListNode(curBuf);
1129 storage = (struct _WsbmBufStorage *)node->buf;
1130 if (storage->pool->unvalidate) {
1131 storage->pool->unvalidate(storage);
1133 wsbmAtomicDec(&storage->onList);
1134 wsbmBufStorageUnref(&storage);
1135 curBuf = validateListNext(&list->userBuffers, curBuf);
1137 return wsbmBOResetList(list);
1141 wsbmPoolTakeDown(struct _WsbmBufferPool *pool)
1143 pool->takeDown(pool);
1148 wsbmBOSize(struct _WsbmBufferObject *buf)
1151 struct _WsbmBufStorage *storage;
1153 storage = buf->storage;
1154 size = storage->pool->size(storage);
1160 struct _ValidateList *
1161 wsbmGetKernelValidateList(struct _WsbmBufferList *list)
1163 return (list->hasKernelBuffers) ? &list->kernelBuffers : NULL;
1166 struct _ValidateList *
1167 wsbmGetUserValidateList(struct _WsbmBufferList *list)
1169 return &list->userBuffers;
1172 struct _ValidateNode *
1173 validateListNode(void *iterator)
1175 struct _WsbmListHead *l = (struct _WsbmListHead *)iterator;
1177 return WSBMLISTENTRY(l, struct _ValidateNode, head);
1181 validateListIterator(struct _ValidateList *list)
1183 void *ret = list->list.next;
1185 if (ret == &list->list)
1191 validateListNext(struct _ValidateList *list, void *iterator)
1195 struct _WsbmListHead *l = (struct _WsbmListHead *)iterator;
1198 if (ret == &list->list)
1204 wsbmKBufHandle(const struct _WsbmKernelBuf * kBuf)
1206 return kBuf->handle;
1210 wsbmUpdateKBuf(struct _WsbmKernelBuf *kBuf,
1211 uint64_t gpuOffset, uint32_t placement,
1212 uint32_t fence_type_mask)
1214 kBuf->gpuOffset = gpuOffset;
1215 kBuf->placement = placement;
1216 kBuf->fence_type_mask = fence_type_mask;
1219 extern struct _WsbmKernelBuf *
1220 wsbmKBuf(const struct _WsbmBufferObject *buf)
1222 struct _WsbmBufStorage *storage = buf->storage;
1224 return storage->pool->kernel(storage);