[RFC xserver 03/16] DRI3: Add multi-planar/modifier buffer requests
Daniel Stone
daniels at collabora.com
Thu Jun 8 18:43:29 UTC 2017
Initial skeleton support for DRI3 v1.1. Does absolutely nothing useful
whatsoever right now.
Signed-off-by: Daniel Stone <daniels at collabora.com>
---
dri3/dri3_request.c | 392 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 392 insertions(+)
diff --git a/dri3/dri3_request.c b/dri3/dri3_request.c
index b28d883a5..336175d92 100644
--- a/dri3/dri3_request.c
+++ b/dri3/dri3_request.c
@@ -299,6 +299,303 @@ proc_dri3_fd_from_fence(ClientPtr client)
return Success;
}
+static int
+proc_dri3_get_supported_formats(ClientPtr client)
+{
+ REQUEST(xDRI3GetSupportedFormatsReq);
+ xDRI3GetSupportedFormatsReply rep = {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ };
+ DrawablePtr drawable;
+ ScreenPtr pScreen;
+ CARD32 *formats = NULL;
+ int nformats = 0;
+ int status;
+ int i;
+
+ REQUEST_SIZE_MATCH(xDRI3GetSupportedFormatsReq);
+
+ status = dixLookupDrawable(&drawable, stuff->window, client, 0,
+ DixReadAccess);
+ if (status != Success)
+ return status;
+ pScreen = drawable->pScreen;
+
+ rep.numFormats = nformats;
+ rep.length = bytes_to_int32(rep.numFormats * sizeof(CARD32));
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swapl(&rep.numFormats);
+ for (i = 0; i < nformats; i++)
+ swapl(&formats[i]);
+ }
+
+ WriteToClient(client, sizeof(rep), &rep);
+ WriteToClient(client, nformats * sizeof(CARD32), formats);
+
+ return Success;
+}
+
+static int
+proc_dri3_get_supported_modifiers(ClientPtr client)
+{
+ REQUEST(xDRI3GetSupportedModifiersReq);
+ xDRI3GetSupportedModifiersReply rep = {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ };
+ DrawablePtr drawable;
+ ScreenPtr pScreen;
+ CARD32 *modifiers_hi = NULL;
+ CARD32 *modifiers_lo = NULL;
+ int nmodifiers = 0;
+ int status;
+ int i;
+
+ REQUEST_SIZE_MATCH(xDRI3GetSupportedModifiersReq);
+
+ status = dixLookupDrawable(&drawable, stuff->window, client, 0,
+ DixReadAccess);
+ if (status != Success)
+ return status;
+ pScreen = drawable->pScreen;
+
+ rep.numModifiers = nmodifiers;
+ rep.length = bytes_to_int32(2 * rep.numModifiers * sizeof(CARD32));
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swapl(&rep.numModifiers);
+ for (i = 0; i < nmodifiers; i++) {
+ swapl(&modifiers_hi[i]);
+ swapl(&modifiers_lo[i]);
+ }
+ }
+
+ WriteToClient(client, sizeof(rep), &rep);
+
+ for (i = 0; i < nmodifiers; i++) {
+ /* XXX: Could this be better ... ? */
+ WriteToClient(client, sizeof(CARD32), &modifiers_hi[i]);
+ WriteToClient(client, sizeof(CARD32), &modifiers_lo[i]);
+ }
+
+ free(modifiers_hi);
+ free(modifiers_lo);
+
+ return Success;
+}
+
+static int
+proc_dri3_pixmap_from_buffers(ClientPtr client)
+{
+ REQUEST(xDRI3PixmapFromBuffersReq);
+ int fds[4];
+ DrawablePtr drawable;
+ PixmapPtr pixmap;
+ int rc;
+ int i;
+
+ SetReqFds(client, stuff->num_buffers);
+ REQUEST_SIZE_MATCH(xDRI3PixmapFromBuffersReq);
+ LEGAL_NEW_RESOURCE(stuff->pixmap, client);
+ rc = dixLookupDrawable(&drawable, stuff->drawable, client, M_ANY, DixGetAttrAccess);
+ if (rc != Success) {
+ client->errorValue = stuff->drawable;
+ return rc;
+ }
+
+ if (!stuff->width || !stuff->height || !stuff->format) {
+ client->errorValue = 0;
+ return BadValue;
+ }
+
+ if (stuff->width > 32767 || stuff->height > 32767)
+ return BadAlloc;
+
+ if (!stuff->num_buffers || stuff->num_buffers > 4) {
+ client->errorValue = stuff->num_buffers;
+ return BadValue;
+ }
+
+ for (i = 0; i < stuff->num_buffers; i++) {
+ fds[i] = ReadFdFromClient(client);
+ if (fds[i] < 0)
+ return BadValue;
+ }
+
+ /* XXX: DTRT */
+ rc = dri3_pixmap_from_fd(&pixmap,
+ drawable->pScreen, fds[0],
+ stuff->width, stuff->height,
+ stuff->stride0,
+ 0, 0);
+ if (rc != Success)
+ goto error;
+
+ pixmap->drawable.id = stuff->pixmap;
+
+ /* security creation/labeling check */
+ rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pixmap, RT_PIXMAP,
+ pixmap, RT_NONE, NULL, DixCreateAccess);
+
+ if (rc != Success) {
+ (*drawable->pScreen->DestroyPixmap) (pixmap);
+ goto error;
+ }
+ if (!AddResource(stuff->pixmap, RT_PIXMAP, (void *) pixmap)) {
+ rc = BadAlloc;
+ goto error;
+ }
+
+ return Success;
+
+error:
+ for (i = 0; i < stuff->num_buffers; i++)
+ close (fds[i]);
+ return rc;
+}
+
+static int
+proc_dri3_buffers_from_pixmap(ClientPtr client)
+{
+ REQUEST(xDRI3BuffersFromPixmapReq);
+ xDRI3BuffersFromPixmapReply rep = {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ };
+ int rc;
+ int fds[4];
+ int num_fds;
+ CARD32 strides[4], offsets[4];
+ int i;
+ PixmapPtr pixmap;
+
+ REQUEST_SIZE_MATCH(xDRI3BufferFromPixmapReq);
+ rc = dixLookupResourceByType((void **) &pixmap, stuff->pixmap, RT_PIXMAP,
+ client, DixWriteAccess);
+ if (rc != Success) {
+ client->errorValue = stuff->pixmap;
+ return rc;
+ }
+
+ rep.width = pixmap->drawable.width;
+ rep.height = pixmap->drawable.height;
+ rep.format = 0; /* XXX: DTRT */
+ rep.modifier_hi = 0; /* XXX: DTRT */
+ rep.modifier_lo = 0; /* XXX: DTRT */
+
+ /* XXX: DTRT */
+ num_fds = 1;
+ rc = dri3_fd_from_pixmap(fds, pixmap, (CARD16 *) strides, NULL);
+ if (rc != Success)
+ return rc;
+
+ rep.nfd = num_fds;
+ rep.length = bytes_to_int32(num_fds * 2 * sizeof(CARD32));
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swaps(&rep.width);
+ swaps(&rep.height);
+ swapl(&rep.format);
+ swapl(&rep.modifier_hi);
+ swapl(&rep.modifier_lo);
+ for (i = 0; i < num_fds; i++) {
+ swapl(&strides[i]);
+ swapl(&offsets[i]);
+ }
+ }
+
+ for (i = 0; i < num_fds; i++) {
+ fds[i] = dup(fds[i]);
+ if (WriteFdToClient(client, fds[i], TRUE) < 0) {
+ while (i--)
+ close(fds[i]);
+ return BadAlloc;
+ }
+ }
+
+ WriteToClient(client, sizeof(rep), &rep);
+ WriteToClient(client, num_fds * sizeof(CARD32), strides);
+ WriteToClient(client, num_fds * sizeof(CARD32), offsets);
+
+ return Success;
+}
+
+static int
+proc_dri3_fence_from_dma_fence_fd(ClientPtr client)
+{
+ REQUEST(xDRI3FenceFromFDReq);
+ DrawablePtr drawable;
+ int fd;
+ int status;
+
+ SetReqFds(client, 1);
+ REQUEST_SIZE_MATCH(xDRI3FenceFromDMAFenceFDReq);
+ LEGAL_NEW_RESOURCE(stuff->fence, client);
+
+ status = dixLookupDrawable(&drawable, stuff->drawable, client, M_ANY, DixGetAttrAccess);
+ if (status != Success)
+ return status;
+
+ fd = ReadFdFromClient(client);
+ if (fd < 0)
+ return BadValue;
+
+ /* XXX: DTRT :) */
+ status = SyncCreateFenceFromFD(client, drawable, stuff->fence,
+ fd, stuff->initially_triggered);
+
+ return status;
+}
+
+static int
+proc_dri3_dma_fence_fd_from_fence(ClientPtr client)
+{
+ REQUEST(xDRI3DMAFenceFDFromFenceReq);
+ xDRI3DMAFenceFDFromFenceReply rep = {
+ .type = X_Reply,
+ .nfd = 1,
+ .sequenceNumber = client->sequence,
+ .length = 0,
+ };
+ DrawablePtr drawable;
+ int fd;
+ int status;
+ SyncFence *fence;
+
+ REQUEST_SIZE_MATCH(xDRI3DMAFenceFDFromFenceReq);
+
+ status = dixLookupDrawable(&drawable, stuff->drawable, client, M_ANY, DixGetAttrAccess);
+ if (status != Success)
+ return status;
+ status = SyncVerifyFence(&fence, stuff->fence, client, DixWriteAccess);
+ if (status != Success)
+ return status;
+
+ /* XXX: DTRT :) */
+ fd = SyncFDFromFence(client, drawable, fence);
+ if (fd < 0)
+ return BadMatch;
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ }
+ if (WriteFdToClient(client, fd, FALSE) < 0)
+ return BadAlloc;
+
+ WriteToClient(client, sizeof(rep), &rep);
+
+ return Success;
+}
+
int (*proc_dri3_vector[DRI3NumberRequests]) (ClientPtr) = {
proc_dri3_query_version, /* 0 */
proc_dri3_open, /* 1 */
@@ -306,6 +603,12 @@ int (*proc_dri3_vector[DRI3NumberRequests]) (ClientPtr) = {
proc_dri3_buffer_from_pixmap, /* 3 */
proc_dri3_fence_from_fd, /* 4 */
proc_dri3_fd_from_fence, /* 5 */
+ proc_dri3_get_supported_formats, /* 6 */
+ proc_dri3_get_supported_modifiers, /* 7 */
+ proc_dri3_pixmap_from_buffers, /* 8 */
+ proc_dri3_buffers_from_pixmap, /* 9 */
+ proc_dri3_fence_from_dma_fence_fd, /* 10 */
+ proc_dri3_dma_fence_fd_from_fence, /* 11 */
};
int
@@ -394,6 +697,89 @@ sproc_dri3_fd_from_fence(ClientPtr client)
return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
}
+static int _X_COLD
+sproc_dri3_get_supported_formats(ClientPtr client)
+{
+ REQUEST(xDRI3GetSupportedFormatsReq);
+ REQUEST_SIZE_MATCH(xDRI3GetSupportedFormatsReq);
+
+ swaps(&stuff->length);
+ swapl(&stuff->window);
+ return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
+}
+
+static int _X_COLD
+sproc_dri3_get_supported_modifiers(ClientPtr client)
+{
+ REQUEST(xDRI3GetSupportedModifiersReq);
+ REQUEST_SIZE_MATCH(xDRI3GetSupportedModifiersReq);
+
+ swaps(&stuff->length);
+ swapl(&stuff->window);
+ swapl(&stuff->format);
+ return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
+}
+
+static int _X_COLD
+sproc_dri3_pixmap_from_buffers(ClientPtr client)
+{
+ REQUEST(xDRI3PixmapFromBuffersReq);
+ REQUEST_SIZE_MATCH(xDRI3PixmapFromBuffersReq);
+
+ swaps(&stuff->length);
+ swapl(&stuff->pixmap);
+ swapl(&stuff->drawable);
+ swaps(&stuff->width);
+ swaps(&stuff->height);
+ swapl(&stuff->stride0);
+ swapl(&stuff->offset0);
+ swapl(&stuff->stride1);
+ swapl(&stuff->offset1);
+ swapl(&stuff->stride2);
+ swapl(&stuff->offset2);
+ swapl(&stuff->stride3);
+ swapl(&stuff->offset3);
+ swapl(&stuff->format);
+ swapl(&stuff->modifier_hi);
+ swapl(&stuff->modifier_lo);
+ return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
+}
+
+static int _X_COLD
+sproc_dri3_buffers_from_pixmap(ClientPtr client)
+{
+ REQUEST(xDRI3BuffersFromPixmapReq);
+ REQUEST_SIZE_MATCH(xDRI3BuffersFromPixmapReq);
+
+ swaps(&stuff->length);
+ swapl(&stuff->pixmap);
+ return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
+}
+
+static int _X_COLD
+sproc_dri3_dma_fence_fd_from_fence(ClientPtr client)
+{
+ REQUEST(xDRI3DMAFenceFDFromFenceReq);
+ REQUEST_SIZE_MATCH(xDRI3DMAFenceFDFromFenceReq);
+
+ swaps(&stuff->length);
+ swapl(&stuff->drawable);
+ swapl(&stuff->fence);
+ return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
+}
+
+static int _X_COLD
+sproc_dri3_fence_from_dma_fence_fd(ClientPtr client)
+{
+ REQUEST(xDRI3FenceFromDMAFenceFDReq);
+ REQUEST_SIZE_MATCH(xDRI3FenceFromDMAFenceFDReq);
+
+ swaps(&stuff->length);
+ swapl(&stuff->drawable);
+ swapl(&stuff->fence);
+ return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
+}
+
int (*sproc_dri3_vector[DRI3NumberRequests]) (ClientPtr) = {
sproc_dri3_query_version, /* 0 */
sproc_dri3_open, /* 1 */
@@ -401,6 +787,12 @@ int (*sproc_dri3_vector[DRI3NumberRequests]) (ClientPtr) = {
sproc_dri3_buffer_from_pixmap, /* 3 */
sproc_dri3_fence_from_fd, /* 4 */
sproc_dri3_fd_from_fence, /* 5 */
+ sproc_dri3_get_supported_formats, /* 6 */
+ sproc_dri3_get_supported_modifiers, /* 7 */
+ sproc_dri3_pixmap_from_buffers, /* 8 */
+ sproc_dri3_buffers_from_pixmap, /* 9 */
+ sproc_dri3_fence_from_dma_fence_fd, /* 10 */
+ sproc_dri3_dma_fence_fd_from_fence, /* 11 */
};
int _X_COLD
--
2.13.0
More information about the xorg-devel
mailing list