From 8e7e0dd9c27bbcf21f821d26895123f38925a70d Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 15 Nov 2013 16:39:38 +1000 Subject: dri3: initial support Signed-off-by: Ben Skeggs --- src/Makefile.am | 3 +- src/nouveau_dri3.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/nv_driver.c | 6 +++- src/nv_proto.h | 9 +++++ 4 files changed, 119 insertions(+), 2 deletions(-) create mode 100644 src/nouveau_dri3.c diff --git a/src/Makefile.am b/src/Makefile.am index 2806852..96adb6e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -30,7 +30,8 @@ nouveau_drv_la_LDFLAGS = -module -avoid-version @LIBDRM_NOUVEAU_LIBS@ \ nouveau_drv_ladir = @moduledir@/drivers if DRI3 -NOUVEAU_DRI3_SOURCES = nouveau_sync.c +NOUVEAU_DRI3_SOURCES = nouveau_sync.c \ + nouveau_dri3.c endif nouveau_drv_la_SOURCES = $(NOUVEAU_DRI3_SOURCES) \ diff --git a/src/nouveau_dri3.c b/src/nouveau_dri3.c new file mode 100644 index 0000000..8cdfd15 --- /dev/null +++ b/src/nouveau_dri3.c @@ -0,0 +1,103 @@ +/* + * Copyright 2013 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ + +#include +#include +#include + +#include "nv_include.h" +#include "dri3.h" + +static int +nouveau_dri3_open(ScreenPtr screen, RRProviderPtr provider, int *fd) +{ + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + NVPtr pNv = NVPTR(scrn); + + *fd = open(pNv->drm_device_name, O_RDWR | O_CLOEXEC, 0); + if ((*fd) < 0) + return BadAlloc; + + return Success; +} + +static PixmapPtr +nouveau_dri3_import(ScreenPtr screen, int fd, CARD16 width, CARD16 height, + CARD16 stride, CARD8 depth, CARD8 bpp) +{ + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + NVPtr pNv = NVPTR(scrn); + PixmapPtr ppix; + struct nouveau_pixmap *priv; + int ret; + + ppix = screen->CreatePixmap(screen, 0, 0, depth, 0); + priv = ppix ? nouveau_pixmap(ppix) : NULL; + if (!priv) + return NULL; + + ret = nouveau_bo_prime_handle_ref(pNv->dev, fd, &priv->bo); + if (ret) { + screen->DestroyPixmap(ppix); + return NULL; + } + + screen->ModifyPixmapHeader(ppix, width, height, 0, 0, stride, NULL); + return ppix; +} + +static int +nouveau_dri3_export(ScreenPtr screen, PixmapPtr pixmap, + CARD16 *stride, CARD32 *size) +{ + struct nouveau_pixmap *priv = nouveau_pixmap(pixmap); + if (priv && priv->bo) { + int fd, ret = nouveau_bo_set_prime(priv->bo, &fd); + if (ret == 0) { + *stride = exaGetPixmapPitch(pixmap); + *size = priv->bo->size; + } + return ret ? ret : fd; + } + return -EINVAL; +} + +static struct dri3_screen_info +nouveau_dri3 = { + .version = DRI3_SCREEN_INFO_VERSION, + .open = nouveau_dri3_open, + .pixmap_from_fd = nouveau_dri3_import, + .fd_from_pixmap = nouveau_dri3_export, +}; + +void +nouveau_dri3_fini(ScreenPtr screen) +{ +} + +Bool +nouveau_dri3_init(ScreenPtr screen) +{ + return dri3_screen_init(screen, &nouveau_dri3); +} diff --git a/src/nv_driver.c b/src/nv_driver.c index 8d02917..581f0c3 100644 --- a/src/nv_driver.c +++ b/src/nv_driver.c @@ -567,6 +567,7 @@ NVCloseScreen(CLOSE_SCREEN_ARGS_DECL) drmmode_screen_fini(pScreen); if (!pNv->NoAccel) { + nouveau_dri3_fini(pScreen); nouveau_sync_fini(pScreen); nouveau_dri2_fini(pScreen); } @@ -1275,7 +1276,10 @@ NVScreenInit(SCREEN_INIT_ARGS_DECL) } if (!pNv->NoAccel) { - nouveau_sync_init(pScreen); + if (nouveau_sync_init(pScreen) && + nouveau_dri3_init(pScreen)) { + } + nouveau_dri2_init(pScreen); } diff --git a/src/nv_proto.h b/src/nv_proto.h index 8175e98..5eba275 100644 --- a/src/nv_proto.h +++ b/src/nv_proto.h @@ -43,6 +43,15 @@ static inline void nouveau_sync_fini(ScreenPtr pScreen) { } Bool nouveau_dri2_init(ScreenPtr pScreen); void nouveau_dri2_fini(ScreenPtr pScreen); +/* in nouveau_dri3.c */ +#ifdef DRI3 +Bool nouveau_dri3_init(ScreenPtr pScreen); +void nouveau_dri3_fini(ScreenPtr pScreen); +#else +static inline Bool nouveau_dri3_init(ScreenPtr pScreen) { return FALSE; } +static inline void nouveau_dri3_fini(ScreenPtr pScreen) { } +#endif + /* in nouveau_xv.c */ void NVInitVideo(ScreenPtr); void NVTakedownVideo(ScrnInfoPtr); -- cgit v1.2.1