Update to xserver 1.20.5. Tested by jsg@

This commit is contained in:
matthieu
2019-07-27 07:57:06 +00:00
parent 14e30ce507
commit a77e9959f3
723 changed files with 37176 additions and 23951 deletions

View File

@@ -69,7 +69,7 @@ CONFIG_HEADER = $(top_builddir)/include/do-not-use-config.h \
$(top_builddir)/include/xorg-config.h \
$(top_builddir)/include/xkb-config.h \
$(top_builddir)/include/xwin-config.h \
$(top_builddir)/include/kdrive-config.h \
$(top_builddir)/include/xwayland-config.h \
$(top_builddir)/include/version-config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
@@ -337,6 +337,7 @@ RANLIB = @RANLIB@
RAWCPP = @RAWCPP@
RAWCPPFLAGS = @RAWCPPFLAGS@
RELEASE_DATE = @RELEASE_DATE@
SCANNER_ARG = @SCANNER_ARG@
SDK_REQUIRED_MODULES = @SDK_REQUIRED_MODULES@
SED = @SED@
SELINUX_CFLAGS = @SELINUX_CFLAGS@
@@ -355,15 +356,18 @@ SYSCONFDIR = @SYSCONFDIR@
SYSTEMD_DAEMON_CFLAGS = @SYSTEMD_DAEMON_CFLAGS@
SYSTEMD_DAEMON_LIBS = @SYSTEMD_DAEMON_LIBS@
TRADITIONALCPPFLAGS = @TRADITIONALCPPFLAGS@
TSLIB_CFLAGS = @TSLIB_CFLAGS@
TSLIB_LIBS = @TSLIB_LIBS@
UDEV_CFLAGS = @UDEV_CFLAGS@
UDEV_LIBS = @UDEV_LIBS@
UTILS_SYS_LIBS = @UTILS_SYS_LIBS@
VENDOR_NAME_SHORT = @VENDOR_NAME_SHORT@
VERSION = @VERSION@
WAYLAND_EGLSTREAM_CFLAGS = @WAYLAND_EGLSTREAM_CFLAGS@
WAYLAND_EGLSTREAM_DATADIR = @WAYLAND_EGLSTREAM_DATADIR@
WAYLAND_EGLSTREAM_LIBS = @WAYLAND_EGLSTREAM_LIBS@
WAYLAND_PROTOCOLS_DATADIR = @WAYLAND_PROTOCOLS_DATADIR@
WAYLAND_SCANNER = @WAYLAND_SCANNER@
WAYLAND_SCANNER_CFLAGS = @WAYLAND_SCANNER_CFLAGS@
WAYLAND_SCANNER_LIBS = @WAYLAND_SCANNER_LIBS@
WINDOWSDRI_CFLAGS = @WINDOWSDRI_CFLAGS@
WINDOWSDRI_LIBS = @WINDOWSDRI_LIBS@
WINDOWSWM_CFLAGS = @WINDOWSWM_CFLAGS@
@@ -371,6 +375,8 @@ WINDOWSWM_LIBS = @WINDOWSWM_LIBS@
WINDRES = @WINDRES@
X11EXAMPLES_DEP_CFLAGS = @X11EXAMPLES_DEP_CFLAGS@
X11EXAMPLES_DEP_LIBS = @X11EXAMPLES_DEP_LIBS@
XCONFIGDIR = @XCONFIGDIR@
XCONFIGFILE = @XCONFIGFILE@
XDMCP_CFLAGS = @XDMCP_CFLAGS@
XDMCP_LIBS = @XDMCP_LIBS@
XDMXCONFIG_DEP_CFLAGS = @XDMXCONFIG_DEP_CFLAGS@
@@ -442,8 +448,6 @@ XWIN_SERVER_NAME = @XWIN_SERVER_NAME@
XWIN_SYS_LIBS = @XWIN_SYS_LIBS@
YACC = @YACC@
YFLAGS = @YFLAGS@
__XCONFIGDIR__ = @__XCONFIGDIR__@
__XCONFIGFILE__ = @__XCONFIGFILE__@
abi_ansic = @abi_ansic@
abi_extension = @abi_extension@
abi_videodrv = @abi_videodrv@

