diff options
author | Thierry Reding <treding@nvidia.com> | 2017-10-11 14:46:25 +0200 |
---|---|---|
committer | Thierry Reding <treding@nvidia.com> | 2019-12-04 11:59:04 +0100 |
commit | d102b78756d828afb67656b295bba8ec48ad0998 (patch) | |
tree | 1d43bf4bb2c820e64369de2b43148302a1d4faed | |
parent | 5585b8eaddd6799b4486a749de18ae9a6f03b91c (diff) |
nouveau: Support fence FDs
Implements fence FDs based on new libdrm API and the accompanying IOCTL.
Signed-off-by: Thierry Reding <treding@nvidia.com>
-rw-r--r-- | src/gallium/drivers/nouveau/nouveau_context.h | 5 | ||||
-rw-r--r-- | src/gallium/drivers/nouveau/nouveau_fence.c | 18 | ||||
-rw-r--r-- | src/gallium/drivers/nouveau/nouveau_fence.h | 2 | ||||
-rw-r--r-- | src/gallium/drivers/nouveau/nouveau_screen.c | 37 | ||||
-rw-r--r-- | src/gallium/drivers/nouveau/nvc0/nvc0_context.c | 19 | ||||
-rw-r--r-- | src/gallium/drivers/nouveau/nvc0/nvc0_screen.c | 2 |
6 files changed, 75 insertions, 8 deletions
diff --git a/src/gallium/drivers/nouveau/nouveau_context.h b/src/gallium/drivers/nouveau/nouveau_context.h index c3bbb11bd60..0e40ad2f104 100644 --- a/src/gallium/drivers/nouveau/nouveau_context.h +++ b/src/gallium/drivers/nouveau/nouveau_context.h @@ -54,6 +54,8 @@ struct nouveau_context { uint32_t buf_cache_count; uint32_t buf_cache_frame; } stats; + + int in_fence_fd; }; static inline struct nouveau_context * @@ -99,6 +101,9 @@ nouveau_context_destroy(struct nouveau_context *ctx) if (ctx->scratch.bo[i]) nouveau_bo_ref(NULL, &ctx->scratch.bo[i]); + if (ctx->in_fence_fd >= 0) + close(ctx->in_fence_fd); + FREE(ctx); } diff --git a/src/gallium/drivers/nouveau/nouveau_fence.c b/src/gallium/drivers/nouveau/nouveau_fence.c index a830f8133d7..e637c973a83 100644 --- a/src/gallium/drivers/nouveau/nouveau_fence.c +++ b/src/gallium/drivers/nouveau/nouveau_fence.c @@ -30,7 +30,8 @@ #endif bool -nouveau_fence_new(struct nouveau_screen *screen, struct nouveau_fence **fence) +nouveau_fence_fd(struct nouveau_screen *screen, struct nouveau_fence **fence, + int fd) { *fence = CALLOC_STRUCT(nouveau_fence); if (!*fence) @@ -38,11 +39,18 @@ nouveau_fence_new(struct nouveau_screen *screen, struct nouveau_fence **fence) (*fence)->screen = screen; (*fence)->ref = 1; + (*fence)->fd = dup(fd); list_inithead(&(*fence)->work); return true; } +bool +nouveau_fence_new(struct nouveau_screen *screen, struct nouveau_fence **fence) +{ + return nouveau_fence_fd(screen, fence, -1); +} + static void nouveau_fence_trigger_work(struct nouveau_fence *fence) { @@ -105,6 +113,9 @@ nouveau_fence_del(struct nouveau_fence *fence) nouveau_fence_trigger_work(fence); } + if (fence->fd >= 0) + close(fence->fd); + FREE(fence); } @@ -175,9 +186,10 @@ nouveau_fence_kick(struct nouveau_fence *fence) nouveau_fence_emit(fence); } - if (fence->state < NOUVEAU_FENCE_STATE_FLUSHED) - if (nouveau_pushbuf_kick(screen->pushbuf, screen->pushbuf->channel)) + if (fence->state < NOUVEAU_FENCE_STATE_FLUSHED) { + if (nouveau_pushbuf_kick_fence(screen->pushbuf, screen->pushbuf->channel, &fence->fd)) return false; + } if (fence == screen->fence.current) nouveau_fence_next(screen); diff --git a/src/gallium/drivers/nouveau/nouveau_fence.h b/src/gallium/drivers/nouveau/nouveau_fence.h index e14572bce8f..83a33c5af24 100644 --- a/src/gallium/drivers/nouveau/nouveau_fence.h +++ b/src/gallium/drivers/nouveau/nouveau_fence.h @@ -24,6 +24,7 @@ struct nouveau_fence { struct nouveau_screen *screen; int state; int ref; + int fd; uint32_t sequence; uint32_t work_count; struct list_head work; @@ -32,6 +33,7 @@ struct nouveau_fence { void nouveau_fence_emit(struct nouveau_fence *); void nouveau_fence_del(struct nouveau_fence *); +bool nouveau_fence_fd(struct nouveau_screen *, struct nouveau_fence **, int); bool nouveau_fence_new(struct nouveau_screen *, struct nouveau_fence **); bool nouveau_fence_work(struct nouveau_fence *, void (*)(void *), void *); void nouveau_fence_update(struct nouveau_screen *, bool flushed); diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c index de9cce3812a..7432f14d91f 100644 --- a/src/gallium/drivers/nouveau/nouveau_screen.c +++ b/src/gallium/drivers/nouveau/nouveau_screen.c @@ -1,3 +1,5 @@ +#include <libsync.h> + #include "pipe/p_defines.h" #include "pipe/p_screen.h" #include "pipe/p_state.h" @@ -88,6 +90,14 @@ nouveau_screen_fence_finish(struct pipe_screen *screen, return nouveau_fence_wait(nouveau_fence(pfence), NULL); } +static int +nouveau_screen_fence_get_fd(struct pipe_screen *screen, + struct pipe_fence_handle *pfence) +{ + struct nouveau_fence *fence = nouveau_fence(pfence); + + return dup(fence->fd); +} struct nouveau_bo * nouveau_screen_bo_from_handle(struct pipe_screen *pscreen, @@ -253,6 +263,7 @@ nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev) pscreen->fence_reference = nouveau_screen_fence_ref; pscreen->fence_finish = nouveau_screen_fence_finish; + pscreen->fence_get_fd = nouveau_screen_fence_get_fd; nouveau_disk_cache_create(screen); @@ -314,8 +325,34 @@ nouveau_set_debug_callback(struct pipe_context *pipe, memset(&context->debug, 0, sizeof(context->debug)); } +static void +nouveau_create_fence_fd(struct pipe_context *pipe, + struct pipe_fence_handle **pfence, + int fd, enum pipe_fd_type type) +{ + struct nouveau_screen *screen = nouveau_screen(pipe->screen); + + assert(type == PIPE_FD_TYPE_NATIVE_SYNC); + nouveau_fence_fd(screen, (struct nouveau_fence **)pfence, fd); +} + +static void +nouveau_fence_server_sync(struct pipe_context *pipe, + struct pipe_fence_handle *pfence) +{ + struct nouveau_context *context = nouveau_context(pipe); + struct nouveau_fence *fence = nouveau_fence(pfence); + + sync_accumulate("nouveau", &context->in_fence_fd, fence->fd); +} + void nouveau_context_init(struct nouveau_context *context) { + context->in_fence_fd = -1; + context->pipe.set_debug_callback = nouveau_set_debug_callback; + + context->pipe.create_fence_fd = nouveau_create_fence_fd; + context->pipe.fence_server_sync = nouveau_fence_server_sync; } diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_context.c b/src/gallium/drivers/nouveau/nvc0/nvc0_context.c index 7c73e26f2b1..5aa69fb6937 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_context.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_context.c @@ -30,16 +30,27 @@ static void nvc0_flush(struct pipe_context *pipe, - struct pipe_fence_handle **fence, + struct pipe_fence_handle **pfence, unsigned flags) { struct nvc0_context *nvc0 = nvc0_context(pipe); struct nouveau_screen *screen = &nvc0->screen->base; - if (fence) - nouveau_fence_ref(screen->fence.current, (struct nouveau_fence **)fence); + if (pfence) + nouveau_fence_ref(screen->fence.current, (struct nouveau_fence **)pfence); - PUSH_KICK(nvc0->base.pushbuf); /* fencing handled in kick_notify */ + if (flags & PIPE_FLUSH_FENCE_FD) { + struct nouveau_fence *fence = screen->fence.current; + struct nouveau_pushbuf *pushbuf = nvc0->base.pushbuf; + struct nouveau_object *channel = pushbuf->channel; + int fd = nvc0->base.in_fence_fd; + + nouveau_pushbuf_kick_fence(pushbuf, channel, &fd); + nvc0->base.in_fence_fd = -1; + fence->fd = fd; + } else { + PUSH_KICK(nvc0->base.pushbuf); /* fencing handled in kick_notify */ + } nouveau_context_update_frame_stats(&nvc0->base); } diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c index c7779c26548..d657dbb1e0c 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c @@ -282,6 +282,7 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_TGSI_DIV: case PIPE_CAP_TGSI_ATOMINC_WRAP: case PIPE_CAP_DEMOTE_TO_HELPER_INVOCATION: + case PIPE_CAP_NATIVE_FENCE_FD: return 1; case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER: return nouveau_screen(pscreen)->vram_domain & NOUVEAU_BO_VRAM ? 1 : 0; @@ -334,7 +335,6 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_PCI_DEVICE: case PIPE_CAP_PCI_FUNCTION: case PIPE_CAP_TGSI_CAN_READ_OUTPUTS: - case PIPE_CAP_NATIVE_FENCE_FD: case PIPE_CAP_GLSL_OPTIMIZE_CONSERVATIVELY: case PIPE_CAP_SPARSE_BUFFER_PAGE_SIZE: case PIPE_CAP_NIR_SAMPLERS_AS_DEREF: |