#include "freedreno_context.h"
#include "freedreno_draw.h"
+#include "freedreno_fence.h"
#include "freedreno_program.h"
#include "freedreno_resource.h"
#include "freedreno_texture.h"
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
* 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;
+}
#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_ */
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)
{