View File

@@ -26,6 +26,8 @@
#include "dri3_priv.h"
#include <drm_fourcc.h>
static int dri3_request;
DevPrivateKeyRec dri3_screen_private_key;
@@ -43,7 +45,7 @@ dri3_close_screen(ScreenPtr screen)
}
Bool
dri3_screen_init(ScreenPtr screen, dri3_screen_info_ptr info)
dri3_screen_init(ScreenPtr screen, const dri3_screen_info_rec *info)
{
dri3_screen_generation = serverGeneration;
@@ -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;
}
}

View File

@@ -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,
const int *fds,
CARD16 width,
CARD16 height,
const CARD32 *strides,
const 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,
uint32_t *strides,
uint32_t *offsets,
uint64_t *modifier);
typedef int (*dri3_get_formats_proc) (ScreenPtr screen,
CARD32 *num_formats,
CARD32 **formats);
typedef int (*dri3_get_modifiers_proc) (ScreenPtr screen,
uint32_t format,
uint32_t *num_modifiers,
uint64_t **modifiers);
typedef int (*dri3_get_drawable_modifiers_proc) (DrawablePtr draw,
uint32_t format,
uint32_t *num_modifiers,
uint64_t **modifiers);
typedef struct dri3_screen_info {
uint32_t version;
@@ -62,14 +94,24 @@ 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
dri3_screen_init(ScreenPtr screen, dri3_screen_info_ptr info);
dri3_screen_init(ScreenPtr screen, const dri3_screen_info_rec *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_ */

View File

@@ -34,12 +34,22 @@
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;
dri3_screen_info_ptr info;
Bool formats_cached;
CARD32 num_formats;
dri3_dmabuf_format_ptr formats;
const dri3_screen_info_rec *info;
} dri3_screen_priv_rec, *dri3_screen_priv_ptr;
#define wrap(priv,real,mem,func) {\
@@ -69,10 +79,26 @@ 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, const int *fds,
CARD16 width, CARD16 height,
const CARD32 *strides, const CARD32 *offsets,
CARD8 depth, CARD8 bpp, CARD64 modifier);
int
dri3_fd_from_pixmap(int *pfd, PixmapPtr pixmap, CARD16 *stride, CARD32 *size);
dri3_fd_from_pixmap(PixmapPtr pixmap, CARD16 *stride, CARD32 *size);
int
dri3_fds_from_pixmap(PixmapPtr pixmap, int *fds,
uint32_t *strides, uint32_t *offsets,
uint64_t *modifier);
int
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_ */

View File

