Mesa (master): freedreno: implement fence

Rob Clark robclark at kemper.freedesktop.org
Sat Feb 21 22:11:53 UTC 2015


Module: Mesa
Branch: master
Commit: e17437386c1bf715b6b241bd9de3a583103f851b
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=e17437386c1bf715b6b241bd9de3a583103f851b

Author: Rob Clark <robclark at freedesktop.org>
Date:   Sun Feb 15 00:04:57 2015 -0500

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 <robclark at freedesktop.org>

---

 src/gallium/drivers/freedreno/freedreno_context.c |   13 ++---
 src/gallium/drivers/freedreno/freedreno_fence.c   |   60 +++++++++++++++++----
 src/gallium/drivers/freedreno/freedreno_fence.h   |   43 ++++-----------
 src/gallium/drivers/freedreno/freedreno_screen.c  |   23 --------
 4 files changed, 65 insertions(+), 74 deletions(-)

diff --git a/src/gallium/drivers/freedreno/freedreno_context.c b/src/gallium/drivers/freedreno/freedreno_context.c
index f7e63fd..79a27fe 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 e637465..46b057d 100644
--- a/src/gallium/drivers/freedreno/freedreno_fence.c
+++ b/src/gallium/drivers/freedreno/freedreno_fence.c
@@ -26,27 +26,67 @@
  *    Rob Clark <robclark at 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;
+}
diff --git a/src/gallium/drivers/freedreno/freedreno_fence.h b/src/gallium/drivers/freedreno/freedreno_fence.h
index 7e8bee3..e36bcc4 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 044b1bc..b17ea58 100644
--- a/src/gallium/drivers/freedreno/freedreno_screen.c
+++ b/src/gallium/drivers/freedreno/freedreno_screen.c
@@ -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);




More information about the mesa-commit mailing list