Initial skeleton support for DRI3 v1.1. Does absolutely nothing useful whatsoever right now.
Signed-off-by: Daniel Stone <[email protected]> --- 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 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
