From e17437386c1bf715b6b241bd9de3a583103f851b Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Sun, 15 Feb 2015 00:04:57 -0500 Subject: [PATCH] freedreno: implement fence I never actually implemented the stubbed out fence stuff back in the early days. Fix that. We'll need a few libdrm_freedreno changes to handle timeout properly, so ignore that for now to avoid a libdrm_freedreno dependency bump. Signed-off-by: Rob Clark --- .../drivers/freedreno/freedreno_context.c | 13 ++-- .../drivers/freedreno/freedreno_fence.c | 68 +++++++++++++++---- .../drivers/freedreno/freedreno_fence.h | 41 +++-------- .../drivers/freedreno/freedreno_screen.c | 23 ------- 4 files changed, 68 insertions(+), 77 deletions(-) diff --git a/src/gallium/drivers/freedreno/freedreno_context.c b/src/gallium/drivers/freedreno/freedreno_context.c index f7e63fdb2d4..79a27fe0e15 100644 --- a/src/gallium/drivers/freedreno/freedreno_context.c +++ b/src/gallium/drivers/freedreno/freedreno_context.c @@ -28,6 +28,7 @@ #include "freedreno_context.h" #include "freedreno_draw.h" +#include "freedreno_fence.h" #include "freedreno_program.h" #include "freedreno_resource.h" #include "freedreno_texture.h" @@ -125,16 +126,10 @@ static void fd_context_flush(struct pipe_context *pctx, struct pipe_fence_handle **fence, unsigned flags) { - DBG("fence=%p", fence); - -#if 0 - if (fence) { - fd_fence_ref(ctx->screen->fence.current, - (struct fd_fence **)fence); - } -#endif - fd_context_render(pctx); + + if (fence) + *fence = fd_fence_create(pctx); } void diff --git a/src/gallium/drivers/freedreno/freedreno_fence.c b/src/gallium/drivers/freedreno/freedreno_fence.c index e6374655f5b..46b057d9062 100644 --- a/src/gallium/drivers/freedreno/freedreno_fence.c +++ b/src/gallium/drivers/freedreno/freedreno_fence.c @@ -26,27 +26,67 @@ * Rob Clark */ +#include "util/u_inlines.h" + #include "freedreno_fence.h" +#include "freedreno_context.h" #include "freedreno_util.h" -boolean -fd_fence_wait(struct fd_fence *fence) -{ - DBG("TODO: "); - return false; -} - -boolean -fd_fence_signalled(struct fd_fence *fence) -{ - DBG("TODO: "); - return false; -} +struct pipe_fence_handle { + struct pipe_reference reference; + struct fd_context *ctx; + uint32_t timestamp; +}; void -fd_fence_del(struct fd_fence *fence) +fd_screen_fence_ref(struct pipe_screen *pscreen, + struct pipe_fence_handle **ptr, + struct pipe_fence_handle *pfence) { + if (pipe_reference(&(*ptr)->reference, &pfence->reference)) + FREE(*ptr); + *ptr = pfence; } +/* TODO we need to spiff out libdrm_freedreno a bit to allow passing + * the timeout.. and maybe a better way to check if fence has been + * signaled. The current implementation is a bit lame for now to + * avoid bumping libdrm version requirement. + */ +boolean fd_screen_fence_signalled(struct pipe_screen *screen, + struct pipe_fence_handle *fence) +{ + uint32_t timestamp = fd_ringbuffer_timestamp(fence->ctx->ring); + + /* TODO util helper for compare w/ rollover? */ + return timestamp >= fence->timestamp; +} + +boolean fd_screen_fence_finish(struct pipe_screen *screen, + struct pipe_fence_handle *fence, + uint64_t timeout) +{ + if (fd_pipe_wait(fence->ctx->screen->pipe, fence->timestamp)) + return false; + + return true; +} + +struct pipe_fence_handle * fd_fence_create(struct pipe_context *pctx) +{ + struct pipe_fence_handle *fence; + struct fd_context *ctx = fd_context(pctx); + + fence = CALLOC_STRUCT(pipe_fence_handle); + if (!fence) + return NULL; + + pipe_reference_init(&fence->reference, 1); + + fence->ctx = ctx; + fence->timestamp = fd_ringbuffer_timestamp(ctx->ring); + + return fence; +} diff --git a/src/gallium/drivers/freedreno/freedreno_fence.h b/src/gallium/drivers/freedreno/freedreno_fence.h index 7e8bee322dc..e36bcc4d1f2 100644 --- a/src/gallium/drivers/freedreno/freedreno_fence.h +++ b/src/gallium/drivers/freedreno/freedreno_fence.h @@ -29,37 +29,16 @@ #ifndef FREEDRENO_FENCE_H_ #define FREEDRENO_FENCE_H_ -#include "util/u_inlines.h" -#include "util/u_double_list.h" - - -struct fd_fence { - int ref; -}; - -boolean fd_fence_wait(struct fd_fence *fence); -boolean fd_fence_signalled(struct fd_fence *fence); -void fd_fence_del(struct fd_fence *fence); - -static INLINE void -fd_fence_ref(struct fd_fence *fence, struct fd_fence **ref) -{ - if (fence) - ++fence->ref; - - if (*ref) { - if (--(*ref)->ref == 0) - fd_fence_del(*ref); - } - - *ref = fence; -} - -static INLINE struct fd_fence * -fd_fence(struct pipe_fence_handle *fence) -{ - return (struct fd_fence *)fence; -} +#include "pipe/p_context.h" +void fd_screen_fence_ref(struct pipe_screen *pscreen, + struct pipe_fence_handle **ptr, + struct pipe_fence_handle *pfence); +boolean fd_screen_fence_signalled(struct pipe_screen *screen, + struct pipe_fence_handle *pfence); +boolean fd_screen_fence_finish(struct pipe_screen *screen, + struct pipe_fence_handle *pfence, + uint64_t timeout); +struct pipe_fence_handle * fd_fence_create(struct pipe_context *pctx); #endif /* FREEDRENO_FENCE_H_ */ diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c index 044b1bcba61..b17ea580d7e 100644 --- a/src/gallium/drivers/freedreno/freedreno_screen.c +++ b/src/gallium/drivers/freedreno/freedreno_screen.c @@ -103,29 +103,6 @@ fd_screen_get_timestamp(struct pipe_screen *pscreen) return cpu_time + fd_screen(pscreen)->cpu_gpu_time_delta; } -static void -fd_screen_fence_ref(struct pipe_screen *pscreen, - struct pipe_fence_handle **ptr, - struct pipe_fence_handle *pfence) -{ - fd_fence_ref(fd_fence(pfence), (struct fd_fence **)ptr); -} - -static boolean -fd_screen_fence_signalled(struct pipe_screen *screen, - struct pipe_fence_handle *pfence) -{ - return fd_fence_signalled(fd_fence(pfence)); -} - -static boolean -fd_screen_fence_finish(struct pipe_screen *screen, - struct pipe_fence_handle *pfence, - uint64_t timeout) -{ - return fd_fence_wait(fd_fence(pfence)); -} - static void fd_screen_destroy(struct pipe_screen *pscreen) {