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:
parent
6855226653
commit
e17437386c
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue