[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