summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSinclair Yeh <[email protected]>2017-05-15 17:10:38 -0700
committerBrian Paul <[email protected]>2017-07-17 10:09:25 -0600
commitd554f72c41e367d8f9b5f441c45853efd35a162b (patch)
tree8ed010b10998e26d39f5f462353546d1f20aef81 /src
parent56a6e890f32a51c91fa4feb78dc5a1a22e8008d9 (diff)
winsys/svga/drm: Connect winsys-side fence_* functions
Connect fence_get_fd, fence_create_fd, and fence_server_sync. Implement the required functions in vmw_fence module. Reviewed-by: Brian Paul <[email protected]> Reviewed-by: Charmaine Lee <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/gallium/winsys/svga/drm/vmw_fence.c78
-rw-r--r--src/gallium/winsys/svga/drm/vmw_fence.h6
-rw-r--r--src/gallium/winsys/svga/drm/vmw_screen_ioctl.c2
-rw-r--r--src/gallium/winsys/svga/drm/vmw_screen_svga.c33
4 files changed, 109 insertions, 10 deletions
diff --git a/src/gallium/winsys/svga/drm/vmw_fence.c b/src/gallium/winsys/svga/drm/vmw_fence.c
index 5b1ba69930b..061f588c864 100644
--- a/src/gallium/winsys/svga/drm/vmw_fence.c
+++ b/src/gallium/winsys/svga/drm/vmw_fence.c
@@ -22,6 +22,8 @@
* SOFTWARE.
*
**********************************************************/
+#include <libsync.h>
+
#include "util/u_memory.h"
#include "util/u_atomic.h"
#include "util/list.h"
@@ -32,7 +34,7 @@
#include "vmw_screen.h"
#include "vmw_fence.h"
-struct vmw_fence_ops
+struct vmw_fence_ops
{
/*
* Immutable members.
@@ -58,6 +60,8 @@ struct vmw_fence
uint32_t mask;
int32_t signalled;
uint32_t seqno;
+ int32_t fence_fd;
+ boolean imported; /* TRUE if imported from another process */
};
/**
@@ -175,15 +179,16 @@ vmw_fence(struct pipe_fence_handle *fence)
* @fence_ops: The fence_ops manager to register with.
* @handle: Handle identifying the kernel fence object.
* @mask: Mask of flags that this fence object may signal.
+ * @fd: File descriptor to associate with the fence
*
* Returns NULL on failure.
*/
struct pipe_fence_handle *
vmw_fence_create(struct pb_fence_ops *fence_ops, uint32_t handle,
- uint32_t seqno, uint32_t mask)
+ uint32_t seqno, uint32_t mask, int32_t fd)
{
struct vmw_fence *fence = CALLOC_STRUCT(vmw_fence);
- struct vmw_fence_ops *ops = vmw_fence_ops(fence_ops);
+ struct vmw_fence_ops *ops = NULL;
if (!fence)
return NULL;
@@ -192,7 +197,20 @@ vmw_fence_create(struct pb_fence_ops *fence_ops, uint32_t handle,
fence->handle = handle;
fence->mask = mask;
fence->seqno = seqno;
+ fence->fence_fd = fd;
p_atomic_set(&fence->signalled, 0);
+
+ /*
+ * If the fence was not created by our device, then we won't
+ * manage it with our ops
+ */
+ if (!fence_ops) {
+ fence->imported = true;
+ return (struct pipe_fence_handle *) fence;
+ }
+
+ ops = vmw_fence_ops(fence_ops);
+
mtx_lock(&ops->mutex);
if (vmw_fence_seq_is_signaled(seqno, ops->last_signaled, seqno)) {
@@ -210,6 +228,21 @@ vmw_fence_create(struct pb_fence_ops *fence_ops, uint32_t handle,
/**
+ * vmw_fence_destroy - Frees a vmw fence object.
+ *
+ * Also closes the file handle associated with the object, if any
+ */
+static
+void vmw_fence_destroy(struct vmw_fence *vfence)
+{
+ if (vfence->fence_fd != -1)
+ close(vfence->fence_fd);
+
+ FREE(vfence);
+}
+
+
+/**
* vmw_fence_reference - Reference / unreference a vmw fence object.
*
* @vws: Pointer to the winsys screen.
@@ -227,13 +260,15 @@ vmw_fence_reference(struct vmw_winsys_screen *vws,
if (p_atomic_dec_zero(&vfence->refcount)) {
struct vmw_fence_ops *ops = vmw_fence_ops(vws->fence_ops);
- vmw_ioctl_fence_unref(vws, vfence->handle);
+ if (!vfence->imported) {
+ vmw_ioctl_fence_unref(vws, vfence->handle);
- mtx_lock(&ops->mutex);
- LIST_DELINIT(&vfence->ops_list);
- mtx_unlock(&ops->mutex);
+ mtx_lock(&ops->mutex);
+ LIST_DELINIT(&vfence->ops_list);
+ mtx_unlock(&ops->mutex);
+ }
- FREE(vfence);
+ vmw_fence_destroy(vfence);
}
}
@@ -321,6 +356,16 @@ vmw_fence_finish(struct vmw_winsys_screen *vws,
return 0;
vfence = vmw_fence(fence);
+
+ if (vfence->imported) {
+ ret = sync_wait(vfence->fence_fd, timeout / 1000000);
+
+ if (!ret)
+ p_atomic_set(&vfence->signalled, 1);
+
+ return !!ret;
+ }
+
old = p_atomic_read(&vfence->signalled);
vflags &= ~vfence->mask;
@@ -341,6 +386,23 @@ vmw_fence_finish(struct vmw_winsys_screen *vws,
return ret;
}
+/**
+ * vmw_fence_get_fd
+ *
+ * Returns the file descriptor associated with the fence
+ */
+int
+vmw_fence_get_fd(struct pipe_fence_handle *fence)
+{
+ struct vmw_fence *vfence;
+
+ if (!fence)
+ return -1;
+
+ vfence = vmw_fence(fence);
+ return vfence->fence_fd;
+}
+
/**
* vmw_fence_ops_fence_reference - wrapper for the pb_fence_ops api.
diff --git a/src/gallium/winsys/svga/drm/vmw_fence.h b/src/gallium/winsys/svga/drm/vmw_fence.h
index 31e1350c316..aab558f6b3d 100644
--- a/src/gallium/winsys/svga/drm/vmw_fence.h
+++ b/src/gallium/winsys/svga/drm/vmw_fence.h
@@ -38,13 +38,17 @@ struct vmw_winsys_screen;
struct pipe_fence_handle *
vmw_fence_create(struct pb_fence_ops *fence_ops,
- uint32_t handle, uint32_t seqno, uint32_t mask);
+ uint32_t handle, uint32_t seqno, uint32_t mask, int32_t fd);
int
vmw_fence_finish(struct vmw_winsys_screen *vws,
struct pipe_fence_handle *fence,
uint64_t timeout,
unsigned flag);
+
+int
+vmw_fence_get_fd(struct pipe_fence_handle *fence);
+
int
vmw_fence_signalled(struct vmw_winsys_screen *vws,
struct pipe_fence_handle *fence,
diff --git a/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c b/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
index 1740d1ab062..aad5ff98105 100644
--- a/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
+++ b/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
@@ -475,7 +475,7 @@ vmw_ioctl_command(struct vmw_winsys_screen *vws, int32_t cid,
TRUE);
*pfence = vmw_fence_create(vws->fence_ops, rep.handle,
- rep.seqno, rep.mask);
+ rep.seqno, rep.mask, -1);
if (*pfence == NULL) {
/*
* Fence creation failed. Need to sync.
diff --git a/src/gallium/winsys/svga/drm/vmw_screen_svga.c b/src/gallium/winsys/svga/drm/vmw_screen_svga.c
index 46335378e0a..7c80642b377 100644
--- a/src/gallium/winsys/svga/drm/vmw_screen_svga.c
+++ b/src/gallium/winsys/svga/drm/vmw_screen_svga.c
@@ -32,6 +32,7 @@
* @author Jose Fonseca
*/
+#include <libsync.h>
#include "svga_cmd.h"
#include "svga3d_caps.h"
@@ -132,6 +133,35 @@ vmw_svga_winsys_fence_finish(struct svga_winsys_screen *sws,
}
+static int
+vmw_svga_winsys_fence_get_fd(struct svga_winsys_screen *sws,
+ struct pipe_fence_handle *fence,
+ boolean duplicate)
+{
+ if (duplicate)
+ return dup(vmw_fence_get_fd(fence));
+ else
+ return vmw_fence_get_fd(fence);
+}
+
+
+static void
+vmw_svga_winsys_fence_create_fd(struct svga_winsys_screen *sws,
+ struct pipe_fence_handle **fence,
+ int32_t fd)
+{
+ *fence = vmw_fence_create(NULL, 0, 0, 0, dup(fd));
+}
+
+static int
+vmw_svga_winsys_fence_server_sync(struct svga_winsys_screen *sws,
+ int32_t *context_fd,
+ struct pipe_fence_handle *fence)
+{
+ return sync_accumulate("vmwgfx", context_fd,
+ sws->fence_get_fd(sws, fence, FALSE));
+}
+
static struct svga_winsys_surface *
vmw_svga_winsys_surface_create(struct svga_winsys_screen *sws,
@@ -435,6 +465,9 @@ vmw_winsys_screen_init_svga(struct vmw_winsys_screen *vws)
vws->base.shader_create = vmw_svga_winsys_shader_create;
vws->base.shader_destroy = vmw_svga_winsys_shader_destroy;
vws->base.fence_finish = vmw_svga_winsys_fence_finish;
+ vws->base.fence_get_fd = vmw_svga_winsys_fence_get_fd;
+ vws->base.fence_create_fd = vmw_svga_winsys_fence_create_fd;
+ vws->base.fence_server_sync = vmw_svga_winsys_fence_server_sync;
vws->base.query_create = vmw_svga_winsys_query_create;
vws->base.query_init = vmw_svga_winsys_query_init;