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:
Erik Kurzinger
2022-08-16 11:57:40 -07:00
committed by Olivier Fourdan
parent f051a2449d
commit 613dcb6a77
7 changed files with 168 additions and 3 deletions

View File

@@ -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