diff options
author | Jason Ekstrand <[email protected]> | 2015-11-14 07:56:10 -0800 |
---|---|---|
committer | Jason Ekstrand <[email protected]> | 2015-11-14 07:56:10 -0800 |
commit | 1469ccb7464836c752fa2664c36d8fae7e80606c (patch) | |
tree | 6f15e2eeb7e16e4085a0c58d50a36a4c12b231a5 /src/gallium/drivers/nouveau/nouveau_fence.c | |
parent | e8f51fe4deb5082fece5f8cb167b89b0f03eb244 (diff) | |
parent | f94e1d97381ec787c2abbbcd5265252596217e33 (diff) |
Merge remote-tracking branch 'mesa-public/master' into vulkan
This pulls in Matt's big compiler refactor.
Diffstat (limited to 'src/gallium/drivers/nouveau/nouveau_fence.c')
-rw-r--r-- | src/gallium/drivers/nouveau/nouveau_fence.c | 78 |
1 files changed, 52 insertions, 26 deletions
diff --git a/src/gallium/drivers/nouveau/nouveau_fence.c b/src/gallium/drivers/nouveau/nouveau_fence.c index 21cf2b9ae5e..691553ae7e4 100644 --- a/src/gallium/drivers/nouveau/nouveau_fence.c +++ b/src/gallium/drivers/nouveau/nouveau_fence.c @@ -23,6 +23,7 @@ #include "nouveau_screen.h" #include "nouveau_winsys.h" #include "nouveau_fence.h" +#include "os/os_time.h" #ifdef PIPE_OS_UNIX #include <sched.h> @@ -58,26 +59,6 @@ nouveau_fence_trigger_work(struct nouveau_fence *fence) } } -bool -nouveau_fence_work(struct nouveau_fence *fence, - void (*func)(void *), void *data) -{ - struct nouveau_fence_work *work; - - if (!fence || fence->state == NOUVEAU_FENCE_STATE_SIGNALLED) { - func(data); - return true; - } - - work = CALLOC_STRUCT(nouveau_fence_work); - if (!work) - return false; - work->func = func; - work->data = data; - LIST_ADD(&work->list, &fence->work); - return true; -} - void nouveau_fence_emit(struct nouveau_fence *fence) { @@ -181,11 +162,10 @@ nouveau_fence_signalled(struct nouveau_fence *fence) return fence->state == NOUVEAU_FENCE_STATE_SIGNALLED; } -bool -nouveau_fence_wait(struct nouveau_fence *fence) +static bool +nouveau_fence_kick(struct nouveau_fence *fence) { struct nouveau_screen *screen = fence->screen; - uint32_t spins = 0; /* wtf, someone is waiting on a fence in flush_notify handler? */ assert(fence->state != NOUVEAU_FENCE_STATE_EMITTING); @@ -206,11 +186,32 @@ nouveau_fence_wait(struct nouveau_fence *fence) if (fence == screen->fence.current) nouveau_fence_next(screen); - do { - nouveau_fence_update(screen, false); + nouveau_fence_update(screen, false); + + return true; +} - if (fence->state == NOUVEAU_FENCE_STATE_SIGNALLED) +bool +nouveau_fence_wait(struct nouveau_fence *fence, struct pipe_debug_callback *debug) +{ + struct nouveau_screen *screen = fence->screen; + uint32_t spins = 0; + int64_t start = 0; + + if (debug && debug->debug_message) + start = os_time_get_nano(); + + if (!nouveau_fence_kick(fence)) + return false; + + do { + if (fence->state == NOUVEAU_FENCE_STATE_SIGNALLED) { + if (debug && debug->debug_message) + pipe_debug_message(debug, PERF_INFO, + "stalled %.3f ms waiting for fence", + (os_time_get_nano() - start) / 1000000.f); return true; + } if (!spins) NOUVEAU_DRV_STAT(screen, any_non_kernel_fence_sync_count, 1); spins++; @@ -218,6 +219,8 @@ nouveau_fence_wait(struct nouveau_fence *fence) if (!(spins % 8)) /* donate a few cycles */ sched_yield(); #endif + + nouveau_fence_update(screen, false); } while (spins < NOUVEAU_FENCE_MAX_SPINS); debug_printf("Wait on fence %u (ack = %u, next = %u) timed out !\n", @@ -249,3 +252,26 @@ nouveau_fence_unref_bo(void *data) nouveau_bo_ref(NULL, &bo); } + +bool +nouveau_fence_work(struct nouveau_fence *fence, + void (*func)(void *), void *data) +{ + struct nouveau_fence_work *work; + + if (!fence || fence->state == NOUVEAU_FENCE_STATE_SIGNALLED) { + func(data); + return true; + } + + work = CALLOC_STRUCT(nouveau_fence_work); + if (!work) + return false; + work->func = func; + work->data = data; + LIST_ADD(&work->list, &fence->work); + p_atomic_inc(&fence->work_count); + if (fence->work_count > 64) + nouveau_fence_kick(fence); + return true; +} |