Lines Matching refs:fence
33 nouveau_fence_new(struct nouveau_screen *screen, struct nouveau_fence **fence)
35 *fence = CALLOC_STRUCT(nouveau_fence);
36 if (!*fence)
39 (*fence)->screen = screen;
40 (*fence)->ref = 1;
41 list_inithead(&(*fence)->work);
47 nouveau_fence_trigger_work(struct nouveau_fence *fence)
51 LIST_FOR_EACH_ENTRY_SAFE(work, tmp, &fence->work, list) {
59 nouveau_fence_emit(struct nouveau_fence *fence)
61 struct nouveau_screen *screen = fence->screen;
63 assert(fence->state == NOUVEAU_FENCE_STATE_AVAILABLE);
65 /* set this now, so that if fence.emit triggers a flush we don't recurse */
66 fence->state = NOUVEAU_FENCE_STATE_EMITTING;
68 ++fence->ref;
70 if (screen->fence.tail)
71 screen->fence.tail->next = fence;
73 screen->fence.head = fence;
75 screen->fence.tail = fence;
77 screen->fence.emit(&screen->base, &fence->sequence);
79 assert(fence->state == NOUVEAU_FENCE_STATE_EMITTING);
80 fence->state = NOUVEAU_FENCE_STATE_EMITTED;
84 nouveau_fence_del(struct nouveau_fence *fence)
87 struct nouveau_screen *screen = fence->screen;
89 if (fence->state == NOUVEAU_FENCE_STATE_EMITTED ||
90 fence->state == NOUVEAU_FENCE_STATE_FLUSHED) {
91 if (fence == screen->fence.head) {
92 screen->fence.head = fence->next;
93 if (!screen->fence.head)
94 screen->fence.tail = NULL;
96 for (it = screen->fence.head; it && it->next != fence; it = it->next);
97 it->next = fence->next;
98 if (screen->fence.tail == fence)
99 screen->fence.tail = it;
103 if (!list_is_empty(&fence->work)) {
104 debug_printf("WARNING: deleting fence with work still pending !\n");
105 nouveau_fence_trigger_work(fence);
108 FREE(fence);
114 if (screen->fence.current) {
117 /* nouveau_fence_wait will create a new current fence, so wait on the
120 nouveau_fence_ref(screen->fence.current, ¤t);
123 nouveau_fence_ref(NULL, &screen->fence.current);
130 struct nouveau_fence *fence;
132 u32 sequence = screen->fence.update(&screen->base);
138 sequence = screen->fence.sequence;
140 if (screen->fence.sequence_ack == sequence)
142 screen->fence.sequence_ack = sequence;
144 for (fence = screen->fence.head; fence; fence = next) {
145 next = fence->next;
146 sequence = fence->sequence;
148 fence->state = NOUVEAU_FENCE_STATE_SIGNALLED;
150 nouveau_fence_trigger_work(fence);
151 nouveau_fence_ref(NULL, &fence);
153 if (sequence == screen->fence.sequence_ack)
156 screen->fence.head = next;
158 screen->fence.tail = NULL;
161 for (fence = next; fence; fence = fence->next)
162 if (fence->state == NOUVEAU_FENCE_STATE_EMITTED)
163 fence->state = NOUVEAU_FENCE_STATE_FLUSHED;
170 nouveau_fence_signalled(struct nouveau_fence *fence)
172 struct nouveau_screen *screen = fence->screen;
174 if (fence->state == NOUVEAU_FENCE_STATE_SIGNALLED)
177 if (fence->state >= NOUVEAU_FENCE_STATE_EMITTED)
180 return fence->state == NOUVEAU_FENCE_STATE_SIGNALLED;
184 nouveau_fence_kick(struct nouveau_fence *fence)
186 struct nouveau_screen *screen = fence->screen;
188 /* wtf, someone is waiting on a fence in flush_notify handler? */
189 assert(fence->state != NOUVEAU_FENCE_STATE_EMITTING);
191 if (fence->state < NOUVEAU_FENCE_STATE_EMITTED) {
194 * current fence. So check again.
196 if (fence->state < NOUVEAU_FENCE_STATE_EMITTED)
197 nouveau_fence_emit(fence);
200 if (fence->state < NOUVEAU_FENCE_STATE_FLUSHED)
204 if (fence == screen->fence.current)
213 nouveau_fence_wait(struct nouveau_fence *fence, struct util_debug_callback *debug)
215 struct nouveau_screen *screen = fence->screen;
222 if (!nouveau_fence_kick(fence))
226 if (fence->state == NOUVEAU_FENCE_STATE_SIGNALLED) {
229 "stalled %.3f ms waiting for fence",
244 debug_printf("Wait on fence %u (ack = %u, next = %u) timed out !\n",
245 fence->sequence,
246 screen->fence.sequence_ack, screen->fence.sequence);
254 if (screen->fence.current->state < NOUVEAU_FENCE_STATE_EMITTING) {
255 if (screen->fence.current->ref > 1)
256 nouveau_fence_emit(screen->fence.current);
261 nouveau_fence_ref(NULL, &screen->fence.current);
263 nouveau_fence_new(screen, &screen->fence.current);
275 nouveau_fence_work(struct nouveau_fence *fence,
280 if (!fence || fence->state == NOUVEAU_FENCE_STATE_SIGNALLED) {
290 list_add(&work->list, &fence->work);
291 p_atomic_inc(&fence->work_count);
292 if (fence->work_count > 64)
293 nouveau_fence_kick(fence);