@@ -30,6 +30,21 @@
#include <xace.h>
#include "../Xext/syncsdk.h"
#include <protocol-versions.h>
#include <drm_fourcc.h>
static Bool
dri3_screen_can_one_point_two(ScreenPtr screen)
{
dri3_screen_priv_ptr dri3 = dri3_screen_priv(screen);
if (dri3 && dri3->info && dri3->info->version >= 2 &&
dri3->info->pixmap_from_fds && dri3->info->fds_from_pixmap &&
dri3->info->get_formats && dri3->info->get_modifiers &&
dri3->info->get_drawable_modifiers)
return TRUE;
return FALSE;
}
static int
proc_dri3_query_version(ClientPtr client)
@@ -44,7 +59,35 @@ proc_dri3_query_version(ClientPtr client)
};
REQUEST_SIZE_MATCH(xDRI3QueryVersionReq);
(void) stuff;
for (int i = 0; i < screenInfo.numScreens; i++) {
if (!dri3_screen_can_one_point_two(screenInfo.screens[i])) {
rep.minorVersion = 0;
break;
}
}
for (int i = 0; i < screenInfo.numGPUScreens; i++) {
if (!dri3_screen_can_one_point_two(screenInfo.gpuscreens[i])) {
rep.minorVersion = 0;
break;
}
}
/* From DRI3 proto:
*
* The client sends the highest supported version to the server
* and the server sends the highest version it supports, but no
* higher than the requested version.
*/
if (rep.majorVersion > stuff->majorVersion ||
(rep.majorVersion == stuff->majorVersion &&
rep.minorVersion > stuff->minorVersion)) {
rep.majorVersion = stuff->majorVersion;
rep.minorVersion = stuff->minorVersion;
}
if (client->swapped) {
swaps(&rep.sequenceNumber);
swapl(&rep.length);
@@ -92,7 +135,7 @@ proc_dri3_open(ClientPtr client)
REQUEST_SIZE_MATCH(xDRI3OpenReq);
status = dixLookupDrawable(&drawable, stuff->drawable, client, 0, DixReadAccess);
status = dixLookupDrawable(&drawable, stuff->drawable, client, 0, DixGetAttrAccess);
if (status != Success)
return status;
@@ -124,6 +167,7 @@ proc_dri3_pixmap_from_buffer(ClientPtr client)
int fd;
DrawablePtr drawable;
PixmapPtr pixmap;
CARD32 stride, offset;
int rc;
SetReqFds(client, 1);
@@ -159,11 +203,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;
@@ -211,9 +258,9 @@ 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;
fd = dri3_fd_from_pixmap(pixmap, &rep.stride, &rep.size);
if (fd < 0)
return BadPixmap;
if (client->swapped) {
swaps(&rep.sequenceNumber);
@@ -299,6 +346,218 @@ 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, DixGetAttrAccess);
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(xDRI3BuffersFromPixmapReq);
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.depth = pixmap->drawable.depth;
rep.bpp = pixmap->drawable.bitsPerPixel;
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 +565,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
@@ -319,7 +581,7 @@ proc_dri3_dispatch(ClientPtr client)
return (*proc_dri3_vector[stuff->data]) (client);
}
static int
static int _X_COLD
sproc_dri3_query_version(ClientPtr client)
{
REQUEST(xDRI3QueryVersionReq);
@@ -331,7 +593,7 @@ sproc_dri3_query_version(ClientPtr client)
return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
}
static int
static int _X_COLD
sproc_dri3_open(ClientPtr client)
{
REQUEST(xDRI3OpenReq);
@@ -343,7 +605,7 @@ sproc_dri3_open(ClientPtr client)
return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
}
static int
static int _X_COLD
sproc_dri3_pixmap_from_buffer(ClientPtr client)
{
REQUEST(xDRI3PixmapFromBufferReq);
@@ -359,7 +621,7 @@ sproc_dri3_pixmap_from_buffer(ClientPtr client)
return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
}
static int
static int _X_COLD
sproc_dri3_buffer_from_pixmap(ClientPtr client)
{
REQUEST(xDRI3BufferFromPixmapReq);
@@ -370,7 +632,7 @@ sproc_dri3_buffer_from_pixmap(ClientPtr client)
return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
}
static int
static int _X_COLD
sproc_dri3_fence_from_fd(ClientPtr client)
{
REQUEST(xDRI3FenceFromFDReq);
@@ -382,7 +644,7 @@ sproc_dri3_fence_from_fd(ClientPtr client)
return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
}
static int
static int _X_COLD
sproc_dri3_fd_from_fence(ClientPtr client)
{
REQUEST(xDRI3FDFromFenceReq);
@@ -394,6 +656,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,9 +708,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_modifiers, /* 6 */
sproc_dri3_pixmap_from_buffers, /* 7 */
sproc_dri3_buffers_from_pixmap, /* 8 */
};
int
int _X_COLD
sproc_dri3_dispatch(ClientPtr client)
{
REQUEST(xReq);

View File

@@ -29,48 +29,50 @@
#include <misync.h>
#include <misyncshm.h>
#include <randrstr.h>
static inline Bool has_open(dri3_screen_info_ptr info) {
if (info == NULL)
return FALSE;
return info->open != NULL ||
(info->version >= 1 && info->open_client != NULL);
}
#include <drm_fourcc.h>
#include <unistd.h>
int
dri3_open(ClientPtr client, ScreenPtr screen, RRProviderPtr provider, int *fd)
{
dri3_screen_priv_ptr ds = dri3_screen_priv(screen);
dri3_screen_info_ptr info = ds->info;
int rc;
const dri3_screen_info_rec *info = ds->info;
if (!has_open(info))
if (info == NULL)
return BadMatch;
if (info->version >= 1 && info->open_client != NULL)
rc = (*info->open_client) (client, screen, provider, fd);
else
rc = (*info->open) (screen, provider, fd);
return (*info->open_client) (client, screen, provider, fd);
if (info->open != NULL)
return (*info->open) (screen, provider, fd);
if (rc != Success)
return rc;
return Success;
return BadMatch;
}
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, const int *fds,
CARD16 width, CARD16 height,
const CARD32 *strides, const CARD32 *offsets,
CARD8 depth, CARD8 bpp, CARD64 modifier)
{
dri3_screen_priv_ptr ds = dri3_screen_priv(screen);
dri3_screen_info_ptr info = ds->info;
const dri3_screen_info_rec *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) {
pixmap = (*info->pixmap_from_fd) (screen, fds[0], width, height,
strides[0], depth, bpp);
} else {
return BadImplementation;
}
if (!pixmap)
return BadAlloc;
@@ -79,20 +81,230 @@ 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,
uint32_t *strides, uint32_t *offsets,
uint64_t *modifier)
{
ScreenPtr screen = pixmap->drawable.pScreen;
dri3_screen_priv_ptr ds = dri3_screen_priv(screen);
dri3_screen_info_ptr info = ds->info;
int fd;
const dri3_screen_info_rec *info = ds->info;
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;
}
}
int
dri3_fd_from_pixmap(PixmapPtr pixmap, CARD16 *stride, CARD32 *size)
{
ScreenPtr screen = pixmap->drawable.pScreen;
dri3_screen_priv_ptr ds = dri3_screen_priv(screen);
const dri3_screen_info_rec *info = ds->info;
uint32_t strides[4];
uint32_t offsets[4];
uint64_t modifier;
int fds[4];
int num_fds;
if (!info)
return -1;
/* Preferentially use the old interface, allowing the implementation to
* ensure the buffer is in a single-plane format which doesn't need
* modifiers. */
if (info->fd_from_pixmap != NULL)
return (*info->fd_from_pixmap)(screen, pixmap, stride, size);
if (info->version < 2 || info->fds_from_pixmap == NULL)
return -1;
/* If using the new interface, make sure that it's a single plane starting
* at 0 within the BO. We don't check the modifier, as the client may
* have an auxiliary mechanism for determining the modifier itself. */
num_fds = info->fds_from_pixmap(screen, pixmap, fds, strides, offsets,
&modifier);
if (num_fds != 1 || offsets[0] != 0) {
int i;
for (i = 0; i < num_fds; i++)
close(fds[i]);
return -1;
}
*stride = strides[0];
*size = size[0];
return fds[0];
}
static int
cache_formats_and_modifiers(ScreenPtr screen)
{
dri3_screen_priv_ptr ds = dri3_screen_priv(screen);
const dri3_screen_info_rec *info = ds->info;
CARD32 num_formats;
CARD32 *formats;
uint32_t num_modifiers;
uint64_t *modifiers;
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->version < 2 || !info->get_formats || !info->get_modifiers) {
ds->formats = NULL;
ds->num_formats = 0;
ds->formats_cached = TRUE;
return Success;
}
if (!info->get_formats(screen, &num_formats, &formats))
return BadAlloc;
*pfd = fd;
if (!num_formats) {
ds->num_formats = 0;
ds->formats_cached = TRUE;
return Success;
}
ds->formats = calloc(num_formats, sizeof(dri3_dmabuf_format_rec));
if (!ds->formats)
return BadAlloc;
for (i = 0; i < num_formats; i++) {
dri3_dmabuf_format_ptr iter = &ds->formats[i];
if (!info->get_modifiers(screen, formats[i],
&num_modifiers,
&modifiers))
continue;
if (!num_modifiers)
continue;
iter->format = formats[i];
iter->num_modifiers = num_modifiers;
iter->modifiers = modifiers;
}
ds->num_formats = i;
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);
const dri3_screen_info_rec *info = ds->info;
int i, j;
int ret;
uint32_t num_drawable_mods;
uint64_t *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)) {
num_drawable_mods = 0;
drawable_mods = NULL;
}
/* 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;
}