summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRob Clark <[email protected]>2015-02-15 00:04:57 -0500
committerRob Clark <[email protected]>2015-02-21 17:11:02 -0500
commite17437386c1bf715b6b241bd9de3a583103f851b (patch)
treeaa7a3c48f16afd40923278109d480d564479bf0c
parent68552266535747bad1eff34d856c43158398b9bf (diff)
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 <[email protected]>
-rw-r--r--src/gallium/drivers/freedreno/freedreno_context.c13
-rw-r--r--src/gallium/drivers/freedreno/freedreno_fence.c60
-rw-r--r--src/gallium/drivers/freedreno/freedreno_fence.h43
-rw-r--r--src/gallium/drivers/freedreno/freedreno_screen.c23
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 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 <[email protected]>
*/
+#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 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
@@ -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);