mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-07 02:10:12 +01:00
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 <brianp@vmware.com> Reviewed-by: Charmaine Lee <charmainel@vmware.com>
This commit is contained in:
parent
56a6e890f3
commit
d554f72c41
4 changed files with 109 additions and 10 deletions
|
|
@ -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)) {
|
||||
|
|
@ -209,6 +227,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.
|
||||
*
|
||||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue