diff options
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | dri3/dri3.c | 19 | ||||
-rw-r--r-- | dri3/dri3.h | 44 | ||||
-rw-r--r-- | dri3/dri3_priv.h | 27 | ||||
-rw-r--r-- | dri3/dri3_request.c | 294 | ||||
-rw-r--r-- | dri3/dri3_screen.c | 196 | ||||
-rw-r--r-- | hw/xwayland/xwayland-glamor.c | 4 | ||||
-rw-r--r-- | meson.build | 2 |
8 files changed, 559 insertions, 29 deletions
diff --git a/configure.ac b/configure.ac index 0ba7550a1..47bf17452 100644 --- a/configure.ac +++ b/configure.ac @@ -729,7 +729,7 @@ SCRNSAVERPROTO="scrnsaverproto >= 1.1" RESOURCEPROTO="resourceproto >= 1.2.0" DRIPROTO="xf86driproto >= 2.1.0" DRI2PROTO="dri2proto >= 2.8" -DRI3PROTO="dri3proto >= 1.0" +DRI3PROTO="dri3proto >= 1.2" XINERAMAPROTO="xineramaproto" BIGFONTPROTO="xf86bigfontproto >= 1.2.0" DGAPROTO="xf86dgaproto >= 2.0.99.1" diff --git a/dri3/dri3.c b/dri3/dri3.c index d042b8b7d..8ac0f3ae2 100644 --- a/dri3/dri3.c +++ b/dri3/dri3.c @@ -26,6 +26,8 @@ #include "dri3_priv.h" +#include <drm_fourcc.h> + static int dri3_request; DevPrivateKeyRec dri3_screen_private_key; @@ -99,3 +101,20 @@ dri3_extension_init(void) bail: FatalError("Cannot initialize DRI3 extension"); } + +uint32_t +drm_format_for_depth(uint32_t depth, uint32_t bpp) +{ + switch (bpp) { + case 16: + return DRM_FORMAT_RGB565; + case 24: + return DRM_FORMAT_XRGB8888; + case 30: + return DRM_FORMAT_XRGB2101010; + case 32: + return DRM_FORMAT_ARGB8888; + default: + return 0; + } +} diff --git a/dri3/dri3.h b/dri3/dri3.h index 7562352ff..89ad13ad9 100644 --- a/dri3/dri3.h +++ b/dri3/dri3.h @@ -28,7 +28,7 @@ #include <X11/extensions/dri3proto.h> #include <randrstr.h> -#define DRI3_SCREEN_INFO_VERSION 1 +#define DRI3_SCREEN_INFO_VERSION 2 typedef int (*dri3_open_proc)(ScreenPtr screen, RRProviderPtr provider, @@ -47,11 +47,43 @@ typedef PixmapPtr (*dri3_pixmap_from_fd_proc) (ScreenPtr screen, CARD8 depth, CARD8 bpp); +typedef PixmapPtr (*dri3_pixmap_from_fds_proc) (ScreenPtr screen, + CARD8 num_fds, + int *fds, + CARD16 width, + CARD16 height, + CARD32 *strides, + CARD32 *offsets, + CARD8 depth, + CARD8 bpp, + CARD64 modifier); + typedef int (*dri3_fd_from_pixmap_proc) (ScreenPtr screen, PixmapPtr pixmap, CARD16 *stride, CARD32 *size); +typedef int (*dri3_fds_from_pixmap_proc) (ScreenPtr screen, + PixmapPtr pixmap, + int *fds, + CARD32 *strides, + CARD32 *offsets, + CARD64 *modifier); + +typedef int (*dri3_get_formats_proc) (ScreenPtr screen, + CARD32 *num_formats, + CARD32 **formats); + +typedef int (*dri3_get_modifiers_proc) (ScreenPtr screen, + CARD32 format, + CARD32 *num_modifiers, + CARD64 **modifiers); + +typedef int (*dri3_get_drawable_modifiers_proc) (DrawablePtr draw, + CARD32 format, + CARD32 *num_modifiers, + CARD64 **modifiers); + typedef struct dri3_screen_info { uint32_t version; @@ -62,6 +94,13 @@ typedef struct dri3_screen_info { /* Version 1 */ dri3_open_client_proc open_client; + /* Version 2 */ + dri3_pixmap_from_fds_proc pixmap_from_fds; + dri3_fds_from_pixmap_proc fds_from_pixmap; + dri3_get_formats_proc get_formats; + dri3_get_modifiers_proc get_modifiers; + dri3_get_drawable_modifiers_proc get_drawable_modifiers; + } dri3_screen_info_rec, *dri3_screen_info_ptr; extern _X_EXPORT Bool @@ -70,6 +109,9 @@ dri3_screen_init(ScreenPtr screen, dri3_screen_info_ptr info); extern _X_EXPORT int dri3_send_open_reply(ClientPtr client, int fd); +extern _X_EXPORT uint32_t +drm_format_for_depth(uint32_t depth, uint32_t bpp); + #endif #endif /* _DRI3_H_ */ diff --git a/dri3/dri3_priv.h b/dri3/dri3_priv.h index e61ef226c..8447680ba 100644 --- a/dri3/dri3_priv.h +++ b/dri3/dri3_priv.h @@ -34,11 +34,21 @@ extern DevPrivateKeyRec dri3_screen_private_key; +typedef struct dri3_dmabuf_format { + uint32_t format; + uint32_t num_modifiers; + uint64_t *modifiers; +} dri3_dmabuf_format_rec, *dri3_dmabuf_format_ptr; + typedef struct dri3_screen_priv { CloseScreenProcPtr CloseScreen; ConfigNotifyProcPtr ConfigNotify; DestroyWindowProcPtr DestroyWindow; + Bool formats_cached; + CARD32 num_formats; + dri3_dmabuf_format_ptr formats; + dri3_screen_info_ptr info; } dri3_screen_priv_rec, *dri3_screen_priv_ptr; @@ -69,10 +79,21 @@ int dri3_open(ClientPtr client, ScreenPtr screen, RRProviderPtr provider, int *fd); int -dri3_pixmap_from_fd(PixmapPtr *ppixmap, ScreenPtr screen, int fd, - CARD16 width, CARD16 height, CARD16 stride, CARD8 depth, CARD8 bpp); +dri3_pixmap_from_fds(PixmapPtr *ppixmap, ScreenPtr screen, CARD8 num_fds, int *fds, + CARD16 width, CARD16 height, CARD32 *strides, CARD32 *offsets, + CARD8 depth, CARD8 bpp, CARD64 modifier); + +int +dri3_fds_from_pixmap(PixmapPtr pixmap, int *fds, + CARD32 *strides, CARD32 *offsets, + CARD64 *modifier); int -dri3_fd_from_pixmap(int *pfd, PixmapPtr pixmap, CARD16 *stride, CARD32 *size); +dri3_get_supported_modifiers(ScreenPtr screen, DrawablePtr drawable, + CARD8 depth, CARD8 bpp, + CARD32 *num_drawable_modifiers, + CARD64 **drawable_modifiers, + CARD32 *num_screen_modifiers, + CARD64 **screen_modifiers); #endif /* _DRI3PRIV_H_ */ diff --git a/dri3/dri3_request.c b/dri3/dri3_request.c index b28d883a5..7f3f0d08c 100644 --- a/dri3/dri3_request.c +++ b/dri3/dri3_request.c @@ -30,6 +30,7 @@ #include <xace.h> #include "../Xext/syncsdk.h" #include <protocol-versions.h> +#include <drm_fourcc.h> static int proc_dri3_query_version(ClientPtr client) @@ -124,6 +125,7 @@ proc_dri3_pixmap_from_buffer(ClientPtr client) int fd; DrawablePtr drawable; PixmapPtr pixmap; + CARD32 stride, offset; int rc; SetReqFds(client, 1); @@ -159,11 +161,14 @@ proc_dri3_pixmap_from_buffer(ClientPtr client) if (fd < 0) return BadValue; - rc = dri3_pixmap_from_fd(&pixmap, - drawable->pScreen, fd, - stuff->width, stuff->height, - stuff->stride, stuff->depth, - stuff->bpp); + offset = 0; + stride = stuff->stride; + rc = dri3_pixmap_from_fds(&pixmap, + drawable->pScreen, 1, &fd, + stuff->width, stuff->height, + &stride, &offset, + stuff->depth, stuff->bpp, + DRM_FORMAT_MOD_INVALID); close (fd); if (rc != Success) return rc; @@ -195,7 +200,10 @@ proc_dri3_buffer_from_pixmap(ClientPtr client) .length = 0, }; int rc; - int fd; + int num_fds; + int fds[4]; + uint32_t strides[4], offsets[4]; + uint64_t modifier; PixmapPtr pixmap; REQUEST_SIZE_MATCH(xDRI3BufferFromPixmapReq); @@ -211,9 +219,12 @@ proc_dri3_buffer_from_pixmap(ClientPtr client) rep.depth = pixmap->drawable.depth; rep.bpp = pixmap->drawable.bitsPerPixel; - rc = dri3_fd_from_pixmap(&fd, pixmap, &rep.stride, &rep.size); - if (rc != Success) - return rc; + num_fds = dri3_fds_from_pixmap(pixmap, fds, strides, offsets, &modifier); + if (num_fds != 1) + return BadPixmap; + + rep.stride = (CARD16) strides[0]; + rep.size = rep.stride * rep.height; if (client->swapped) { swaps(&rep.sequenceNumber); @@ -223,8 +234,8 @@ proc_dri3_buffer_from_pixmap(ClientPtr client) swaps(&rep.height); swaps(&rep.stride); } - if (WriteFdToClient(client, fd, TRUE) < 0) { - close(fd); + if (WriteFdToClient(client, fds[0], TRUE) < 0) { + close(fds[0]); return BadAlloc; } @@ -299,6 +310,216 @@ proc_dri3_fd_from_fence(ClientPtr client) return Success; } +static int +proc_dri3_get_supported_modifiers(ClientPtr client) +{ + REQUEST(xDRI3GetSupportedModifiersReq); + xDRI3GetSupportedModifiersReply rep = { + .type = X_Reply, + .sequenceNumber = client->sequence, + }; + WindowPtr window; + ScreenPtr pScreen; + CARD64 *window_modifiers = NULL; + CARD64 *screen_modifiers = NULL; + CARD32 nwindowmodifiers = 0; + CARD32 nscreenmodifiers = 0; + int status; + int i; + + REQUEST_SIZE_MATCH(xDRI3GetSupportedModifiersReq); + + status = dixLookupWindow(&window, stuff->window, client, DixReadAccess); + if (status != Success) + return status; + pScreen = window->drawable.pScreen; + + dri3_get_supported_modifiers(pScreen, &window->drawable, + stuff->depth, stuff->bpp, + &nwindowmodifiers, &window_modifiers, + &nscreenmodifiers, &screen_modifiers); + + rep.numWindowModifiers = nwindowmodifiers; + rep.numScreenModifiers = nscreenmodifiers; + rep.length = bytes_to_int32(rep.numWindowModifiers * sizeof(CARD64)) + + bytes_to_int32(rep.numScreenModifiers * sizeof(CARD64)); + + if (client->swapped) { + swaps(&rep.sequenceNumber); + swapl(&rep.length); + swapl(&rep.numWindowModifiers); + swapl(&rep.numScreenModifiers); + for (i = 0; i < nwindowmodifiers; i++) + swapll(&window_modifiers[i]); + for (i = 0; i < nscreenmodifiers; i++) + swapll(&screen_modifiers[i]); + } + + WriteToClient(client, sizeof(rep), &rep); + WriteToClient(client, nwindowmodifiers * sizeof(CARD64), window_modifiers); + WriteToClient(client, nscreenmodifiers * sizeof(CARD64), screen_modifiers); + + free(window_modifiers); + free(screen_modifiers); + + return Success; +} + +static int +proc_dri3_pixmap_from_buffers(ClientPtr client) +{ + REQUEST(xDRI3PixmapFromBuffersReq); + int fds[4]; + CARD32 strides[4], offsets[4]; + ScreenPtr screen; + WindowPtr window; + PixmapPtr pixmap; + int rc; + int i; + + SetReqFds(client, stuff->num_buffers); + REQUEST_SIZE_MATCH(xDRI3PixmapFromBuffersReq); + LEGAL_NEW_RESOURCE(stuff->pixmap, client); + rc = dixLookupWindow(&window, stuff->window, client, DixGetAttrAccess); + if (rc != Success) { + client->errorValue = stuff->window; + return rc; + } + screen = window->drawable.pScreen; + + if (!stuff->width || !stuff->height || !stuff->bpp || !stuff->depth) { + client->errorValue = 0; + return BadValue; + } + + if (stuff->width > 32767 || stuff->height > 32767) + return BadAlloc; + + if (stuff->depth != 1) { + DepthPtr depth = screen->allowedDepths; + int j; + for (j = 0; j < screen->numDepths; j++, depth++) + if (depth->depth == stuff->depth) + break; + if (j == screen->numDepths) { + client->errorValue = stuff->depth; + return BadValue; + } + } + + 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) { + while (--i >= 0) + close(fds[i]); + return BadValue; + } + } + + strides[0] = stuff->stride0; + strides[1] = stuff->stride1; + strides[2] = stuff->stride2; + strides[3] = stuff->stride3; + offsets[0] = stuff->offset0; + offsets[1] = stuff->offset1; + offsets[2] = stuff->offset2; + offsets[3] = stuff->offset3; + + rc = dri3_pixmap_from_fds(&pixmap, screen, + stuff->num_buffers, fds, + stuff->width, stuff->height, + strides, offsets, + stuff->depth, stuff->bpp, + stuff->modifier); + + for (i = 0; i < stuff->num_buffers; i++) + close (fds[i]); + + if (rc != Success) + return rc; + + 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) { + (*screen->DestroyPixmap) (pixmap); + return rc; + } + if (!AddResource(stuff->pixmap, RT_PIXMAP, (void *) pixmap)) + return BadAlloc; + + return Success; +} + +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; + uint32_t strides[4], offsets[4]; + uint64_t modifier; + 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; + } + + num_fds = dri3_fds_from_pixmap(pixmap, fds, strides, offsets, &modifier); + if (num_fds == 0) + return BadPixmap; + + rep.nfd = num_fds; + rep.length = bytes_to_int32(num_fds * 2 * sizeof(CARD32)); + rep.width = pixmap->drawable.width; + rep.height = pixmap->drawable.height; + rep.modifier = modifier; + + if (client->swapped) { + swaps(&rep.sequenceNumber); + swapl(&rep.length); + swaps(&rep.width); + swaps(&rep.height); + swapll(&rep.modifier); + for (i = 0; i < num_fds; i++) { + swapl(&strides[i]); + swapl(&offsets[i]); + } + } + + for (i = 0; i < num_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; +} + int (*proc_dri3_vector[DRI3NumberRequests]) (ClientPtr) = { proc_dri3_query_version, /* 0 */ proc_dri3_open, /* 1 */ @@ -306,6 +527,9 @@ 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_modifiers, /* 6 */ + proc_dri3_pixmap_from_buffers, /* 7 */ + proc_dri3_buffers_from_pixmap, /* 8 */ }; int @@ -394,6 +618,51 @@ sproc_dri3_fd_from_fence(ClientPtr client) 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); + 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->window); + 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); + swapll(&stuff->modifier); + 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); +} + int (*sproc_dri3_vector[DRI3NumberRequests]) (ClientPtr) = { sproc_dri3_query_version, /* 0 */ sproc_dri3_open, /* 1 */ @@ -401,6 +670,9 @@ 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_modifiers, /* 6 */ + sproc_dri3_pixmap_from_buffers, /* 7 */ + sproc_dri3_buffers_from_pixmap, /* 8 */ }; int _X_COLD diff --git a/dri3/dri3_screen.c b/dri3/dri3_screen.c index 6c0c60cbf..df40f8281 100644 --- a/dri3/dri3_screen.c +++ b/dri3/dri3_screen.c @@ -29,6 +29,7 @@ #include <misync.h> #include <misyncshm.h> #include <randrstr.h> +#include <drm_fourcc.h> static inline Bool has_open(dri3_screen_info_ptr info) { if (info == NULL) @@ -60,17 +61,30 @@ dri3_open(ClientPtr client, ScreenPtr screen, RRProviderPtr provider, int *fd) } int -dri3_pixmap_from_fd(PixmapPtr *ppixmap, ScreenPtr screen, int fd, - CARD16 width, CARD16 height, CARD16 stride, CARD8 depth, CARD8 bpp) +dri3_pixmap_from_fds(PixmapPtr *ppixmap, ScreenPtr screen, + CARD8 num_fds, int *fds, + CARD16 width, CARD16 height, + CARD32 *strides, CARD32 *offsets, + CARD8 depth, CARD8 bpp, CARD64 modifier) { dri3_screen_priv_ptr ds = dri3_screen_priv(screen); dri3_screen_info_ptr info = ds->info; PixmapPtr pixmap; - if (!info || !info->pixmap_from_fd) + if (!info) return BadImplementation; - pixmap = (*info->pixmap_from_fd) (screen, fd, width, height, stride, depth, bpp); + if (info->version >= 2 && info->pixmap_from_fds != NULL) { + pixmap = (*info->pixmap_from_fds) (screen, num_fds, fds, width, height, + strides, offsets, depth, bpp, modifier); + } else if (info->pixmap_from_fd != NULL && num_fds == 1 && + modifier == DRM_FORMAT_MOD_INVALID) { + pixmap = (*info->pixmap_from_fd) (screen, fds[0], width, height, + strides[0], depth, bpp); + } else { + return BadImplementation; + } + if (!pixmap) return BadAlloc; @@ -79,20 +93,182 @@ dri3_pixmap_from_fd(PixmapPtr *ppixmap, ScreenPtr screen, int fd, } int -dri3_fd_from_pixmap(int *pfd, PixmapPtr pixmap, CARD16 *stride, CARD32 *size) +dri3_fds_from_pixmap(PixmapPtr pixmap, int *fds, + CARD32 *strides, CARD32 *offsets, + CARD64 *modifier) { ScreenPtr screen = pixmap->drawable.pScreen; dri3_screen_priv_ptr ds = dri3_screen_priv(screen); dri3_screen_info_ptr info = ds->info; - int fd; - if (!info || !info->fd_from_pixmap) + if (!info) + return 0; + + if (info->version >= 2 && info->fds_from_pixmap != NULL) { + return (*info->fds_from_pixmap)(screen, pixmap, fds, strides, offsets, + modifier); + } else if (info->fd_from_pixmap != NULL) { + CARD16 stride; + CARD32 size; + + fds[0] = (*info->fd_from_pixmap)(screen, pixmap, &stride, &size); + if (fds[0] < 0) + return 0; + + strides[0] = stride; + offsets[0] = 0; + *modifier = DRM_FORMAT_MOD_INVALID; + return 1; + } else { + return 0; + } +} + +static int +cache_formats_and_modifiers(ScreenPtr screen) +{ + dri3_screen_priv_ptr ds = dri3_screen_priv(screen); + dri3_screen_info_ptr info = ds->info; + CARD32 *formats = NULL; + CARD64 *modifiers = NULL; + int i; + + if (ds->formats_cached) + return Success; + + if (!info) return BadImplementation; - fd = (*info->fd_from_pixmap)(screen, pixmap, stride, size); - if (fd < 0) + if (!info->get_formats || !info->get_modifiers) { + ds->formats = NULL; + ds->num_formats = 0; + ds->formats_cached = TRUE; + return Success; + } + + (*info->get_formats) (screen, &ds->num_formats, &formats); + ds->formats = calloc(ds->num_formats, sizeof(dri3_dmabuf_format_rec)); + if (!ds->formats) return BadAlloc; - *pfd = fd; + + for (i = 0; i < ds->num_formats; i++) { + dri3_dmabuf_format_ptr iter = &ds->formats[i]; + + iter->format = formats[i]; + (*info->get_modifiers) (screen, formats[i], + &iter->num_modifiers, + &modifiers); + + iter->modifiers = malloc(iter->num_modifiers * sizeof(CARD64)); + if (iter->modifiers == NULL) + goto error; + + memcpy(iter->modifiers, modifiers, + iter->num_modifiers * sizeof(CARD64)); + goto done; + +error: + iter->num_modifiers = 0; + free(iter->modifiers); +done: + free(modifiers); + } + free(formats); + ds->formats_cached = TRUE; + return Success; } +int +dri3_get_supported_modifiers(ScreenPtr screen, DrawablePtr drawable, + CARD8 depth, CARD8 bpp, + CARD32 *num_intersect_modifiers, + CARD64 **intersect_modifiers, + CARD32 *num_screen_modifiers, + CARD64 **screen_modifiers) +{ + dri3_screen_priv_ptr ds = dri3_screen_priv(screen); + dri3_screen_info_ptr info = ds->info; + int i, j; + int ret; + CARD32 num_drawable_mods; + CARD64 *drawable_mods; + CARD64 *intersect_mods = NULL; + CARD64 *screen_mods = NULL; + CARD32 format; + dri3_dmabuf_format_ptr screen_format = NULL; + + ret = cache_formats_and_modifiers(screen); + if (ret != Success) + return ret; + + format = drm_format_for_depth(depth, bpp); + if (format == 0) + return BadValue; + + /* Find screen-global modifiers from cache + */ + for (i = 0; i < ds->num_formats; i++) { + if (ds->formats[i].format == format) { + screen_format = &ds->formats[i]; + break; + } + } + if (screen_format == NULL) + return BadMatch; + + if (screen_format->num_modifiers == 0) { + *num_screen_modifiers = 0; + *num_intersect_modifiers = 0; + return Success; + } + + if (info->get_drawable_modifiers) + (*info->get_drawable_modifiers) (drawable, format, + &num_drawable_mods, + &drawable_mods); + + /* We're allocating slightly more memory than necessary but it reduces + * the complexity of finding the intersection set. + */ + screen_mods = malloc(screen_format->num_modifiers * sizeof(CARD64)); + if (!screen_mods) + return BadAlloc; + if (num_drawable_mods > 0) { + intersect_mods = malloc(screen_format->num_modifiers * sizeof(CARD64)); + if (!intersect_mods) { + free(screen_mods); + return BadAlloc; + } + } + + *num_screen_modifiers = 0; + *num_intersect_modifiers = 0; + for (i = 0; i < screen_format->num_modifiers; i++) { + CARD64 modifier = screen_format->modifiers[i]; + Bool intersect = FALSE; + + for (j = 0; j < num_drawable_mods; j++) { + if (drawable_mods[j] == modifier) { + intersect = TRUE; + break; + } + } + + if (intersect) { + intersect_mods[*num_intersect_modifiers] = modifier; + *num_intersect_modifiers += 1; + } else { + screen_mods[*num_screen_modifiers] = modifier; + *num_screen_modifiers += 1; + } + } + + assert(*num_intersect_modifiers + *num_screen_modifiers == screen_format->num_modifiers); + + *intersect_modifiers = intersect_mods; + *screen_modifiers = screen_mods; + free(drawable_mods); + + return Success; +} diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c index 8ffb40d6f..0933e9411 100644 --- a/hw/xwayland/xwayland-glamor.c +++ b/hw/xwayland/xwayland-glamor.c @@ -59,7 +59,7 @@ xwl_glamor_egl_make_current(struct glamor_context *glamor_ctx) } static uint32_t -drm_format_for_depth(int depth) +wl_drm_format_for_depth(int depth) { switch (depth) { case 15: @@ -170,7 +170,7 @@ xwl_glamor_pixmap_get_wl_buffer(PixmapPtr pixmap) wl_drm_create_prime_buffer(xwl_screen->drm, prime_fd, pixmap->drawable.width, pixmap->drawable.height, - drm_format_for_depth(pixmap->drawable.depth), + wl_drm_format_for_depth(pixmap->drawable.depth), 0, gbm_bo_get_stride(xwl_pixmap->bo), 0, 0, 0, 0); diff --git a/meson.build b/meson.build index 430c770cb..d64fb0ca3 100644 --- a/meson.build +++ b/meson.build @@ -78,7 +78,7 @@ scrnsaverproto_dep = dependency('scrnsaverproto', version: '>= 1.1') resourceproto_dep = dependency('resourceproto', version: '>= 1.2.0') xf86driproto_dep = dependency('xf86driproto', version: '>= 2.1.0', required: get_option('dri1') == 'true') dri2proto_dep = dependency('dri2proto', version: '>= 2.8', required: get_option('dri2') == 'true') -dri3proto_dep = dependency('dri3proto', version: '>= 1.0', required: get_option('dri3') == 'true') +dri3proto_dep = dependency('dri3proto', version: '>= 1.2', required: get_option('dri3') == 'true') xineramaproto_dep = dependency('xineramaproto') xf86bigfontproto_dep = dependency('xf86bigfontproto', version: '>= 1.2.0') xf86vidmodeproto_dep = dependency('xf86vidmodeproto', version: '>= 2.2.99.1', required: false) |