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@freedesktop.org>
This commit is contained in:
Rob Clark 2015-02-15 00:04:57 -05:00
parent 6855226653
commit e17437386c
4 changed files with 68 additions and 77 deletions

View 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

View File

@ -26,27 +26,67 @@
* 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)
{
DBG("TODO: ");
return false;
}
boolean
fd_fence_signalled(struct fd_fence *fence)
{
DBG("TODO: ");
return false;
}
struct pipe_fence_handle {
struct pipe_reference reference;
struct fd_context *ctx;
uint32_t timestamp;
};
void
fd_fence_del(struct fd_fence *fence)
fd_screen_fence_ref(struct pipe_screen *pscreen,
struct pipe_fence_handle **ptr,
struct pipe_fence_handle *pfence)
{
if (pipe_reference(&(*ptr)->reference, &pfence->reference))
FREE(*ptr);
*ptr = pfence;
}
/* 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)
{
uint32_t timestamp = fd_ringbuffer_timestamp(fence->ctx->ring);
/* TODO util helper for compare w/ rollover? */
return timestamp >= fence->timestamp;
}
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;
}

View File

@ -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_ */

View 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)
{