freedreno: implement fence
authorRob Clark <robclark@freedesktop.org>
Sun, 15 Feb 2015 05:04:57 +0000 (00:04 -0500)
committerRob Clark <robclark@freedesktop.org>
Sat, 21 Feb 2015 22:11:02 +0000 (17:11 -0500)
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 <robclark@freedesktop.org>
src/gallium/drivers/freedreno/freedreno_context.c
src/gallium/drivers/freedreno/freedreno_fence.c
src/gallium/drivers/freedreno/freedreno_fence.h
src/gallium/drivers/freedreno/freedreno_screen.c

index f7e63fd..79a27fe 100644 (file)
@@ -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
index e637465..46b057d 100644 (file)
  *    Rob Clark <robclark@freedesktop.org>
  */
 
+#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)
+struct pipe_fence_handle {
+       struct pipe_reference reference;
+       struct fd_context *ctx;
+       uint32_t timestamp;
+};
+
+void
+fd_screen_fence_ref(struct pipe_screen *pscreen,
+               struct pipe_fence_handle **ptr,
+               struct pipe_fence_handle *pfence)
 {
-       DBG("TODO: ");
-       return false;
+       if (pipe_reference(&(*ptr)->reference, &pfence->reference))
+               FREE(*ptr);
+
+       *ptr = pfence;
 }
 
-boolean
-fd_fence_signalled(struct fd_fence *fence)
+/* 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)
 {
-       DBG("TODO: ");
-       return false;
+       uint32_t timestamp = fd_ringbuffer_timestamp(fence->ctx->ring);
+
+       /* TODO util helper for compare w/ rollover? */
+       return timestamp >= fence->timestamp;
 }
 
-void
-fd_fence_del(struct fd_fence *fence)
+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;
+}
index 7e8bee3..e36bcc4 100644 (file)
 #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_ */
index 044b1bc..b17ea58 100644 (file)
@@ -104,29 +104,6 @@ fd_screen_get_timestamp(struct pipe_screen *pscreen)
 }
 
 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)
 {
        struct fd_screen *screen = fd_screen(pscreen);