X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Ffreedreno%2Ffreedreno_fence.c;h=e3d200aa3a1cc3910560b9293b089258e02b4711;hb=010ebed72aa82f930067bd49e4cc12469cc4eb6a;hp=46b057d90622b47932a8385bed8823127646d794;hpb=e17437386c1bf715b6b241bd9de3a583103f851b;p=mesa.git diff --git a/src/gallium/drivers/freedreno/freedreno_fence.c b/src/gallium/drivers/freedreno/freedreno_fence.c index 46b057d9062..e3d200aa3a1 100644 --- a/src/gallium/drivers/freedreno/freedreno_fence.c +++ b/src/gallium/drivers/freedreno/freedreno_fence.c @@ -26,6 +26,8 @@ * Rob Clark */ +#include + #include "util/u_inlines.h" #include "freedreno_fence.h" @@ -35,49 +37,71 @@ struct pipe_fence_handle { struct pipe_reference reference; struct fd_context *ctx; + struct fd_screen *screen; + int fence_fd; uint32_t timestamp; }; -void -fd_screen_fence_ref(struct pipe_screen *pscreen, +static void fd_fence_destroy(struct pipe_fence_handle *fence) +{ + if (fence->fence_fd != -1) + close(fence->fence_fd); + FREE(fence); +} + +void fd_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); + fd_fence_destroy(*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_fence_finish(struct pipe_screen *pscreen, + struct pipe_context *ctx, + struct pipe_fence_handle *fence, + uint64_t timeout) +{ + if (fence->fence_fd != -1) { + int ret = sync_wait(fence->fence_fd, timeout / 1000000); + return ret == 0; + } + + if (fd_pipe_wait_timeout(fence->ctx->pipe, fence->timestamp, timeout)) + return false; + + return true; +} + +void fd_create_fence_fd(struct pipe_context *pctx, + struct pipe_fence_handle **pfence, int fd) +{ + *pfence = fd_fence_create(fd_context(pctx), 0, dup(fd)); +} -boolean fd_screen_fence_signalled(struct pipe_screen *screen, +void fd_fence_server_sync(struct pipe_context *pctx, struct pipe_fence_handle *fence) { - uint32_t timestamp = fd_ringbuffer_timestamp(fence->ctx->ring); + struct fd_context *ctx = fd_context(pctx); + struct fd_batch *batch = ctx->batch; - /* TODO util helper for compare w/ rollover? */ - return timestamp >= fence->timestamp; + if (sync_accumulate("freedreno", &batch->in_fence_fd, fence->fence_fd)) { + /* error */ + } } -boolean fd_screen_fence_finish(struct pipe_screen *screen, - struct pipe_fence_handle *fence, - uint64_t timeout) +int fd_fence_get_fd(struct pipe_screen *pscreen, + struct pipe_fence_handle *fence) { - if (fd_pipe_wait(fence->ctx->screen->pipe, fence->timestamp)) - return false; - - return true; + return dup(fence->fence_fd); } -struct pipe_fence_handle * fd_fence_create(struct pipe_context *pctx) +struct pipe_fence_handle * fd_fence_create(struct fd_context *ctx, + uint32_t timestamp, int fence_fd) { struct pipe_fence_handle *fence; - struct fd_context *ctx = fd_context(pctx); fence = CALLOC_STRUCT(pipe_fence_handle); if (!fence) @@ -86,7 +110,9 @@ struct pipe_fence_handle * fd_fence_create(struct pipe_context *pctx) pipe_reference_init(&fence->reference, 1); fence->ctx = ctx; - fence->timestamp = fd_ringbuffer_timestamp(ctx->ring); + fence->screen = ctx->screen; + fence->timestamp = timestamp; + fence->fence_fd = fence_fd; return fence; }