winsys/svga: Update to vmwgfx kernel module 2.1
Introduces fence objecs and a size limit on query buffers. The possibility to map the fifo from user-space is gone, and replaced by an ioctl that reads the 3D capabilities. Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> Reviewed-by: Jakob Bornecranz <jakob@vmware.com>
This commit is contained in:
parent
e63f2787b6
commit
e7843273fa
|
@ -241,7 +241,7 @@ static boolean svga_get_query_result(struct pipe_context *pipe,
|
|||
if(!wait)
|
||||
return FALSE;
|
||||
|
||||
sws->fence_finish(sws, sq->fence, 0);
|
||||
sws->fence_finish(sws, sq->fence, SVGA_FENCE_FLAG_QUERY);
|
||||
|
||||
state = sq->queryResult->state;
|
||||
}
|
||||
|
|
|
@ -61,7 +61,8 @@ struct winsys_handle;
|
|||
#define SVGA_RELOC_WRITE 0x1
|
||||
#define SVGA_RELOC_READ 0x2
|
||||
|
||||
|
||||
#define SVGA_FENCE_FLAG_EXEC (1 << 0)
|
||||
#define SVGA_FENCE_FLAG_QUERY (1 << 1)
|
||||
|
||||
/** Opaque surface handle */
|
||||
struct svga_winsys_surface;
|
||||
|
|
|
@ -89,8 +89,6 @@ struct vmw_svga_winsys_context
|
|||
|
||||
struct pb_validate *validate;
|
||||
|
||||
uint32_t last_fence;
|
||||
|
||||
/**
|
||||
* The amount of GMR that is referred by the commands currently batched
|
||||
* in the context.
|
||||
|
@ -166,9 +164,7 @@ vmw_swc_flush(struct svga_winsys_context *swc,
|
|||
throttle_us,
|
||||
vswc->command.buffer,
|
||||
vswc->command.used,
|
||||
&vswc->last_fence);
|
||||
|
||||
fence = vmw_pipe_fence(vswc->last_fence);
|
||||
&fence);
|
||||
|
||||
pb_validate_fence(vswc->validate, fence);
|
||||
}
|
||||
|
@ -200,7 +196,9 @@ vmw_swc_flush(struct svga_winsys_context *swc,
|
|||
vswc->seen_regions = 0;
|
||||
|
||||
if(pfence)
|
||||
*pfence = fence;
|
||||
vmw_fence_reference(vswc->vws, pfence, fence);
|
||||
|
||||
vmw_fence_reference(vswc->vws, &fence, NULL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**********************************************************
|
||||
* Copyright 2009 VMware, Inc. All rights reserved.
|
||||
* Copyright 2009-2011 VMware, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
|
@ -22,16 +22,26 @@
|
|||
* SOFTWARE.
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
*
|
||||
* Fencing is currently a bit inefficient, since we need to call the
|
||||
* kernel do determine a fence object signaled status if the fence is not
|
||||
* signaled. This can be greatly improved upon by using the fact that the
|
||||
* execbuf ioctl returns the last signaled fence seqno, as does the
|
||||
* fence signaled ioctl. We should set up a ring of fence objects and
|
||||
* walk through them checking for signaled status each time we receive a
|
||||
* new passed fence seqno.
|
||||
*/
|
||||
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_atomic.h"
|
||||
|
||||
#include "pipebuffer/pb_buffer_fenced.h"
|
||||
|
||||
#include "vmw_screen.h"
|
||||
#include "vmw_fence.h"
|
||||
|
||||
|
||||
|
||||
struct vmw_fence_ops
|
||||
{
|
||||
struct pb_fence_ops base;
|
||||
|
@ -39,7 +49,57 @@ struct vmw_fence_ops
|
|||
struct vmw_winsys_screen *vws;
|
||||
};
|
||||
|
||||
struct vmw_fence
|
||||
{
|
||||
int32_t refcount;
|
||||
uint32_t handle;
|
||||
uint32_t mask;
|
||||
int32_t signalled;
|
||||
};
|
||||
|
||||
/**
|
||||
* vmw_fence - return the vmw_fence object identified by a
|
||||
* struct pipe_fence_handle *
|
||||
*
|
||||
* @fence: The opaque pipe fence handle.
|
||||
*/
|
||||
static INLINE struct vmw_fence *
|
||||
vmw_fence(struct pipe_fence_handle *fence)
|
||||
{
|
||||
return (struct vmw_fence *) fence;
|
||||
}
|
||||
|
||||
/**
|
||||
* vmw_fence_create - Create a user-space fence object.
|
||||
*
|
||||
* @handle: Handle identifying the kernel fence object.
|
||||
* @mask: Mask of flags that this fence object may signal.
|
||||
*
|
||||
* Returns NULL on failure.
|
||||
*/
|
||||
struct pipe_fence_handle *
|
||||
vmw_fence_create(uint32_t handle, uint32_t mask)
|
||||
{
|
||||
struct vmw_fence *fence = CALLOC_STRUCT(vmw_fence);
|
||||
|
||||
if (!fence)
|
||||
return NULL;
|
||||
|
||||
p_atomic_set(&fence->refcount, 1);
|
||||
fence->handle = handle;
|
||||
fence->mask = mask;
|
||||
p_atomic_set(&fence->signalled, 0);
|
||||
|
||||
return (struct pipe_fence_handle *) fence;
|
||||
}
|
||||
|
||||
/**
|
||||
* vmw_fence_ops - Return the vmw_fence_ops structure backing a
|
||||
* struct pb_fence_ops pointer.
|
||||
*
|
||||
* @ops: Pointer to a struct pb_fence_ops.
|
||||
*
|
||||
*/
|
||||
static INLINE struct vmw_fence_ops *
|
||||
vmw_fence_ops(struct pb_fence_ops *ops)
|
||||
{
|
||||
|
@ -48,37 +108,182 @@ vmw_fence_ops(struct pb_fence_ops *ops)
|
|||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* vmw_fence_reference - Reference / unreference a vmw fence object.
|
||||
*
|
||||
* @vws: Pointer to the winsys screen.
|
||||
* @ptr: Pointer to reference transfer destination.
|
||||
* @fence: Pointer to object to reference. May be NULL.
|
||||
*/
|
||||
void
|
||||
vmw_fence_reference(struct vmw_winsys_screen *vws,
|
||||
struct pipe_fence_handle **ptr,
|
||||
struct pipe_fence_handle *fence)
|
||||
{
|
||||
if (*ptr) {
|
||||
struct vmw_fence *vfence = vmw_fence(*ptr);
|
||||
|
||||
if (p_atomic_dec_zero(&vfence->refcount)) {
|
||||
vmw_ioctl_fence_unref(vws, vfence->handle);
|
||||
FREE(vfence);
|
||||
}
|
||||
}
|
||||
|
||||
if (fence) {
|
||||
struct vmw_fence *vfence = vmw_fence(fence);
|
||||
|
||||
p_atomic_inc(&vfence->refcount);
|
||||
}
|
||||
|
||||
*ptr = fence;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* vmw_fence_signalled - Check whether a fence object is signalled.
|
||||
*
|
||||
* @vws: Pointer to the winsys screen.
|
||||
* @fence: Handle to the fence object.
|
||||
* @flag: Fence flags to check. If the fence object can't signal
|
||||
* a flag, it is assumed to be already signaled.
|
||||
*
|
||||
* Returns 0 if the fence object was signaled, nonzero otherwise.
|
||||
*/
|
||||
int
|
||||
vmw_fence_signalled(struct vmw_winsys_screen *vws,
|
||||
struct pipe_fence_handle *fence,
|
||||
unsigned flag)
|
||||
{
|
||||
struct vmw_fence *vfence;
|
||||
int32_t vflags = SVGA_FENCE_FLAG_EXEC;
|
||||
int ret;
|
||||
uint32_t old;
|
||||
|
||||
if (!fence)
|
||||
return 0;
|
||||
|
||||
vfence = vmw_fence(fence);
|
||||
old = p_atomic_read(&vfence->signalled);
|
||||
|
||||
vflags &= ~vfence->mask;
|
||||
|
||||
if ((old & vflags) == vflags)
|
||||
return 0;
|
||||
|
||||
ret = vmw_ioctl_fence_signalled(vws, vfence->handle, vflags);
|
||||
|
||||
if (ret == 0) {
|
||||
int32_t prev = old;
|
||||
|
||||
do {
|
||||
old = prev;
|
||||
prev = p_atomic_cmpxchg(&vfence->signalled, old, old | vflags);
|
||||
} while (prev != old);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* vmw_fence_finish - Wait for a fence object to signal.
|
||||
*
|
||||
* @vws: Pointer to the winsys screen.
|
||||
* @fence: Handle to the fence object.
|
||||
* @flag: Fence flags to wait for. If the fence object can't signal
|
||||
* a flag, it is assumed to be already signaled.
|
||||
*
|
||||
* Returns 0 if the wait succeeded. Nonzero otherwise.
|
||||
*/
|
||||
int
|
||||
vmw_fence_finish(struct vmw_winsys_screen *vws,
|
||||
struct pipe_fence_handle *fence,
|
||||
unsigned flag)
|
||||
{
|
||||
struct vmw_fence *vfence;
|
||||
int32_t vflags = SVGA_FENCE_FLAG_EXEC;
|
||||
int ret;
|
||||
uint32_t old;
|
||||
|
||||
if (!fence)
|
||||
return 0;
|
||||
|
||||
vfence = vmw_fence(fence);
|
||||
old = p_atomic_read(&vfence->signalled);
|
||||
vflags &= ~vfence->mask;
|
||||
|
||||
if ((old & vflags) == vflags)
|
||||
return 0;
|
||||
|
||||
ret = vmw_ioctl_fence_finish(vws, vfence->handle, vflags);
|
||||
|
||||
if (ret == 0) {
|
||||
int32_t prev = old;
|
||||
|
||||
do {
|
||||
old = prev;
|
||||
prev = p_atomic_cmpxchg(&vfence->signalled, old, old | vflags);
|
||||
} while (prev != old);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* vmw_fence_ops_fence_reference - wrapper for the pb_fence_ops api.
|
||||
*
|
||||
* wrapper around vmw_fence_reference.
|
||||
*/
|
||||
static void
|
||||
vmw_fence_ops_fence_reference(struct pb_fence_ops *ops,
|
||||
struct pipe_fence_handle **ptr,
|
||||
struct pipe_fence_handle *fence)
|
||||
{
|
||||
*ptr = fence;
|
||||
struct vmw_winsys_screen *vws = vmw_fence_ops(ops)->vws;
|
||||
|
||||
vmw_fence_reference(vws, ptr, fence);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* vmw_fence_ops_fence_signalled - wrapper for the pb_fence_ops api.
|
||||
*
|
||||
* wrapper around vmw_fence_signalled.
|
||||
*/
|
||||
static int
|
||||
vmw_fence_ops_fence_signalled(struct pb_fence_ops *ops,
|
||||
struct pipe_fence_handle *fence,
|
||||
unsigned flag)
|
||||
{
|
||||
struct vmw_winsys_screen *vws = vmw_fence_ops(ops)->vws;
|
||||
(void)flag;
|
||||
return vmw_ioctl_fence_signalled(vws, vmw_fence(fence));
|
||||
|
||||
return vmw_fence_signalled(vws, fence, flag);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* vmw_fence_ops_fence_finish - wrapper for the pb_fence_ops api.
|
||||
*
|
||||
* wrapper around vmw_fence_finish.
|
||||
*/
|
||||
static int
|
||||
vmw_fence_ops_fence_finish(struct pb_fence_ops *ops,
|
||||
struct pipe_fence_handle *fence,
|
||||
unsigned flag)
|
||||
{
|
||||
struct vmw_winsys_screen *vws = vmw_fence_ops(ops)->vws;
|
||||
(void)flag;
|
||||
return vmw_ioctl_fence_finish(vws, vmw_fence(fence));
|
||||
|
||||
return vmw_fence_finish(vws, fence, flag);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* vmw_fence_ops_destroy - Destroy a pb_fence_ops function table.
|
||||
*
|
||||
* @ops: The function table to destroy.
|
||||
*
|
||||
* Part of the pb_fence_ops api.
|
||||
*/
|
||||
static void
|
||||
vmw_fence_ops_destroy(struct pb_fence_ops *ops)
|
||||
{
|
||||
|
@ -86,6 +291,16 @@ vmw_fence_ops_destroy(struct pb_fence_ops *ops)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* vmw_fence_ops_create - Create a pb_fence_ops function table.
|
||||
*
|
||||
* @vws: Pointer to a struct vmw_winsys_screen.
|
||||
*
|
||||
* Returns a pointer to a pb_fence_ops function table to interface
|
||||
* with pipe_buffer. This function is typically called on driver setup.
|
||||
*
|
||||
* Returns NULL on failure.
|
||||
*/
|
||||
struct pb_fence_ops *
|
||||
vmw_fence_ops_create(struct vmw_winsys_screen *vws)
|
||||
{
|
||||
|
|
|
@ -36,24 +36,25 @@ struct pb_fence_ops;
|
|||
struct vmw_winsys_screen;
|
||||
|
||||
|
||||
/** Cast from a pipe_fence_handle pointer into a SVGA fence */
|
||||
static INLINE uint32_t
|
||||
vmw_fence( struct pipe_fence_handle *fence )
|
||||
{
|
||||
return (uint32_t)(uintptr_t)fence;
|
||||
}
|
||||
|
||||
|
||||
/** Cast from a SVGA fence number to pipe_fence_handle pointer */
|
||||
static INLINE struct pipe_fence_handle *
|
||||
vmw_pipe_fence( uint32_t fence )
|
||||
{
|
||||
return (struct pipe_fence_handle *)(uintptr_t)fence;
|
||||
}
|
||||
struct pipe_fence_handle *
|
||||
vmw_fence_create(uint32_t handle, uint32_t mask);
|
||||
|
||||
int
|
||||
vmw_fence_finish(struct vmw_winsys_screen *vws,
|
||||
struct pipe_fence_handle *fence,
|
||||
unsigned flag);
|
||||
int
|
||||
vmw_fence_signalled(struct vmw_winsys_screen *vws,
|
||||
struct pipe_fence_handle *fence,
|
||||
unsigned flag);
|
||||
void
|
||||
vmw_fence_reference(struct vmw_winsys_screen *vws,
|
||||
struct pipe_fence_handle **ptr,
|
||||
struct pipe_fence_handle *fence);
|
||||
|
||||
struct pb_fence_ops *
|
||||
vmw_fence_ops_create(struct vmw_winsys_screen *vws);
|
||||
|
||||
|
||||
|
||||
#endif /* VMW_FENCE_H_ */
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
|
||||
|
||||
#define VMW_GMR_POOL_SIZE (16*1024*1024)
|
||||
|
||||
#define VMW_QUERY_POOL_SIZE (8192)
|
||||
|
||||
struct pb_manager;
|
||||
struct vmw_region;
|
||||
|
@ -56,15 +56,18 @@ struct vmw_winsys_screen
|
|||
uint32_t default_throttle_us;
|
||||
|
||||
struct {
|
||||
volatile uint32_t *fifo_map;
|
||||
uint64_t last_fence;
|
||||
int drm_fd;
|
||||
uint32_t hwversion;
|
||||
uint32_t *buffer;
|
||||
} ioctl;
|
||||
|
||||
struct {
|
||||
struct pb_manager *gmr;
|
||||
struct pb_manager *gmr_mm;
|
||||
struct pb_manager *gmr_fenced;
|
||||
struct pb_manager *query;
|
||||
struct pb_manager *query_mm;
|
||||
struct pb_manager *query_fenced;
|
||||
} pools;
|
||||
};
|
||||
|
||||
|
@ -101,7 +104,7 @@ vmw_ioctl_command(struct vmw_winsys_screen *vws,
|
|||
uint32_t throttle_us,
|
||||
void *commands,
|
||||
uint32_t size,
|
||||
uint32_t *fence);
|
||||
struct pipe_fence_handle **fence);
|
||||
|
||||
struct vmw_region *
|
||||
vmw_ioctl_region_create(struct vmw_winsys_screen *vws, uint32_t size);
|
||||
|
@ -120,17 +123,22 @@ vmw_ioctl_region_unmap(struct vmw_region *region);
|
|||
|
||||
int
|
||||
vmw_ioctl_fence_finish(struct vmw_winsys_screen *vws,
|
||||
uint32_t fence);
|
||||
uint32_t handle, uint32_t flags);
|
||||
|
||||
int
|
||||
vmw_ioctl_fence_signalled(struct vmw_winsys_screen *vws,
|
||||
uint32_t fence);
|
||||
uint32_t handle, uint32_t flags);
|
||||
|
||||
void
|
||||
vmw_ioctl_fence_unref(struct vmw_winsys_screen *vws,
|
||||
uint32_t handle);
|
||||
|
||||
|
||||
/* Initialize parts of vmw_winsys_screen at startup:
|
||||
*/
|
||||
boolean vmw_ioctl_init(struct vmw_winsys_screen *vws);
|
||||
boolean vmw_pools_init(struct vmw_winsys_screen *vws);
|
||||
boolean vmw_query_pools_init(struct vmw_winsys_screen *vws);
|
||||
boolean vmw_winsys_screen_init_svga(struct vmw_winsys_screen *vws);
|
||||
|
||||
void vmw_ioctl_cleanup(struct vmw_winsys_screen *vws);
|
||||
|
|
|
@ -56,9 +56,8 @@ vmw_drm_surface_get_handle(struct svga_winsys_screen *sws,
|
|||
unsigned stride,
|
||||
struct winsys_handle *whandle);
|
||||
|
||||
static struct dri1_api_version drm_required = { 1, 0, 0 };
|
||||
static struct dri1_api_version drm_compat = { 1, 0, 0 };
|
||||
static struct dri1_api_version drm_scanout = { 0, 9, 0 };
|
||||
static struct dri1_api_version drm_required = { 2, 1, 0 };
|
||||
static struct dri1_api_version drm_compat = { 2, 0, 0 };
|
||||
|
||||
static boolean
|
||||
vmw_dri1_check_version(const struct dri1_api_version *cur,
|
||||
|
@ -88,8 +87,6 @@ struct svga_winsys_screen *
|
|||
svga_drm_winsys_screen_create(int fd)
|
||||
{
|
||||
struct vmw_winsys_screen *vws;
|
||||
boolean use_old_scanout_flag = FALSE;
|
||||
|
||||
struct dri1_api_version drm_ver;
|
||||
drmVersionPtr ver;
|
||||
|
||||
|
@ -106,11 +103,7 @@ svga_drm_winsys_screen_create(int fd)
|
|||
&drm_compat, "vmwgfx drm driver"))
|
||||
return NULL;
|
||||
|
||||
if (!vmw_dri1_check_version(&drm_ver, &drm_scanout,
|
||||
&drm_compat, "use old scanout field (not a error)"))
|
||||
use_old_scanout_flag = TRUE;
|
||||
|
||||
vws = vmw_winsys_create( fd, use_old_scanout_flag );
|
||||
vws = vmw_winsys_create( fd, FALSE );
|
||||
if (!vws)
|
||||
goto out_no_vws;
|
||||
|
||||
|
|
|
@ -39,8 +39,10 @@
|
|||
#include "svgadump/svga_dump.h"
|
||||
#include "vmw_screen.h"
|
||||
#include "vmw_context.h"
|
||||
#include "vmw_fence.h"
|
||||
#include "xf86drm.h"
|
||||
#include "vmwgfx_drm.h"
|
||||
#include "svga3d_caps.h"
|
||||
|
||||
#include "os/os_mman.h"
|
||||
|
||||
|
@ -64,62 +66,6 @@ struct vmw_region
|
|||
*/
|
||||
#define SVGA3D_SURFACE_HINT_SCANOUT (1 << 9)
|
||||
|
||||
static void
|
||||
vmw_check_last_cmd(struct vmw_winsys_screen *vws)
|
||||
{
|
||||
static uint32_t buffer[16384];
|
||||
struct drm_vmw_fifo_debug_arg arg;
|
||||
int ret;
|
||||
|
||||
return;
|
||||
memset(&arg, 0, sizeof(arg));
|
||||
arg.debug_buffer = (unsigned long)buffer;
|
||||
arg.debug_buffer_size = 65536;
|
||||
|
||||
ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_FIFO_DEBUG,
|
||||
&arg, sizeof(arg));
|
||||
|
||||
if (ret) {
|
||||
debug_printf("%s Ioctl error: \"%s\".\n", __FUNCTION__, strerror(-ret));
|
||||
return;
|
||||
}
|
||||
|
||||
if (arg.did_not_fit) {
|
||||
debug_printf("%s Command did not fit completely.\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
svga_dump_commands(buffer, arg.used_size);
|
||||
}
|
||||
|
||||
static void
|
||||
vmw_ioctl_fifo_unmap(struct vmw_winsys_screen *vws, void *mapping)
|
||||
{
|
||||
VMW_FUNC;
|
||||
(void)os_munmap(mapping, getpagesize());
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
vmw_ioctl_fifo_map(struct vmw_winsys_screen *vws,
|
||||
uint32_t fifo_offset )
|
||||
{
|
||||
void *map;
|
||||
|
||||
VMW_FUNC;
|
||||
|
||||
map = os_mmap(NULL, getpagesize(), PROT_READ, MAP_SHARED,
|
||||
vws->ioctl.drm_fd, fifo_offset);
|
||||
|
||||
if (map == MAP_FAILED) {
|
||||
debug_printf("Map failed %s\n", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vmw_printf("Fifo (min) is 0x%08x\n", ((uint32_t *) map)[SVGA_FIFO_MIN]);
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
uint32
|
||||
vmw_ioctl_context_create(struct vmw_winsys_screen *vws)
|
||||
{
|
||||
|
@ -134,7 +80,6 @@ vmw_ioctl_context_create(struct vmw_winsys_screen *vws)
|
|||
if (ret)
|
||||
return -1;
|
||||
|
||||
vmw_check_last_cmd(vws);
|
||||
vmw_printf("Context id is %d\n", c_arg.cid);
|
||||
|
||||
return c_arg.cid;
|
||||
|
@ -153,7 +98,6 @@ vmw_ioctl_context_destroy(struct vmw_winsys_screen *vws, uint32 cid)
|
|||
(void)drmCommandWrite(vws->ioctl.drm_fd, DRM_VMW_UNREF_CONTEXT,
|
||||
&c_arg, sizeof(c_arg));
|
||||
|
||||
vmw_check_last_cmd(vws);
|
||||
}
|
||||
|
||||
uint32
|
||||
|
@ -220,7 +164,6 @@ vmw_ioctl_surface_create(struct vmw_winsys_screen *vws,
|
|||
return -1;
|
||||
|
||||
vmw_printf("Surface id is %d\n", rep->sid);
|
||||
vmw_check_last_cmd(vws);
|
||||
|
||||
return rep->sid;
|
||||
}
|
||||
|
@ -237,14 +180,12 @@ vmw_ioctl_surface_destroy(struct vmw_winsys_screen *vws, uint32 sid)
|
|||
|
||||
(void)drmCommandWrite(vws->ioctl.drm_fd, DRM_VMW_UNREF_SURFACE,
|
||||
&s_arg, sizeof(s_arg));
|
||||
vmw_check_last_cmd(vws);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
vmw_ioctl_command(struct vmw_winsys_screen *vws, int32_t cid,
|
||||
uint32_t throttle_us, void *commands, uint32_t size,
|
||||
uint32_t *pfence)
|
||||
struct pipe_fence_handle **pfence)
|
||||
{
|
||||
struct drm_vmw_execbuf_arg arg;
|
||||
struct drm_vmw_fence_rep rep;
|
||||
|
@ -274,10 +215,12 @@ vmw_ioctl_command(struct vmw_winsys_screen *vws, int32_t cid,
|
|||
memset(&rep, 0, sizeof(rep));
|
||||
|
||||
rep.error = -EFAULT;
|
||||
arg.fence_rep = (unsigned long)&rep;
|
||||
if (pfence)
|
||||
arg.fence_rep = (unsigned long)&rep;
|
||||
arg.commands = (unsigned long)commands;
|
||||
arg.command_size = size;
|
||||
arg.throttle_us = throttle_us;
|
||||
arg.version = DRM_VMW_EXECBUF_VERSION;
|
||||
|
||||
do {
|
||||
ret = drmCommandWrite(vws->ioctl.drm_fd, DRM_VMW_EXECBUF, &arg, sizeof(arg));
|
||||
|
@ -285,26 +228,27 @@ vmw_ioctl_command(struct vmw_winsys_screen *vws, int32_t cid,
|
|||
if (ret) {
|
||||
debug_printf("%s error %s.\n", __FUNCTION__, strerror(-ret));
|
||||
}
|
||||
|
||||
if (rep.error) {
|
||||
|
||||
/*
|
||||
* Kernel has synced and put the last fence sequence in the FIFO
|
||||
* register.
|
||||
* Kernel has already synced, or caller requested no fence.
|
||||
*/
|
||||
if (pfence)
|
||||
*pfence = NULL;
|
||||
} else {
|
||||
if (pfence) {
|
||||
*pfence = vmw_fence_create(rep.handle, rep.mask);
|
||||
|
||||
if (rep.error == -EFAULT)
|
||||
rep.fence_seq = vws->ioctl.fifo_map[SVGA_FIFO_FENCE];
|
||||
|
||||
debug_printf("%s Fence error %s.\n", __FUNCTION__,
|
||||
strerror(-rep.error));
|
||||
if (*pfence == NULL) {
|
||||
/*
|
||||
* Fence creation failed. Need to sync.
|
||||
*/
|
||||
(void) vmw_ioctl_fence_finish(vws, rep.handle, rep.mask);
|
||||
vmw_ioctl_fence_unref(vws, rep.handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vws->ioctl.last_fence = rep.fence_seq;
|
||||
|
||||
if (pfence)
|
||||
*pfence = rep.fence_seq;
|
||||
vmw_check_last_cmd(vws);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -412,67 +356,81 @@ vmw_ioctl_region_unmap(struct vmw_region *region)
|
|||
--region->map_count;
|
||||
}
|
||||
|
||||
void
|
||||
vmw_ioctl_fence_unref(struct vmw_winsys_screen *vws,
|
||||
uint32_t handle)
|
||||
{
|
||||
struct drm_vmw_fence_arg arg;
|
||||
int ret;
|
||||
|
||||
memset(&arg, 0, sizeof(arg));
|
||||
arg.handle = handle;
|
||||
|
||||
ret = drmCommandWrite(vws->ioctl.drm_fd, DRM_VMW_FENCE_UNREF,
|
||||
&arg, sizeof(arg));
|
||||
if (ret != 0)
|
||||
debug_printf("%s Failed\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
static INLINE uint32_t
|
||||
vmw_drm_fence_flags(uint32_t flags)
|
||||
{
|
||||
uint32_t dflags = 0;
|
||||
|
||||
if (flags & SVGA_FENCE_FLAG_EXEC)
|
||||
dflags |= DRM_VMW_FENCE_FLAG_EXEC;
|
||||
if (flags & SVGA_FENCE_FLAG_QUERY)
|
||||
dflags |= DRM_VMW_FENCE_FLAG_QUERY;
|
||||
|
||||
return dflags;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
vmw_ioctl_fence_signalled(struct vmw_winsys_screen *vws,
|
||||
uint32_t fence)
|
||||
uint32_t handle,
|
||||
uint32_t flags)
|
||||
{
|
||||
uint32_t expected;
|
||||
uint32_t current;
|
||||
|
||||
assert(fence);
|
||||
if(!fence)
|
||||
return 0;
|
||||
|
||||
expected = fence;
|
||||
current = vws->ioctl.fifo_map[SVGA_FIFO_FENCE];
|
||||
|
||||
if ((int32)(current - expected) >= 0)
|
||||
return 0; /* fence passed */
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
vmw_ioctl_sync(struct vmw_winsys_screen *vws,
|
||||
uint32_t fence)
|
||||
{
|
||||
uint32_t cur_fence;
|
||||
struct drm_vmw_fence_wait_arg arg;
|
||||
struct drm_vmw_fence_signaled_arg arg;
|
||||
uint32_t vflags = vmw_drm_fence_flags(flags);
|
||||
int ret;
|
||||
|
||||
vmw_printf("%s: fence = %lu\n", __FUNCTION__,
|
||||
(unsigned long)fence);
|
||||
|
||||
cur_fence = vws->ioctl.fifo_map[SVGA_FIFO_FENCE];
|
||||
vmw_printf("%s: Fence id read is 0x%08x\n", __FUNCTION__,
|
||||
(unsigned int)cur_fence);
|
||||
|
||||
if ((cur_fence - fence) < (1 << 24))
|
||||
return;
|
||||
|
||||
memset(&arg, 0, sizeof(arg));
|
||||
arg.sequence = fence;
|
||||
arg.handle = handle;
|
||||
arg.flags = vflags;
|
||||
|
||||
do {
|
||||
ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_FENCE_WAIT, &arg,
|
||||
sizeof(arg));
|
||||
} while (ret == -ERESTART);
|
||||
ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_FENCE_SIGNALED,
|
||||
&arg, sizeof(arg));
|
||||
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
return (arg.signaled) ? 0 : -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
vmw_ioctl_fence_finish(struct vmw_winsys_screen *vws,
|
||||
uint32_t fence)
|
||||
uint32_t handle,
|
||||
uint32_t flags)
|
||||
{
|
||||
assert(fence);
|
||||
|
||||
if(fence) {
|
||||
if(vmw_ioctl_fence_signalled(vws, fence) != 0) {
|
||||
vmw_ioctl_sync(vws, fence);
|
||||
}
|
||||
}
|
||||
struct drm_vmw_fence_wait_arg arg;
|
||||
uint32_t vflags = vmw_drm_fence_flags(flags);
|
||||
int ret;
|
||||
|
||||
memset(&arg, 0, sizeof(arg));
|
||||
|
||||
arg.handle = handle;
|
||||
arg.timeout_us = 10*1000000;
|
||||
arg.lazy = 0;
|
||||
arg.flags = vflags;
|
||||
|
||||
ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_FENCE_WAIT,
|
||||
&arg, sizeof(arg));
|
||||
|
||||
if (ret != 0)
|
||||
debug_printf("%s Failed\n", __FUNCTION__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -482,6 +440,8 @@ boolean
|
|||
vmw_ioctl_init(struct vmw_winsys_screen *vws)
|
||||
{
|
||||
struct drm_vmw_getparam_arg gp_arg;
|
||||
struct drm_vmw_get_3d_cap_arg cap_arg;
|
||||
unsigned int size;
|
||||
int ret;
|
||||
|
||||
VMW_FUNC;
|
||||
|
@ -491,32 +451,46 @@ vmw_ioctl_init(struct vmw_winsys_screen *vws)
|
|||
ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_GET_PARAM,
|
||||
&gp_arg, sizeof(gp_arg));
|
||||
if (ret || gp_arg.value == 0) {
|
||||
debug_printf("No 3D enabled (%i, %s)\n", ret, strerror(-ret));
|
||||
goto out_err1;
|
||||
debug_printf("No 3D enabled (%i, %s).\n", ret, strerror(-ret));
|
||||
goto out_no_3d;
|
||||
}
|
||||
|
||||
memset(&gp_arg, 0, sizeof(gp_arg));
|
||||
gp_arg.param = DRM_VMW_PARAM_FIFO_OFFSET;
|
||||
gp_arg.param = DRM_VMW_PARAM_FIFO_HW_VERSION;
|
||||
ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_GET_PARAM,
|
||||
&gp_arg, sizeof(gp_arg));
|
||||
|
||||
if (ret) {
|
||||
debug_printf("GET_PARAM on %d returned %d: %s\n",
|
||||
vws->ioctl.drm_fd, ret, strerror(-ret));
|
||||
goto out_err1;
|
||||
debug_printf("Failed to get fifo hw version"
|
||||
" (%i, %s).\n", ret, strerror(-ret));
|
||||
goto out_no_3d;
|
||||
}
|
||||
vws->ioctl.hwversion = gp_arg.value;
|
||||
|
||||
size = SVGA_FIFO_3D_CAPS_SIZE * sizeof(uint32_t);
|
||||
vws->ioctl.buffer = calloc(1, size);
|
||||
if (!vws->ioctl.buffer) {
|
||||
debug_printf("Failed alloc fifo 3D caps buffer.\n");
|
||||
goto out_no_3d;
|
||||
}
|
||||
|
||||
vmw_printf("Offset to map is 0x%08llx\n",
|
||||
(unsigned long long)gp_arg.value);
|
||||
memset(&cap_arg, 0, sizeof(cap_arg));
|
||||
cap_arg.buffer = (uint64_t) (unsigned long) (vws->ioctl.buffer);
|
||||
cap_arg.max_size = size;
|
||||
|
||||
vws->ioctl.fifo_map = vmw_ioctl_fifo_map(vws, gp_arg.value);
|
||||
if (vws->ioctl.fifo_map == NULL)
|
||||
goto out_err1;
|
||||
ret = drmCommandWrite(vws->ioctl.drm_fd, DRM_VMW_GET_3D_CAP,
|
||||
&cap_arg, sizeof(cap_arg));
|
||||
|
||||
if (ret) {
|
||||
debug_printf("Failed to get 3D capabilities"
|
||||
" (%i, %s).\n", ret, strerror(-ret));
|
||||
goto out_no_caps;
|
||||
}
|
||||
|
||||
vmw_printf("%s OK\n", __FUNCTION__);
|
||||
return TRUE;
|
||||
|
||||
out_err1:
|
||||
out_no_caps:
|
||||
free(vws->ioctl.buffer);
|
||||
out_no_3d:
|
||||
debug_printf("%s Failed\n", __FUNCTION__);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -527,6 +501,4 @@ void
|
|||
vmw_ioctl_cleanup(struct vmw_winsys_screen *vws)
|
||||
{
|
||||
VMW_FUNC;
|
||||
|
||||
vmw_ioctl_fifo_unmap(vws, (void *)vws->ioctl.fifo_map);
|
||||
}
|
||||
|
|
|
@ -32,19 +32,81 @@
|
|||
#include "pipebuffer/pb_buffer.h"
|
||||
#include "pipebuffer/pb_bufmgr.h"
|
||||
|
||||
/*
|
||||
* TODO: Have the query pool always ask the fence manager for
|
||||
* SVGA_FENCE_FLAG_QUERY signaled. Unfortunately, pb_fenced doesn't
|
||||
* support that currently, so we'd have to create a separate
|
||||
* pb_fence_ops wrapper that does this implicitly.
|
||||
*/
|
||||
|
||||
/**
|
||||
* vmw_pools_cleanup - Destroy the buffer pools.
|
||||
*
|
||||
* @vws: pointer to a struct vmw_winsys_screen.
|
||||
*/
|
||||
void
|
||||
vmw_pools_cleanup(struct vmw_winsys_screen *vws)
|
||||
{
|
||||
if(vws->pools.gmr_fenced)
|
||||
vws->pools.gmr_fenced->destroy(vws->pools.gmr_fenced);
|
||||
if (vws->pools.query_fenced)
|
||||
vws->pools.query_fenced->destroy(vws->pools.query_fenced);
|
||||
|
||||
/* gmr_mm pool is already destroyed above */
|
||||
|
||||
if(vws->pools.gmr)
|
||||
vws->pools.gmr->destroy(vws->pools.gmr);
|
||||
if(vws->pools.query)
|
||||
vws->pools.query->destroy(vws->pools.query);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* vmw_query_pools_init - Create a pool of query buffers.
|
||||
*
|
||||
* @vws: Pointer to a struct vmw_winsys_screen.
|
||||
*
|
||||
* Typically this pool should be created on demand when we
|
||||
* detect that the app will be using queries. There's nothing
|
||||
* special with this pool other than the backing kernel buffer size,
|
||||
* which is limited to 8192.
|
||||
*/
|
||||
boolean
|
||||
vmw_query_pools_init(struct vmw_winsys_screen *vws)
|
||||
{
|
||||
vws->pools.query = vmw_gmr_bufmgr_create(vws);
|
||||
if(!vws->pools.query)
|
||||
return FALSE;
|
||||
|
||||
vws->pools.query_mm = mm_bufmgr_create(vws->pools.query,
|
||||
VMW_QUERY_POOL_SIZE,
|
||||
3 /* 8 alignment */);
|
||||
if(!vws->pools.query_mm)
|
||||
goto out_no_query_mm;
|
||||
|
||||
vws->pools.query_fenced = fenced_bufmgr_create(
|
||||
vws->pools.query_mm,
|
||||
vmw_fence_ops_create(vws),
|
||||
VMW_QUERY_POOL_SIZE,
|
||||
~0);
|
||||
|
||||
if(!vws->pools.query_fenced)
|
||||
goto out_no_query_fenced;
|
||||
|
||||
return TRUE;
|
||||
|
||||
out_no_query_fenced:
|
||||
vws->pools.query_mm->destroy(vws->pools.query_mm);
|
||||
out_no_query_mm:
|
||||
vws->pools.query->destroy(vws->pools.query);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* vmw_pools_init - Create a pool of GMR buffers.
|
||||
*
|
||||
* @vws: Pointer to a struct vmw_winsys_screen.
|
||||
*/
|
||||
boolean
|
||||
vmw_pools_init(struct vmw_winsys_screen *vws)
|
||||
{
|
||||
|
@ -88,6 +150,10 @@ vmw_pools_init(struct vmw_winsys_screen *vws)
|
|||
if(!vws->pools.gmr_fenced)
|
||||
goto error;
|
||||
|
||||
vws->pools.query_fenced = NULL;
|
||||
vws->pools.query_mm = NULL;
|
||||
vws->pools.query = NULL;
|
||||
|
||||
return TRUE;
|
||||
|
||||
error:
|
||||
|
|
|
@ -64,7 +64,12 @@ vmw_svga_winsys_buffer_create(struct svga_winsys_screen *sws,
|
|||
desc.alignment = alignment;
|
||||
desc.usage = usage;
|
||||
|
||||
provider = vws->pools.gmr_fenced;
|
||||
if (usage == SVGA_BUFFER_USAGE_PINNED) {
|
||||
if (vws->pools.query_fenced == NULL && !vmw_query_pools_init(vws))
|
||||
return NULL;
|
||||
provider = vws->pools.query_fenced;
|
||||
} else
|
||||
provider = vws->pools.gmr_fenced;
|
||||
|
||||
assert(provider);
|
||||
buffer = provider->create_buffer(provider, size, &desc);
|
||||
|
@ -109,8 +114,9 @@ vmw_svga_winsys_fence_reference(struct svga_winsys_screen *sws,
|
|||
struct pipe_fence_handle **pdst,
|
||||
struct pipe_fence_handle *src)
|
||||
{
|
||||
(void)sws;
|
||||
*pdst = src;
|
||||
struct vmw_winsys_screen *vws = vmw_winsys_screen(sws);
|
||||
|
||||
vmw_fence_reference(vws, pdst, src);
|
||||
}
|
||||
|
||||
|
||||
|
@ -120,8 +126,8 @@ vmw_svga_winsys_fence_signalled(struct svga_winsys_screen *sws,
|
|||
unsigned flag)
|
||||
{
|
||||
struct vmw_winsys_screen *vws = vmw_winsys_screen(sws);
|
||||
(void)flag;
|
||||
return vmw_ioctl_fence_signalled(vws, vmw_fence(fence));
|
||||
|
||||
return vmw_fence_signalled(vws, fence, flag);
|
||||
}
|
||||
|
||||
|
||||
|
@ -131,8 +137,8 @@ vmw_svga_winsys_fence_finish(struct svga_winsys_screen *sws,
|
|||
unsigned flag)
|
||||
{
|
||||
struct vmw_winsys_screen *vws = vmw_winsys_screen(sws);
|
||||
(void)flag;
|
||||
return vmw_ioctl_fence_finish(vws, vmw_fence(fence));
|
||||
|
||||
return vmw_fence_finish(vws, fence, flag);
|
||||
}
|
||||
|
||||
|
||||
|
@ -206,11 +212,7 @@ vmw_svga_winsys_get_hw_version(struct svga_winsys_screen *sws)
|
|||
{
|
||||
struct vmw_winsys_screen *vws = vmw_winsys_screen(sws);
|
||||
|
||||
if (!vws->ioctl.fifo_map) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return vws->ioctl.fifo_map[SVGA_FIFO_3D_HWVERSION];
|
||||
return (SVGA3dHardwareVersion) vws->ioctl.hwversion;
|
||||
}
|
||||
|
||||
|
||||
|
@ -226,16 +228,13 @@ vmw_svga_winsys_get_cap(struct svga_winsys_screen *sws,
|
|||
const SVGA3dCapPair *capArray;
|
||||
int numCaps, first, last;
|
||||
|
||||
if(!vws->ioctl.fifo_map)
|
||||
return FALSE;
|
||||
|
||||
if(vws->ioctl.fifo_map[SVGA_FIFO_3D_HWVERSION] < SVGA3D_HWVERSION_WS6_B1)
|
||||
if(vws->ioctl.hwversion < SVGA3D_HWVERSION_WS6_B1)
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
* Search linearly through the caps block records for the specified type.
|
||||
*/
|
||||
capsBlock = (const uint32 *)&vws->ioctl.fifo_map[SVGA_FIFO_3D_CAPS];
|
||||
capsBlock = (const uint32 *)vws->ioctl.buffer;
|
||||
for (offset = 0; capsBlock[offset] != 0; offset += capsBlock[offset]) {
|
||||
const SVGA3dCapsRecord *record;
|
||||
assert(offset < SVGA_FIFO_3D_CAPS_SIZE);
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
#define DRM_VMW_MAX_SURFACE_FACES 6
|
||||
#define DRM_VMW_MAX_MIP_LEVELS 24
|
||||
|
||||
#define DRM_VMW_EXT_NAME_LEN 128
|
||||
|
||||
#define DRM_VMW_GET_PARAM 0
|
||||
#define DRM_VMW_ALLOC_DMABUF 1
|
||||
|
@ -48,10 +47,13 @@
|
|||
#define DRM_VMW_UNREF_SURFACE 10
|
||||
#define DRM_VMW_REF_SURFACE 11
|
||||
#define DRM_VMW_EXECBUF 12
|
||||
#define DRM_VMW_FIFO_DEBUG 13
|
||||
#define DRM_VMW_GET_3D_CAP 13
|
||||
#define DRM_VMW_FENCE_WAIT 14
|
||||
/* guarded by minor version >= 2 */
|
||||
#define DRM_VMW_UPDATE_LAYOUT 15
|
||||
#define DRM_VMW_FENCE_SIGNALED 15
|
||||
#define DRM_VMW_FENCE_UNREF 16
|
||||
#define DRM_VMW_FENCE_EVENT 17
|
||||
#define DRM_VMW_PRESENT 18
|
||||
#define DRM_VMW_PRESENT_READBACK 19
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
|
@ -69,10 +71,10 @@
|
|||
#define DRM_VMW_PARAM_NUM_STREAMS 0
|
||||
#define DRM_VMW_PARAM_NUM_FREE_STREAMS 1
|
||||
#define DRM_VMW_PARAM_3D 2
|
||||
#define DRM_VMW_PARAM_FIFO_OFFSET 3
|
||||
#define DRM_VMW_PARAM_HW_CAPS 4
|
||||
#define DRM_VMW_PARAM_FIFO_CAPS 5
|
||||
#define DRM_VMW_PARAM_MAX_FB_SIZE 6
|
||||
#define DRM_VMW_PARAM_HW_CAPS 3
|
||||
#define DRM_VMW_PARAM_FIFO_CAPS 4
|
||||
#define DRM_VMW_PARAM_MAX_FB_SIZE 5
|
||||
#define DRM_VMW_PARAM_FIFO_HW_VERSION 6
|
||||
|
||||
/**
|
||||
* struct drm_vmw_getparam_arg
|
||||
|
@ -249,7 +251,7 @@ union drm_vmw_surface_reference_arg {
|
|||
* DRM_VMW_EXECBUF
|
||||
*
|
||||
* Submit a command buffer for execution on the host, and return a
|
||||
* fence sequence that when signaled, indicates that the command buffer has
|
||||
* fence seqno that when signaled, indicates that the command buffer has
|
||||
* executed.
|
||||
*/
|
||||
|
||||
|
@ -271,21 +273,30 @@ union drm_vmw_surface_reference_arg {
|
|||
* Argument to the DRM_VMW_EXECBUF Ioctl.
|
||||
*/
|
||||
|
||||
#define DRM_VMW_EXECBUF_VERSION 0
|
||||
#define DRM_VMW_EXECBUF_VERSION 1
|
||||
|
||||
struct drm_vmw_execbuf_arg {
|
||||
uint64_t commands;
|
||||
uint32_t command_size;
|
||||
uint32_t throttle_us;
|
||||
uint64_t fence_rep;
|
||||
uint32_t version;
|
||||
uint32_t flags;
|
||||
uint32_t version;
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct drm_vmw_fence_rep
|
||||
*
|
||||
* @fence_seq: Fence sequence associated with a command submission.
|
||||
* @handle: Fence object handle for fence associated with a command submission.
|
||||
* @mask: Fence flags relevant for this fence object.
|
||||
* @seqno: Fence sequence number in fifo. A fence object with a lower
|
||||
* seqno will signal the EXEC flag before a fence object with a higher
|
||||
* seqno. This can be used by user-space to avoid kernel calls to determine
|
||||
* whether a fence has signaled the EXEC flag. Note that @seqno will
|
||||
* wrap at 32-bit.
|
||||
* @passed_seqno: The highest seqno number processed by the hardware
|
||||
* so far. This can be used to mark user-space fence objects as signaled, and
|
||||
* to determine whether a fence seqno might be stale.
|
||||
* @error: This member should've been set to -EFAULT on submission.
|
||||
* The following actions should be take on completion:
|
||||
* error == -EFAULT: Fence communication failed. The host is synchronized.
|
||||
|
@ -299,9 +310,12 @@ struct drm_vmw_execbuf_arg {
|
|||
*/
|
||||
|
||||
struct drm_vmw_fence_rep {
|
||||
uint64_t fence_seq;
|
||||
int32_t error;
|
||||
uint32_t handle;
|
||||
uint32_t mask;
|
||||
uint32_t seqno;
|
||||
uint32_t passed_seqno;
|
||||
uint32_t pad64;
|
||||
int32_t error;
|
||||
};
|
||||
|
||||
/*************************************************************************/
|
||||
|
@ -390,39 +404,6 @@ struct drm_vmw_unref_dmabuf_arg {
|
|||
uint32_t pad64;
|
||||
};
|
||||
|
||||
/*************************************************************************/
|
||||
/**
|
||||
* DRM_VMW_FIFO_DEBUG - Get last FIFO submission.
|
||||
*
|
||||
* This IOCTL copies the last FIFO submission directly out of the FIFO buffer.
|
||||
*/
|
||||
|
||||
/**
|
||||
* struct drm_vmw_fifo_debug_arg
|
||||
*
|
||||
* @debug_buffer: User space address of a debug_buffer cast to an uint64_t //In
|
||||
* @debug_buffer_size: Size in bytes of debug buffer //In
|
||||
* @used_size: Number of bytes copied to the buffer // Out
|
||||
* @did_not_fit: Boolean indicating that the fifo contents did not fit. //Out
|
||||
*
|
||||
* Argument to the DRM_VMW_FIFO_DEBUG Ioctl.
|
||||
*/
|
||||
|
||||
struct drm_vmw_fifo_debug_arg {
|
||||
uint64_t debug_buffer;
|
||||
uint32_t debug_buffer_size;
|
||||
uint32_t used_size;
|
||||
int32_t did_not_fit;
|
||||
uint32_t pad64;
|
||||
};
|
||||
|
||||
struct drm_vmw_fence_wait_arg {
|
||||
uint64_t sequence;
|
||||
uint64_t kernel_cookie;
|
||||
int32_t cookie_valid;
|
||||
int32_t pad64;
|
||||
};
|
||||
|
||||
/*************************************************************************/
|
||||
/**
|
||||
* DRM_VMW_CONTROL_STREAM - Control overlays, aka streams.
|
||||
|
@ -547,26 +528,197 @@ struct drm_vmw_stream_arg {
|
|||
|
||||
/*************************************************************************/
|
||||
/**
|
||||
* DRM_VMW_UPDATE_LAYOUT - Update layout
|
||||
* DRM_VMW_GET_3D_CAP
|
||||
*
|
||||
* Read 3D capabilities from the FIFO
|
||||
*
|
||||
* Updates the prefered modes and connection status for connectors. The
|
||||
* command conisits of one drm_vmw_update_layout_arg pointing out a array
|
||||
* of num_outputs drm_vmw_rect's.
|
||||
*/
|
||||
|
||||
/**
|
||||
* struct drm_vmw_update_layout_arg
|
||||
* struct drm_vmw_get_3d_cap_arg
|
||||
*
|
||||
* @num_outputs: number of active
|
||||
* @rects: pointer to array of drm_vmw_rect
|
||||
* @buffer: Pointer to a buffer for capability data, cast to an uint64_t
|
||||
* @size: Max size to copy
|
||||
*
|
||||
* Input argument to the DRM_VMW_UPDATE_LAYOUT Ioctl.
|
||||
* Input argument to the DRM_VMW_GET_3D_CAP_IOCTL
|
||||
* ioctls.
|
||||
*/
|
||||
|
||||
struct drm_vmw_update_layout_arg {
|
||||
uint32_t num_outputs;
|
||||
struct drm_vmw_get_3d_cap_arg {
|
||||
uint64_t buffer;
|
||||
uint32_t max_size;
|
||||
uint32_t pad64;
|
||||
uint64_t rects;
|
||||
};
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/**
|
||||
* DRM_VMW_FENCE_WAIT
|
||||
*
|
||||
* Waits for a fence object to signal. The wait is interruptible, so that
|
||||
* signals may be delivered during the interrupt. The wait may timeout,
|
||||
* in which case the calls returns -EBUSY. If the wait is restarted,
|
||||
* that is restarting without resetting @cookie_valid to zero,
|
||||
* the timeout is computed from the first call.
|
||||
*
|
||||
* The flags argument to the DRM_VMW_FENCE_WAIT ioctl indicates what to wait
|
||||
* on:
|
||||
* DRM_VMW_FENCE_FLAG_EXEC: All commands ahead of the fence in the command
|
||||
* stream
|
||||
* have executed.
|
||||
* DRM_VMW_FENCE_FLAG_QUERY: All query results resulting from query finish
|
||||
* commands
|
||||
* in the buffer given to the EXECBUF ioctl returning the fence object handle
|
||||
* are available to user-space.
|
||||
*
|
||||
* DRM_VMW_WAIT_OPTION_UNREF: If this wait option is given, and the
|
||||
* fenc wait ioctl returns 0, the fence object has been unreferenced after
|
||||
* the wait.
|
||||
*/
|
||||
|
||||
#define DRM_VMW_FENCE_FLAG_EXEC (1 << 0)
|
||||
#define DRM_VMW_FENCE_FLAG_QUERY (1 << 1)
|
||||
|
||||
#define DRM_VMW_WAIT_OPTION_UNREF (1 << 0)
|
||||
|
||||
/**
|
||||
* struct drm_vmw_fence_wait_arg
|
||||
*
|
||||
* @handle: Fence object handle as returned by the DRM_VMW_EXECBUF ioctl.
|
||||
* @cookie_valid: Must be reset to 0 on first call. Left alone on restart.
|
||||
* @kernel_cookie: Set to 0 on first call. Left alone on restart.
|
||||
* @timeout_us: Wait timeout in microseconds. 0 for indefinite timeout.
|
||||
* @lazy: Set to 1 if timing is not critical. Allow more than a kernel tick
|
||||
* before returning.
|
||||
* @flags: Fence flags to wait on.
|
||||
* @wait_options: Options that control the behaviour of the wait ioctl.
|
||||
*
|
||||
* Input argument to the DRM_VMW_FENCE_WAIT ioctl.
|
||||
*/
|
||||
|
||||
struct drm_vmw_fence_wait_arg {
|
||||
uint32_t handle;
|
||||
int32_t cookie_valid;
|
||||
uint64_t kernel_cookie;
|
||||
uint64_t timeout_us;
|
||||
int32_t lazy;
|
||||
int32_t flags;
|
||||
int32_t wait_options;
|
||||
int32_t pad64;
|
||||
};
|
||||
|
||||
/*************************************************************************/
|
||||
/**
|
||||
* DRM_VMW_FENCE_SIGNALED
|
||||
*
|
||||
* Checks if a fence object is signaled..
|
||||
*/
|
||||
|
||||
/**
|
||||
* struct drm_vmw_fence_signaled_arg
|
||||
*
|
||||
* @handle: Fence object handle as returned by the DRM_VMW_EXECBUF ioctl.
|
||||
* @flags: Fence object flags input to DRM_VMW_FENCE_SIGNALED ioctl
|
||||
* @signaled: Out: Flags signaled.
|
||||
* @sequence: Out: Highest sequence passed so far. Can be used to signal the
|
||||
* EXEC flag of user-space fence objects.
|
||||
*
|
||||
* Input/Output argument to the DRM_VMW_FENCE_SIGNALED and DRM_VMW_FENCE_UNREF
|
||||
* ioctls.
|
||||
*/
|
||||
|
||||
struct drm_vmw_fence_signaled_arg {
|
||||
uint32_t handle;
|
||||
uint32_t flags;
|
||||
int32_t signaled;
|
||||
uint32_t passed_seqno;
|
||||
uint32_t signaled_flags;
|
||||
uint32_t pad64;
|
||||
};
|
||||
|
||||
/*************************************************************************/
|
||||
/**
|
||||
* DRM_VMW_FENCE_UNREF
|
||||
*
|
||||
* Unreferences a fence object, and causes it to be destroyed if there are no
|
||||
* other references to it.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* struct drm_vmw_fence_arg
|
||||
*
|
||||
* @handle: Fence object handle as returned by the DRM_VMW_EXECBUF ioctl.
|
||||
*
|
||||
* Input/Output argument to the DRM_VMW_FENCE_UNREF ioctl..
|
||||
*/
|
||||
|
||||
struct drm_vmw_fence_arg {
|
||||
uint32_t handle;
|
||||
uint32_t pad64;
|
||||
};
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/**
|
||||
* DRM_VMW_PRESENT
|
||||
*
|
||||
* Executes an SVGA present on a given fb for a given surface. The surface
|
||||
* is placed on the framebuffer. Cliprects are given relative to the given
|
||||
* point (the point disignated by dest_{x|y}).
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* struct drm_vmw_present_arg
|
||||
* @fb_id: framebuffer id to present / read back from.
|
||||
* @sid: Surface id to present from.
|
||||
* @dest_x: X placement coordinate for surface.
|
||||
* @dest_y: Y placement coordinate for surface.
|
||||
* @clips_ptr: Pointer to an array of clip rects cast to an uint64_t.
|
||||
* @num_clips: Number of cliprects given relative to the framebuffer origin,
|
||||
* in the same coordinate space as the frame buffer.
|
||||
* @pad64: Unused 64-bit padding.
|
||||
*
|
||||
* Input argument to the DRM_VMW_PRESENT ioctl.
|
||||
*/
|
||||
|
||||
struct drm_vmw_present_arg {
|
||||
uint32_t fb_id;
|
||||
uint32_t sid;
|
||||
int32_t dest_x;
|
||||
int32_t dest_y;
|
||||
uint64_t clips_ptr;
|
||||
uint32_t num_clips;
|
||||
uint32_t pad64;
|
||||
};
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/**
|
||||
* DRM_VMW_PRESENT_READBACK
|
||||
*
|
||||
* Executes an SVGA present readback from a given fb to the dma buffer
|
||||
* currently bound as the fb. If there is no dma buffer bound to the fb,
|
||||
* an error will be returned.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* struct drm_vmw_present_arg
|
||||
* @fb_id: fb_id to present / read back from.
|
||||
* @num_clips: Number of cliprects.
|
||||
* @clips_ptr: Pointer to an array of clip rects cast to an uint64_t.
|
||||
* @fence_rep: Pointer to a struct drm_vmw_fence_rep, cast to an uint64_t.
|
||||
* If this member is NULL, then the ioctl should not return a fence.
|
||||
*/
|
||||
|
||||
struct drm_vmw_present_readback_arg {
|
||||
uint32_t fb_id;
|
||||
uint32_t num_clips;
|
||||
uint64_t clips_ptr;
|
||||
uint64_t fence_rep;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue