DRI3: add DRI3ImportSyncobj and DRI3FreeSyncobj
Adds the required infrastructure in the core DRI3 code to support importing DRM synchronization objects from clients. This includes support for the two new protocol requests from DRI3 version 1.4, an internal representation of these objects in the form of the dri3_syncobj structure, and an import_syncobj screen info callback. The following operations are defined for dri3_syncobj objects * free - release any server-side resources associated with the object * has_fence - check if the fence for a timeline point is submitted * is_signaled - check if a timeline point is signaled * export_fence - return a sync fd corresponding to a timeline point * import_fence - submit a sync fd as the fence for a timeline point * signal - immediately signal a timeline point * submitted_eventfd and signaled_eventfd - register an eventfd to be signaled when the given timeline point is either submitted or signaled Implementations will be responsible for populating these function pointers when importing a syncobj. Signed-off-by: Erik Kurzinger <ekurzinger@nvidia.com> Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/967>
This commit is contained in:
parent
f051a2449d
commit
613dcb6a77
15
dri3/dri3.c
15
dri3/dri3.c
|
@ -63,6 +63,16 @@ dri3_screen_init(ScreenPtr screen, const dri3_screen_info_rec *info)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
RESTYPE dri3_syncobj_type;
|
||||
|
||||
static int dri3_syncobj_free(void *data, XID id)
|
||||
{
|
||||
struct dri3_syncobj *syncobj = data;
|
||||
if (--syncobj->refcount == 0)
|
||||
syncobj->free(syncobj);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
dri3_extension_init(void)
|
||||
{
|
||||
|
@ -92,6 +102,11 @@ dri3_extension_init(void)
|
|||
if (!dri3_screen_init(screenInfo.screens[i], NULL))
|
||||
goto bail;
|
||||
}
|
||||
|
||||
dri3_syncobj_type = CreateNewResourceType(dri3_syncobj_free, "DRI3Syncobj");
|
||||
if (!dri3_syncobj_type)
|
||||
goto bail;
|
||||
|
||||
return;
|
||||
|
||||
bail:
|
||||
|
|
38
dri3/dri3.h
38
dri3/dri3.h
|
@ -28,7 +28,35 @@
|
|||
#include <X11/extensions/dri3proto.h>
|
||||
#include <randrstr.h>
|
||||
|
||||
#define DRI3_SCREEN_INFO_VERSION 2
|
||||
#define DRI3_SCREEN_INFO_VERSION 4
|
||||
|
||||
extern RESTYPE dri3_syncobj_type;
|
||||
|
||||
struct dri3_syncobj
|
||||
{
|
||||
XID id;
|
||||
ScreenPtr screen;
|
||||
uint32_t refcount;
|
||||
|
||||
void (*free)(struct dri3_syncobj *syncobj);
|
||||
Bool (*has_fence)(struct dri3_syncobj *syncobj, uint64_t point);
|
||||
Bool (*is_signaled)(struct dri3_syncobj *syncobj, uint64_t point);
|
||||
int (*export_fence)(struct dri3_syncobj *syncobj, uint64_t point);
|
||||
void (*import_fence)(struct dri3_syncobj *syncobj, uint64_t point, int fd);
|
||||
void (*signal)(struct dri3_syncobj *syncobj, uint64_t point);
|
||||
void (*submitted_eventfd)(struct dri3_syncobj *syncobj, uint64_t point, int efd);
|
||||
void (*signaled_eventfd)(struct dri3_syncobj *syncobj, uint64_t point, int efd);
|
||||
};
|
||||
|
||||
#define VERIFY_DRI3_SYNCOBJ(id, ptr, a)\
|
||||
do {\
|
||||
int rc = dixLookupResourceByType((void **)&(ptr), id,\
|
||||
dri3_syncobj_type, client, a);\
|
||||
if (rc != Success) {\
|
||||
client->errorValue = id;\
|
||||
return rc;\
|
||||
}\
|
||||
} while (0);
|
||||
|
||||
typedef int (*dri3_open_proc)(ScreenPtr screen,
|
||||
RRProviderPtr provider,
|
||||
|
@ -84,6 +112,11 @@ typedef int (*dri3_get_drawable_modifiers_proc) (DrawablePtr draw,
|
|||
uint32_t *num_modifiers,
|
||||
uint64_t **modifiers);
|
||||
|
||||
typedef struct dri3_syncobj *(*dri3_import_syncobj_proc) (ClientPtr client,
|
||||
ScreenPtr screen,
|
||||
XID id,
|
||||
int fd);
|
||||
|
||||
typedef struct dri3_screen_info {
|
||||
uint32_t version;
|
||||
|
||||
|
@ -101,6 +134,9 @@ typedef struct dri3_screen_info {
|
|||
dri3_get_modifiers_proc get_modifiers;
|
||||
dri3_get_drawable_modifiers_proc get_drawable_modifiers;
|
||||
|
||||
/* Version 4 */
|
||||
dri3_import_syncobj_proc import_syncobj;
|
||||
|
||||
} dri3_screen_info_rec, *dri3_screen_info_ptr;
|
||||
|
||||
extern _X_EXPORT Bool
|
||||
|
|
|
@ -102,4 +102,7 @@ dri3_get_supported_modifiers(ScreenPtr screen, DrawablePtr drawable,
|
|||
CARD32 *num_screen_modifiers,
|
||||
CARD64 **screen_modifiers);
|
||||
|
||||
int
|
||||
dri3_import_syncobj(ClientPtr client, ScreenPtr screen, XID id, int fd);
|
||||
|
||||
#endif /* _DRI3PRIV_H_ */
|
||||
|
|
|
@ -29,6 +29,17 @@
|
|||
#include <drm_fourcc.h>
|
||||
#include "randrstr_priv.h"
|
||||
|
||||
static Bool
|
||||
dri3_screen_can_one_point_four(ScreenPtr screen)
|
||||
{
|
||||
dri3_screen_priv_ptr dri3 = dri3_screen_priv(screen);
|
||||
|
||||
return dri3 &&
|
||||
dri3->info &&
|
||||
dri3->info->version >= 4 &&
|
||||
dri3->info->import_syncobj;
|
||||
}
|
||||
|
||||
static Bool
|
||||
dri3_screen_can_one_point_two(ScreenPtr screen)
|
||||
{
|
||||
|
@ -62,6 +73,10 @@ proc_dri3_query_version(ClientPtr client)
|
|||
rep.minorVersion = 0;
|
||||
break;
|
||||
}
|
||||
if (!dri3_screen_can_one_point_four(screenInfo.screens[i])) {
|
||||
rep.minorVersion = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < screenInfo.numGPUScreens; i++) {
|
||||
|
@ -69,6 +84,10 @@ proc_dri3_query_version(ClientPtr client)
|
|||
rep.minorVersion = 0;
|
||||
break;
|
||||
}
|
||||
if (!dri3_screen_can_one_point_four(screenInfo.gpuscreens[i])) {
|
||||
rep.minorVersion = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* From DRI3 proto:
|
||||
|
@ -576,6 +595,51 @@ proc_dri3_set_drm_device_in_use(ClientPtr client)
|
|||
return Success;
|
||||
}
|
||||
|
||||
static int
|
||||
proc_dri3_import_syncobj(ClientPtr client)
|
||||
{
|
||||
REQUEST(xDRI3ImportSyncobjReq);
|
||||
DrawablePtr drawable;
|
||||
ScreenPtr screen;
|
||||
int fd;
|
||||
int status;
|
||||
|
||||
SetReqFds(client, 1);
|
||||
REQUEST_SIZE_MATCH(xDRI3ImportSyncobjReq);
|
||||
LEGAL_NEW_RESOURCE(stuff->syncobj, client);
|
||||
|
||||
status = dixLookupDrawable(&drawable, stuff->drawable, client,
|
||||
M_ANY, DixGetAttrAccess);
|
||||
if (status != Success)
|
||||
return status;
|
||||
|
||||
screen = drawable->pScreen;
|
||||
|
||||
fd = ReadFdFromClient(client);
|
||||
if (fd < 0)
|
||||
return BadValue;
|
||||
|
||||
return dri3_import_syncobj(client, screen, stuff->syncobj, fd);
|
||||
}
|
||||
|
||||
static int
|
||||
proc_dri3_free_syncobj(ClientPtr client)
|
||||
{
|
||||
REQUEST(xDRI3FreeSyncobjReq);
|
||||
struct dri3_syncobj *syncobj;
|
||||
int status;
|
||||
|
||||
REQUEST_SIZE_MATCH(xDRI3FreeSyncobjReq);
|
||||
|
||||
status = dixLookupResourceByType((void **) &syncobj, stuff->syncobj,
|
||||
dri3_syncobj_type, client, DixWriteAccess);
|
||||
if (status != Success)
|
||||
return status;
|
||||
|
||||
FreeResource(stuff->syncobj, RT_NONE);
|
||||
return Success;
|
||||
}
|
||||
|
||||
int (*proc_dri3_vector[DRI3NumberRequests]) (ClientPtr) = {
|
||||
proc_dri3_query_version, /* 0 */
|
||||
proc_dri3_open, /* 1 */
|
||||
|
@ -587,6 +651,8 @@ int (*proc_dri3_vector[DRI3NumberRequests]) (ClientPtr) = {
|
|||
proc_dri3_pixmap_from_buffers, /* 7 */
|
||||
proc_dri3_buffers_from_pixmap, /* 8 */
|
||||
proc_dri3_set_drm_device_in_use, /* 9 */
|
||||
proc_dri3_import_syncobj, /* 10 */
|
||||
proc_dri3_free_syncobj, /* 11 */
|
||||
};
|
||||
|
||||
int
|
||||
|
@ -731,6 +797,29 @@ sproc_dri3_set_drm_device_in_use(ClientPtr client)
|
|||
return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
|
||||
}
|
||||
|
||||
static int _X_COLD
|
||||
sproc_dri3_import_syncobj(ClientPtr client)
|
||||
{
|
||||
REQUEST(xDRI3ImportSyncobjReq);
|
||||
REQUEST_SIZE_MATCH(xDRI3ImportSyncobjReq);
|
||||
|
||||
swaps(&stuff->length);
|
||||
swapl(&stuff->syncobj);
|
||||
swapl(&stuff->drawable);
|
||||
return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
|
||||
}
|
||||
|
||||
static int _X_COLD
|
||||
sproc_dri3_free_syncobj(ClientPtr client)
|
||||
{
|
||||
REQUEST(xDRI3FreeSyncobjReq);
|
||||
REQUEST_SIZE_MATCH(xDRI3FreeSyncobjReq);
|
||||
|
||||
swaps(&stuff->length);
|
||||
swapl(&stuff->syncobj);
|
||||
return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
|
||||
}
|
||||
|
||||
int (*sproc_dri3_vector[DRI3NumberRequests]) (ClientPtr) = {
|
||||
sproc_dri3_query_version, /* 0 */
|
||||
sproc_dri3_open, /* 1 */
|
||||
|
@ -742,6 +831,8 @@ int (*sproc_dri3_vector[DRI3NumberRequests]) (ClientPtr) = {
|
|||
sproc_dri3_pixmap_from_buffers, /* 7 */
|
||||
sproc_dri3_buffers_from_pixmap, /* 8 */
|
||||
sproc_dri3_set_drm_device_in_use, /* 9 */
|
||||
sproc_dri3_import_syncobj, /* 10 */
|
||||
sproc_dri3_free_syncobj, /* 11 */
|
||||
};
|
||||
|
||||
int _X_COLD
|
||||
|
|
|
@ -272,3 +272,23 @@ dri3_get_supported_modifiers(ScreenPtr screen, DrawablePtr drawable,
|
|||
|
||||
return Success;
|
||||
}
|
||||
|
||||
int dri3_import_syncobj(ClientPtr client, ScreenPtr screen, XID id, int fd)
|
||||
{
|
||||
const dri3_screen_info_rec *info = dri3_screen_priv(screen)->info;
|
||||
struct dri3_syncobj *syncobj = NULL;
|
||||
|
||||
if (info->version < 4 || !info->import_syncobj)
|
||||
return BadImplementation;
|
||||
|
||||
syncobj = info->import_syncobj(client, screen, id, fd);
|
||||
close(fd);
|
||||
|
||||
if (!syncobj)
|
||||
return BadAlloc;
|
||||
|
||||
if (!AddResource(id, dri3_syncobj_type, syncobj))
|
||||
return BadAlloc;
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
|
||||
/* DRI3 */
|
||||
#define SERVER_DRI3_MAJOR_VERSION 1
|
||||
#define SERVER_DRI3_MINOR_VERSION 3
|
||||
#define SERVER_DRI3_MINOR_VERSION 4
|
||||
|
||||
/* Generic event extension */
|
||||
#define SERVER_GE_MAJOR_VERSION 1
|
||||
|
|
|
@ -91,7 +91,7 @@ scrnsaverproto_dep = dependency('scrnsaverproto', version: '>= 1.1', fallback: [
|
|||
resourceproto_dep = dependency('resourceproto', version: '>= 1.2.0', fallback: ['xorgproto', 'ext_xorgproto'])
|
||||
xf86driproto_dep = dependency('xf86driproto', version: '>= 2.1.0', fallback: ['xorgproto', 'ext_xorgproto'], required: get_option('dri1') == 'true')
|
||||
dri2proto_dep = dependency('dri2proto', version: '>= 2.8', fallback: ['xorgproto', 'ext_xorgproto'], required: get_option('dri2') == 'true')
|
||||
dri3proto_dep = dependency('dri3proto', version: '>= 1.3', fallback: ['xorgproto', 'ext_xorgproto'], required: get_option('dri3') == 'true')
|
||||
dri3proto_dep = dependency('dri3proto', version: '>= 1.4', fallback: ['xorgproto', 'ext_xorgproto'], required: get_option('dri3') == 'true')
|
||||
xineramaproto_dep = dependency('xineramaproto', fallback: ['xorgproto', 'ext_xorgproto'])
|
||||
xf86bigfontproto_dep = dependency('xf86bigfontproto', version: '>= 1.2.0', fallback: ['xorgproto', 'ext_xorgproto'], required: get_option('xf86bigfont'))
|
||||
xf86vidmodeproto_dep = dependency('xf86vidmodeproto', version: '>= 2.2.99.1', fallback: ['xorgproto', 'ext_xorgproto'])
|
||||
|
|
Loading…
Reference in New Issue