From a3db44a50baa02c9c48c612045eb3aaf793da303 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 29 Aug 2008 01:35:26 +1000 Subject: [PATCH] dri: pass GEM handle of front buffer to DRI client --- src/nouveau_bo.c | 72 +++++++++++++++++++++++++++++++++----------- src/nouveau_bo.h | 29 +++++++++--------- src/nouveau_device.c | 2 +- src/nouveau_drmif.h | 5 +++ src/nv_dri.c | 12 ++------ src/nv_dri.h | 7 +---- src/nv_driver.c | 10 +++--- 7 files changed, 84 insertions(+), 53 deletions(-) diff --git a/src/nouveau_bo.c b/src/nouveau_bo.c index a89c97d..8214f31 100644 --- a/src/nouveau_bo.c +++ b/src/nouveau_bo.c @@ -75,6 +75,25 @@ nouveau_bo_ufree(struct nouveau_bo_priv *nvbo) } } +static void +nouveau_bo_kfree(struct nouveau_bo_priv *nvbo) +{ + struct nouveau_device_priv *nvdev = nouveau_device(nvbo->base.device); + struct drm_gem_close req; + + if (!nvbo->handle) + return; + + if (nvbo->map) { + munmap(nvbo->map, nvbo->size); + nvbo->map = NULL; + } + + req.handle = nvbo->handle; + nvbo->handle = 0; + ioctl(nvdev->fd, DRM_IOCTL_GEM_CLOSE, &req); +} + static int nouveau_bo_kalloc(struct nouveau_bo_priv *nvbo) { @@ -111,31 +130,24 @@ nouveau_bo_kalloc(struct nouveau_bo_priv *nvbo) &req, sizeof(req)); if (ret) return ret; - - nvbo->handle = req.handle; nvbo->size = req.size; nvbo->domain = req.domain; - return 0; -} -static void -nouveau_bo_kfree(struct nouveau_bo_priv *nvbo) -{ - struct nouveau_device_priv *nvdev = nouveau_device(nvbo->base.device); - struct drm_gem_close req; + if (nvbo->flags & NOUVEAU_BO_SHARED) { + struct drm_gem_flink f_req; - if (!nvbo->handle) - return; + f_req.handle = req.handle; + ret = ioctl(nvdev->fd, DRM_IOCTL_GEM_FLINK, &f_req); + if (ret) { + nouveau_bo_kfree(nvbo); + return ret; + } - if (nvbo->map) { - munmap(nvbo->map, nvbo->size); - nvbo->map = NULL; + nvbo->global_handle = f_req.name; } - req.handle = nvbo->handle; - nvbo->handle = 0; - ioctl(nvdev->fd, DRM_IOCTL_GEM_CLOSE, &req); + return 0; } static int @@ -219,6 +231,32 @@ nouveau_bo_user(struct nouveau_device *dev, void *ptr, int size, return 0; } +int +nouveau_bo_ref_handle(struct nouveau_device *dev, uint32_t handle, + struct nouveau_bo **bo) +{ + struct nouveau_device_priv *nvdev = nouveau_device(dev); + struct nouveau_bo_priv *nvbo; + struct drm_gem_open req; + int ret; + + ret = nouveau_bo_new(dev, 0, 0, 0, bo); + if (ret) + return ret; + nvbo = nouveau_bo(*bo); + + req.name = handle; + ret = ioctl(nvdev->fd, DRM_IOCTL_GEM_OPEN, &req); + if (ret) { + nouveau_bo_del(bo); + return ret; + } + + nvbo->size = req.size; + nvbo->handle = req.handle; + return 0; +} + int nouveau_bo_ref(struct nouveau_device *dev, uint64_t handle, struct nouveau_bo **bo) diff --git a/src/nouveau_bo.h b/src/nouveau_bo.h index bd51844..1c03005 100644 --- a/src/nouveau_bo.h +++ b/src/nouveau_bo.h @@ -24,20 +24,21 @@ #define __NOUVEAU_BO_H__ /* Relocation/Buffer type flags */ -#define NOUVEAU_BO_VRAM (1 << 0) -#define NOUVEAU_BO_GART (1 << 1) -#define NOUVEAU_BO_RD (1 << 2) -#define NOUVEAU_BO_WR (1 << 3) -#define NOUVEAU_BO_RDWR (NOUVEAU_BO_RD | NOUVEAU_BO_WR) -#define NOUVEAU_BO_MAP (1 << 4) -#define NOUVEAU_BO_PIN (1 << 5) -#define NOUVEAU_BO_LOW (1 << 6) -#define NOUVEAU_BO_HIGH (1 << 7) -#define NOUVEAU_BO_OR (1 << 8) -#define NOUVEAU_BO_LOCAL (1 << 9) -#define NOUVEAU_BO_TILED (1 << 10) -#define NOUVEAU_BO_ZTILE (1 << 11) -#define NOUVEAU_BO_DUMMY (1 << 31) +#define NOUVEAU_BO_VRAM (1 << 0) +#define NOUVEAU_BO_GART (1 << 1) +#define NOUVEAU_BO_RD (1 << 2) +#define NOUVEAU_BO_WR (1 << 3) +#define NOUVEAU_BO_RDWR (NOUVEAU_BO_RD | NOUVEAU_BO_WR) +#define NOUVEAU_BO_MAP (1 << 4) +#define NOUVEAU_BO_PIN (1 << 5) +#define NOUVEAU_BO_LOW (1 << 6) +#define NOUVEAU_BO_HIGH (1 << 7) +#define NOUVEAU_BO_OR (1 << 8) +#define NOUVEAU_BO_LOCAL (1 << 9) +#define NOUVEAU_BO_TILED (1 << 10) +#define NOUVEAU_BO_ZTILE (1 << 11) +#define NOUVEAU_BO_SHARED (1 << 12) +#define NOUVEAU_BO_DUMMY (1 << 31) struct nouveau_bo { struct nouveau_device *device; diff --git a/src/nouveau_device.c b/src/nouveau_device.c index ead5a26..fcc7bdd 100644 --- a/src/nouveau_device.c +++ b/src/nouveau_device.c @@ -26,7 +26,7 @@ #include "nouveau_drmif.h" -#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 107 +#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 108 #error nouveau_drm.h does not match expected patchlevel, update libdrm. #endif diff --git a/src/nouveau_drmif.h b/src/nouveau_drmif.h index 36a12d8..88d4b47 100644 --- a/src/nouveau_drmif.h +++ b/src/nouveau_drmif.h @@ -223,6 +223,7 @@ struct nouveau_bo_priv { void *sysmem; /* Kernel object */ + uint32_t global_handle; unsigned handle; void *map; @@ -247,6 +248,10 @@ NOUVEAU_PRIVATE int nouveau_bo_user(struct nouveau_device *, void *ptr, int size, struct nouveau_bo **); +NOUVEAU_PRIVATE int +nouveau_bo_ref_handle(struct nouveau_device *, uint32_t handle, + struct nouveau_bo **); + NOUVEAU_PRIVATE int nouveau_bo_ref(struct nouveau_device *, uint64_t handle, struct nouveau_bo **); diff --git a/src/nv_dri.c b/src/nv_dri.c index 69c4d45..721cc3f 100644 --- a/src/nv_dri.c +++ b/src/nv_dri.c @@ -320,7 +320,7 @@ Bool NVDRIScreenInit(ScrnInfoPtr pScrn) * We should detect when the DRM decides to change the FB area * but we currently don't know how to. */ - pDRIInfo->frameBufferSize = pNv->VRAMPhysicalSize / 2; + pDRIInfo->frameBufferSize = 0x1000; pDRIInfo->frameBufferPhysicalAddress = (void *)pNv->VRAMPhysical; pDRIInfo->frameBufferStride = pScrn->displayWidth * pScrn->bitsPerPixel/8; @@ -403,16 +403,8 @@ Bool NVDRIFinishScreenInit(ScrnInfoPtr pScrn) pNOUVEAUDRI->depth = pScrn->depth; pNOUVEAUDRI->bpp = pScrn->bitsPerPixel; - pNOUVEAUDRI->front_offset = pNv->FB->offset; + pNOUVEAUDRI->front_handle = nouveau_bo(pNv->FB)->global_handle; pNOUVEAUDRI->front_pitch = pScrn->displayWidth; - /* back/depth buffers will likely be allocated on a per-drawable - * basis, but these may be useful if we want to support shared back - * buffers at some point. - */ - pNOUVEAUDRI->back_offset = 0; - pNOUVEAUDRI->back_pitch = 0; - pNOUVEAUDRI->depth_offset = 0; - pNOUVEAUDRI->depth_pitch = 0; return TRUE; } diff --git a/src/nv_dri.h b/src/nv_dri.h index c2502c9..3ad4b82 100644 --- a/src/nv_dri.h +++ b/src/nv_dri.h @@ -15,13 +15,8 @@ typedef struct { uint32_t bus_type; /**< \brief ths bus type */ uint32_t bus_mode; /**< \brief bus mode (used for AGP, maybe also for PCI-E ?) */ - uint32_t front_offset; /**< \brief front buffer offset */ + uint32_t front_handle; uint32_t front_pitch; /**< \brief front buffer pitch */ - uint32_t back_offset; /**< \brief private back buffer offset */ - uint32_t back_pitch; /**< \brief private back buffer pitch */ - uint32_t depth_offset; /**< \brief private depth buffer offset */ - uint32_t depth_pitch; /**< \brief private depth buffer pitch */ - } NOUVEAUDRIRec, *NOUVEAUDRIPtr; #endif diff --git a/src/nv_driver.c b/src/nv_driver.c index 422997c..fbf2dba 100644 --- a/src/nv_driver.c +++ b/src/nv_driver.c @@ -1983,11 +1983,11 @@ NVScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) return FALSE; } - if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_PIN, - 0, - NOUVEAU_ALIGN(pScrn->virtualX, 64) * - NOUVEAU_ALIGN(pScrn->virtualY, 64) * - (pScrn->bitsPerPixel >> 3), &pNv->FB)) { + if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_PIN | + NOUVEAU_BO_SHARED, 0, + NOUVEAU_ALIGN(pScrn->virtualX, 64) * + NOUVEAU_ALIGN(pScrn->virtualY, 64) * + (pScrn->bitsPerPixel >> 3), &pNv->FB)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate memory for screen pixmap.\n"); return FALSE; -- 2.32.0.93.g670b81a890