summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2017-10-11 14:46:25 +0200
committerThierry Reding <treding@nvidia.com>2018-04-04 16:23:13 +0200
commit35f7b746238ab2c4eae13c22dc54c666192757d4 (patch)
tree3c3bf333795695605f0c48d478bbe6e28f691384
parentbce1b10c711bc9f7fc73961fb4c37ee9b8414e53 (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.h5
-rw-r--r--src/gallium/drivers/nouveau/nouveau_fence.c18
-rw-r--r--src/gallium/drivers/nouveau/nouveau_fence.h2
-rw-r--r--src/gallium/drivers/nouveau/nouveau_screen.c37
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_context.c19
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_screen.c2
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 d14c59b2dd1..b508b9b7163 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 c144b39b2dd..d2c01d98ecc 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"
@@ -86,6 +88,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,
@@ -239,6 +249,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);
@@ -296,8 +307,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 2e4490b8d97..609a5abbef8 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 b4a2c676f59..adc50598354 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
@@ -254,6 +254,7 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_COMPUTE:
case PIPE_CAP_CAN_BIND_CONST_BUFFER_AS_VERTEX:
case PIPE_CAP_ALLOW_MAPPED_BUFFERS_DURING_EXECUTION:
+ 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;
@@ -293,7 +294,6 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_PCI_FUNCTION:
case PIPE_CAP_VIEWPORT_SUBPIXEL_BITS:
case PIPE_CAP_TGSI_CAN_READ_OUTPUTS:
- case PIPE_CAP_NATIVE_FENCE_FD:
case PIPE_CAP_GLSL_OPTIMIZE_CONSERVATIVELY:
case PIPE_CAP_INT64_DIVMOD:
case PIPE_CAP_SPARSE_BUFFER_PAGE_SIZE: