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 f7e63fdb2d4b14faffabb48dd88c58fe59b2971b..79a27fe0e1523beb10bf86552ef92adce52828c1 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 e6374655f5b2449c70041b9cfabce2bb5205f361..46b057d90622b47932a8385bed8823127646d794 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 7e8bee322dc7c60413a8f27b92a962dc4ed70dda..e36bcc4d1f2bf106a37bf2ab9155f411f552133c 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 044b1bcba613d4f4ef5029634234f812be3246cf..b17ea580d7e4b856b74f2b32a4d1aebc27e1a56a 100644 (file)
@@ -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)
 {