Changes for single-entity multi-screen DRI.

The entity (device) has a locking SAREA and a master file descriptor
that optionally isn't closed between server generation.

The locking SAREA contains the device hardware lock.
Each DRI screen creates an new SAREA containing the drawable lock,
drawable-and private info, the drawable SAREA.

The first screen optionally shares its drawable SAREA with the
device SAREA.

Default is to close the master descriptor between server generations,
and to share the drawable SAREA of the first screen with the device locking
SAREA. Thus we should (hopefully) have full backwards compatibility.

Mesa changes to support single-device multiple screens are pending.
This commit is contained in:
Thomas Hellstrom 2007-04-16 17:24:53 +02:00
parent b5823ea3e1
commit 02d42f344c
4 changed files with 382 additions and 173 deletions

View File

@ -43,6 +43,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <errno.h>
#define NEED_REPLIES #define NEED_REPLIES
#define NEED_EVENTS #define NEED_EVENTS
@ -77,6 +78,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
extern Bool noPanoramiXExtension; extern Bool noPanoramiXExtension;
#endif #endif
static int DRIEntPrivIndex = -1;
static int DRIScreenPrivIndex = -1; static int DRIScreenPrivIndex = -1;
static int DRIWindowPrivIndex = -1; static int DRIWindowPrivIndex = -1;
static unsigned long DRIGeneration = 0; static unsigned long DRIGeneration = 0;
@ -112,18 +114,203 @@ DRIDrvMsg(int scrnIndex, MessageType type, const char *format, ...)
} }
static void
DRIOpenDRMCleanup(DRIEntPrivPtr pDRIEntPriv)
{
if (pDRIEntPriv->pLSAREA != NULL) {
drmUnmap(pDRIEntPriv->pLSAREA, pDRIEntPriv->sAreaSize);
pDRIEntPriv->pLSAREA = NULL;
}
if (pDRIEntPriv->hLSAREA != 0) {
drmRmMap(pDRIEntPriv->drmFD, pDRIEntPriv->hLSAREA);
}
if (pDRIEntPriv->drmFD >= 0) {
drmClose(pDRIEntPriv->drmFD);
pDRIEntPriv->drmFD = 0;
}
}
int
DRIMasterFD(ScrnInfoPtr pScrn)
{
return DRI_ENT_PRIV(pScrn)->drmFD;
}
void *
DRIMasterSareaPointer(ScrnInfoPtr pScrn)
{
return DRI_ENT_PRIV(pScrn)->pLSAREA;
}
drm_handle_t
DRIMasterSareaHandle(ScrnInfoPtr pScrn)
{
return DRI_ENT_PRIV(pScrn)->hLSAREA;
}
Bool
DRIOpenDRMMaster(ScrnInfoPtr pScrn,
unsigned long sAreaSize,
const char *busID,
const char *drmDriverName)
{
drmSetVersion saveSv, sv;
Bool drmWasAvailable;
DRIEntPrivPtr pDRIEntPriv;
DRIEntPrivRec tmp;
drmVersionPtr drmlibv;
int drmlibmajor, drmlibminor;
const char *openBusID;
int count;
int err;
if (DRIEntPrivIndex == -1)
DRIEntPrivIndex = xf86AllocateEntityPrivateIndex();
pDRIEntPriv = DRI_ENT_PRIV(pScrn);
if (pDRIEntPriv && pDRIEntPriv->drmFD != -1)
return TRUE;
drmWasAvailable = drmAvailable();
memset(&tmp, 0, sizeof(tmp));
/* Check the DRM lib version.
* drmGetLibVersion was not supported in version 1.0, so check for
* symbol first to avoid possible crash or hang.
*/
drmlibmajor = 1;
drmlibminor = 0;
if (xf86LoaderCheckSymbol("drmGetLibVersion")) {
drmlibv = drmGetLibVersion(-1);
if (drmlibv != NULL) {
drmlibmajor = drmlibv->version_major;
drmlibminor = drmlibv->version_minor;
drmFreeVersion(drmlibv);
}
}
/* Check if the libdrm can handle falling back to loading based on name
* if a busid string is passed.
*/
openBusID = (drmlibmajor == 1 && drmlibminor >= 2) ? busID : NULL;
tmp.drmFD = -1;
sv.drm_di_major = 1;
sv.drm_di_minor = 1;
sv.drm_dd_major = -1;
saveSv = sv;
count = 10;
while (count--) {
tmp.drmFD = drmOpen(drmDriverName, openBusID);
if (tmp.drmFD < 0) {
DRIDrvMsg(-1, X_ERROR, "[drm] drmOpen failed.\n");
goto out_err;
}
err = drmSetInterfaceVersion(tmp.drmFD, &sv);
if (err != -EPERM)
break;
sv = saveSv;
drmClose(tmp.drmFD);
tmp.drmFD = -1;
usleep(100000);
}
if (tmp.drmFD <= 0) {
DRIDrvMsg(-1, X_ERROR, "[drm] DRM was busy with another master.\n");
goto out_err;
}
if (!drmWasAvailable) {
DRIDrvMsg(-1, X_INFO,
"[drm] loaded kernel module for \"%s\" driver.\n",
drmDriverName);
}
if (err != 0) {
sv.drm_di_major = 1;
sv.drm_di_minor = 0;
}
DRIDrvMsg(-1, X_INFO, "[drm] DRM interface version %d.%d\n",
sv.drm_di_major, sv.drm_di_minor);
if (sv.drm_di_major == 1 && sv.drm_di_minor >= 1)
err = 0;
else
err = drmSetBusid(tmp.drmFD, busID);
if (err) {
DRIDrvMsg(-1, X_ERROR, "[drm] Could not set DRM device bus ID.\n");
goto out_err;
}
/*
* Create a lock-containing sarea.
*/
if (drmAddMap( tmp.drmFD, 0, sAreaSize, DRM_SHM,
DRM_CONTAINS_LOCK, &tmp.hLSAREA) < 0) {
DRIDrvMsg(-1, X_INFO, "[drm] Could not create SAREA for DRM lock.\n");
tmp.hLSAREA = 0;
goto out_err;
}
if (drmMap( tmp.drmFD, tmp.hLSAREA, sAreaSize,
(drmAddressPtr)(&tmp.pLSAREA)) < 0) {
DRIDrvMsg(-1, X_INFO, "[drm] Mapping SAREA for DRM lock failed.\n");
tmp.pLSAREA = NULL;
goto out_err;
}
memset(tmp.pLSAREA, 0, sAreaSize);
/*
* Reserved contexts are handled by the first opened screen.
*/
tmp.resOwner = NULL;
if (!pDRIEntPriv)
pDRIEntPriv = xnfcalloc(sizeof(*pDRIEntPriv), 1);
if (!pDRIEntPriv) {
DRIDrvMsg(-1, X_INFO, "[drm] Failed to allocate memory for "
"DRM device.\n");
goto out_err;
}
*pDRIEntPriv = tmp;
xf86GetEntityPrivate((pScrn)->entityList[0],DRIEntPrivIndex)->ptr =
pDRIEntPriv;
DRIDrvMsg(-1, X_INFO, "[drm] DRM open master succeeded.\n");
return TRUE;
out_err:
DRIOpenDRMCleanup(&tmp);
return FALSE;
}
Bool Bool
DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD) DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD)
{ {
DRIScreenPrivPtr pDRIPriv; DRIScreenPrivPtr pDRIPriv;
drm_context_t * reserved; drm_context_t * reserved;
int reserved_count; int reserved_count;
int i, fd, drmWasAvailable; int i;
Bool xineramaInCore = FALSE; Bool xineramaInCore = FALSE;
int err = 0; DRIEntPrivPtr pDRIEntPriv;
char *openbusid; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
drmVersionPtr drmlibv;
int drmlibmajor, drmlibminor, drmdimajor, drmdiminor;
if (DRIGeneration != serverGeneration) { if (DRIGeneration != serverGeneration) {
if ((DRIScreenPrivIndex = AllocateScreenPrivateIndex()) < 0) if ((DRIScreenPrivIndex = AllocateScreenPrivateIndex()) < 0)
@ -153,47 +340,12 @@ DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD)
} }
} }
drmWasAvailable = drmAvailable(); if (!DRIOpenDRMMaster(pScrn, pDRIInfo->SAREASize,
pDRIInfo->busIdString,
/* Check the DRM lib version. pDRIInfo->drmDriverName))
* drmGetLibVersion was not supported in version 1.0, so check for
* symbol first to avoid possible crash or hang.
*/
drmlibmajor = 1;
drmlibminor = 0;
if (xf86LoaderCheckSymbol("drmGetLibVersion")) {
drmlibv = drmGetLibVersion(-1);
if (drmlibv != NULL) {
drmlibmajor = drmlibv->version_major;
drmlibminor = drmlibv->version_minor;
drmFreeVersion(drmlibv);
}
}
/* Check if the libdrm can handle falling back to loading based on name
* if a busid string is passed.
*/
if (drmlibmajor == 1 && drmlibminor >= 2)
openbusid = pDRIInfo->busIdString;
else
openbusid = NULL;
/* Note that drmOpen will try to load the kernel module, if needed. */
fd = drmOpen(pDRIInfo->drmDriverName, openbusid);
if (fd < 0) {
/* failed to open DRM */
pScreen->devPrivates[DRIScreenPrivIndex].ptr = NULL;
DRIDrvMsg(pScreen->myNum, X_INFO,
"[drm] drmOpen failed\n");
return FALSE; return FALSE;
}
if (!drmWasAvailable) { pDRIEntPriv = DRI_ENT_PRIV(pScrn);
/* drmOpen loaded the kernel module, print a message to say so */
DRIDrvMsg(pScreen->myNum, X_INFO,
"[drm] loaded kernel module for \"%s\" driver\n",
pDRIInfo->drmDriverName);
}
pDRIPriv = (DRIScreenPrivPtr) xcalloc(1, sizeof(DRIScreenPrivRec)); pDRIPriv = (DRIScreenPrivPtr) xcalloc(1, sizeof(DRIScreenPrivRec));
if (!pDRIPriv) { if (!pDRIPriv) {
@ -202,7 +354,7 @@ DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD)
} }
pScreen->devPrivates[DRIScreenPrivIndex].ptr = (pointer) pDRIPriv; pScreen->devPrivates[DRIScreenPrivIndex].ptr = (pointer) pDRIPriv;
pDRIPriv->drmFD = fd; pDRIPriv->drmFD = pDRIEntPriv->drmFD;
pDRIPriv->directRenderingSupport = TRUE; pDRIPriv->directRenderingSupport = TRUE;
pDRIPriv->pDriverInfo = pDRIInfo; pDRIPriv->pDriverInfo = pDRIInfo;
pDRIPriv->nrWindows = 0; pDRIPriv->nrWindows = 0;
@ -214,61 +366,15 @@ DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD)
pDRIPriv->grabbedDRILock = FALSE; pDRIPriv->grabbedDRILock = FALSE;
pDRIPriv->drmSIGIOHandlerInstalled = FALSE; pDRIPriv->drmSIGIOHandlerInstalled = FALSE;
if (drmlibmajor == 1 && drmlibminor >= 2) {
drmSetVersion sv;
/* Get the interface version, asking for 1.1. */
sv.drm_di_major = 1;
sv.drm_di_minor = 1;
sv.drm_dd_major = -1;
err = drmSetInterfaceVersion(pDRIPriv->drmFD, &sv);
if (err == 0) {
drmdimajor = sv.drm_di_major;
drmdiminor = sv.drm_di_minor;
} else {
/* failure, so set it to 1.0.0. */
drmdimajor = 1;
drmdiminor = 0;
}
}
else {
/* We can't check the DI DRM interface version, so set it to 1.0.0. */
drmdimajor = 1;
drmdiminor = 0;
}
DRIDrvMsg(pScreen->myNum, X_INFO,
"[drm] DRM interface version %d.%d\n", drmdimajor, drmdiminor);
/* If the interface minor number is 1.1, then we've opened a DRM device
* that already had the busid set through drmOpen.
*/
if (drmdimajor == 1 && drmdiminor >= 1)
err = 0;
else
err = drmSetBusid(pDRIPriv->drmFD, pDRIPriv->pDriverInfo->busIdString);
if (err < 0) {
pDRIPriv->directRenderingSupport = FALSE;
pScreen->devPrivates[DRIScreenPrivIndex].ptr = NULL;
drmClose(pDRIPriv->drmFD);
DRIDrvMsg(pScreen->myNum, X_INFO,
"[drm] drmSetBusid failed (%d, %s), %s\n",
pDRIPriv->drmFD, pDRIPriv->pDriverInfo->busIdString, strerror(-err));
return FALSE;
}
*pDRMFD = pDRIPriv->drmFD; *pDRMFD = pDRIPriv->drmFD;
DRIDrvMsg(pScreen->myNum, X_INFO,
"[drm] created \"%s\" driver at busid \"%s\"\n", if (pDRIEntPriv->sAreaGrabbed || pDRIInfo->allocSarea) {
pDRIPriv->pDriverInfo->drmDriverName,
pDRIPriv->pDriverInfo->busIdString);
if (drmAddMap( pDRIPriv->drmFD, if (drmAddMap( pDRIPriv->drmFD,
0, 0,
pDRIPriv->pDriverInfo->SAREASize, pDRIPriv->pDriverInfo->SAREASize,
DRM_SHM, DRM_SHM,
DRM_CONTAINS_LOCK, 0,
&pDRIPriv->hSAREA) < 0) &pDRIPriv->hSAREA) < 0)
{ {
pDRIPriv->directRenderingSupport = FALSE; pDRIPriv->directRenderingSupport = FALSE;
@ -282,6 +388,7 @@ DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD)
"[drm] added %d byte SAREA at %p\n", "[drm] added %d byte SAREA at %p\n",
pDRIPriv->pDriverInfo->SAREASize, pDRIPriv->hSAREA); pDRIPriv->pDriverInfo->SAREASize, pDRIPriv->hSAREA);
/* Backwards compat. */
if (drmMap( pDRIPriv->drmFD, if (drmMap( pDRIPriv->drmFD,
pDRIPriv->hSAREA, pDRIPriv->hSAREA,
pDRIPriv->pDriverInfo->SAREASize, pDRIPriv->pDriverInfo->SAREASize,
@ -294,9 +401,19 @@ DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD)
"[drm] drmMap failed\n"); "[drm] drmMap failed\n");
return FALSE; return FALSE;
} }
memset(pDRIPriv->pSAREA, 0, pDRIPriv->pDriverInfo->SAREASize);
DRIDrvMsg(pScreen->myNum, X_INFO, "[drm] mapped SAREA %p to %p\n", DRIDrvMsg(pScreen->myNum, X_INFO, "[drm] mapped SAREA %p to %p\n",
pDRIPriv->hSAREA, pDRIPriv->pSAREA); pDRIPriv->hSAREA, pDRIPriv->pSAREA);
memset(pDRIPriv->pSAREA, 0, pDRIPriv->pDriverInfo->SAREASize);
} else {
DRIDrvMsg(pScreen->myNum, X_INFO, "[drm] Using the DRM lock "
"SAREA also for drawables.\n");
pDRIPriv->hSAREA = pDRIEntPriv->hLSAREA;
pDRIPriv->pSAREA = (XF86DRISAREAPtr) pDRIEntPriv->pLSAREA;
pDRIEntPriv->sAreaGrabbed = TRUE;
}
pDRIPriv->hLSAREA = pDRIEntPriv->hLSAREA;
pDRIPriv->pLSAREA = pDRIEntPriv->pLSAREA;
if (drmAddMap( pDRIPriv->drmFD, if (drmAddMap( pDRIPriv->drmFD,
(drm_handle_t)pDRIPriv->pDriverInfo->frameBufferPhysicalAddress, (drm_handle_t)pDRIPriv->pDriverInfo->frameBufferPhysicalAddress,
@ -316,6 +433,9 @@ DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD)
DRIDrvMsg(pScreen->myNum, X_INFO, "[drm] framebuffer handle = %p\n", DRIDrvMsg(pScreen->myNum, X_INFO, "[drm] framebuffer handle = %p\n",
pDRIPriv->hFrameBuffer); pDRIPriv->hFrameBuffer);
if (pDRIEntPriv->resOwner == NULL) {
pDRIEntPriv->resOwner = pScreen;
/* Add tags for reserved contexts */ /* Add tags for reserved contexts */
if ((reserved = drmGetReservedContextList(pDRIPriv->drmFD, if ((reserved = drmGetReservedContextList(pDRIPriv->drmFD,
&reserved_count))) { &reserved_count))) {
@ -333,6 +453,7 @@ DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD)
"[drm] added %d reserved context%s for kernel\n", "[drm] added %d reserved context%s for kernel\n",
reserved_count, reserved_count > 1 ? "s" : ""); reserved_count, reserved_count > 1 ? "s" : "");
} }
}
/* validate max drawable table entry set by driver */ /* validate max drawable table entry set by driver */
if ((pDRIPriv->pDriverInfo->maxDrawableTableEntry <= 0) || if ((pDRIPriv->pDriverInfo->maxDrawableTableEntry <= 0) ||
@ -349,6 +470,11 @@ DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD)
pDRIPriv->pSAREA->drawableTable[i].flags = 0; pDRIPriv->pSAREA->drawableTable[i].flags = 0;
} }
pDRIPriv->pLockRefCount = &pDRIEntPriv->lockRefCount;
pDRIPriv->pLockingContext = &pDRIEntPriv->lockingContext;
pDRIEntPriv->refCount++;
return TRUE; return TRUE;
} }
@ -490,6 +616,9 @@ DRICloseScreen(ScreenPtr pScreen)
DRIInfoPtr pDRIInfo; DRIInfoPtr pDRIInfo;
drm_context_t * reserved; drm_context_t * reserved;
int reserved_count; int reserved_count;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
DRIEntPrivPtr pDRIEntPriv = DRI_ENT_PRIV(pScrn);
Bool closeMaster;
if (pDRIPriv && pDRIPriv->directRenderingSupport) { if (pDRIPriv && pDRIPriv->directRenderingSupport) {
@ -542,6 +671,9 @@ DRICloseScreen(ScreenPtr pScreen)
} }
/* Remove tags for reserved contexts */ /* Remove tags for reserved contexts */
if (pDRIEntPriv->resOwner == pScreen) {
pDRIEntPriv->resOwner = NULL;
if ((reserved = drmGetReservedContextList(pDRIPriv->drmFD, if ((reserved = drmGetReservedContextList(pDRIPriv->drmFD,
&reserved_count))) { &reserved_count))) {
int i; int i;
@ -555,10 +687,14 @@ DRICloseScreen(ScreenPtr pScreen)
"[drm] removed %d reserved context%s for kernel\n", "[drm] removed %d reserved context%s for kernel\n",
reserved_count, reserved_count > 1 ? "s" : ""); reserved_count, reserved_count > 1 ? "s" : "");
} }
}
/* Make sure signals get unblocked etc. */ /* Make sure signals get unblocked etc. */
drmUnlock(pDRIPriv->drmFD, pDRIPriv->myContext); drmUnlock(pDRIPriv->drmFD, pDRIPriv->myContext);
pDRIPriv->lockRefCount = 0; pDRIPriv->pLockRefCount = NULL;
closeMaster = (--pDRIEntPriv->refCount == 0) &&
!pDRIEntPriv->keepFDOpen;
if (closeMaster || pDRIPriv->hSAREA != pDRIEntPriv->hLSAREA) {
DRIDrvMsg(pScreen->myNum, X_INFO, DRIDrvMsg(pScreen->myNum, X_INFO,
"[drm] unmapping %d bytes of SAREA %p at %p\n", "[drm] unmapping %d bytes of SAREA %p at %p\n",
pDRIInfo->SAREASize, pDRIInfo->SAREASize,
@ -572,8 +708,18 @@ DRICloseScreen(ScreenPtr pScreen)
pDRIPriv->hSAREA, pDRIPriv->hSAREA,
pDRIPriv->pSAREA); pDRIPriv->pSAREA);
} }
} else {
pDRIEntPriv->sAreaGrabbed = FALSE;
}
if (closeMaster || (pDRIEntPriv->drmFD != pDRIPriv->drmFD)) {
drmClose(pDRIPriv->drmFD); drmClose(pDRIPriv->drmFD);
if (pDRIEntPriv->drmFD == pDRIPriv->drmFD) {
DRIDrvMsg(pScreen->myNum, X_INFO,
"[drm] Closed DRM master.\n");
pDRIEntPriv->drmFD = -1;
}
}
xfree(pDRIPriv); xfree(pDRIPriv);
pScreen->devPrivates[DRIScreenPrivIndex].ptr = NULL; pScreen->devPrivates[DRIScreenPrivIndex].ptr = NULL;
@ -2001,28 +2147,46 @@ void
DRILock(ScreenPtr pScreen, int flags) DRILock(ScreenPtr pScreen, int flags)
{ {
DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
if(!pDRIPriv) return;
if (!pDRIPriv->lockRefCount) if(!pDRIPriv || !pDRIPriv->pLockRefCount) return;
DRM_LOCK(pDRIPriv->drmFD, pDRIPriv->pSAREA, pDRIPriv->myContext, flags);
pDRIPriv->lockRefCount++; if (!*pDRIPriv->pLockRefCount) {
DRM_LOCK(pDRIPriv->drmFD, pDRIPriv->pLSAREA, pDRIPriv->myContext, flags);
*pDRIPriv->pLockingContext = pDRIPriv->myContext;
} else if (*pDRIPriv->pLockingContext != pDRIPriv->myContext) {
DRIDrvMsg(pScreen->myNum, X_ERROR,
"[DRI] Locking deadlock.\n"
"\tAlready locked with context %d,\n"
"\ttrying to lock with context %d.\n",
pDRIPriv->pLockingContext,
pDRIPriv->myContext);
}
(*pDRIPriv->pLockRefCount)++;
} }
void void
DRIUnlock(ScreenPtr pScreen) DRIUnlock(ScreenPtr pScreen)
{ {
DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
if(!pDRIPriv) return;
if (pDRIPriv->lockRefCount > 0) { if(!pDRIPriv || !pDRIPriv->pLockRefCount) return;
pDRIPriv->lockRefCount--;
if (*pDRIPriv->pLockRefCount > 0) {
if (pDRIPriv->myContext != *pDRIPriv->pLockingContext) {
DRIDrvMsg(pScreen->myNum, X_ERROR,
"[DRI] Unlocking inconsistency:\n"
"\tContext %d trying to unlock lock held by context %d\n",
pDRIPriv->pLockingContext,
pDRIPriv->myContext);
} }
else { (*pDRIPriv->pLockRefCount)--;
ErrorF("DRIUnlock called when not locked\n"); } else {
DRIDrvMsg(pScreen->myNum, X_ERROR,
"DRIUnlock called when not locked.\n");
return; return;
} }
if (!pDRIPriv->lockRefCount) if (! *pDRIPriv->pLockRefCount)
DRM_UNLOCK(pDRIPriv->drmFD, pDRIPriv->pSAREA, pDRIPriv->myContext); DRM_UNLOCK(pDRIPriv->drmFD, pDRIPriv->pLSAREA, pDRIPriv->myContext);
} }
void * void *

View File

@ -107,7 +107,7 @@ typedef struct {
*/ */
#define DRIINFO_MAJOR_VERSION 5 #define DRIINFO_MAJOR_VERSION 5
#define DRIINFO_MINOR_VERSION 1 #define DRIINFO_MINOR_VERSION 2
#define DRIINFO_PATCH_VERSION 0 #define DRIINFO_PATCH_VERSION 0
typedef struct { typedef struct {
@ -176,9 +176,17 @@ typedef struct {
/* New with DRI version 5.1.0 */ /* New with DRI version 5.1.0 */
void (*ClipNotify)(ScreenPtr pScreen, WindowPtr *ppWin, int num); void (*ClipNotify)(ScreenPtr pScreen, WindowPtr *ppWin, int num);
/* New with DRI version 5.2.0 */
Bool allocSarea;
Bool keepFDOpen;
} DRIInfoRec, *DRIInfoPtr; } DRIInfoRec, *DRIInfoPtr;
extern Bool DRIOpenDRMMaster(ScrnInfoPtr pScrn, unsigned long sAreaSize,
const char *busID,
const char *drmDriverName);
extern Bool DRIScreenInit(ScreenPtr pScreen, extern Bool DRIScreenInit(ScreenPtr pScreen,
DRIInfoPtr pDRIInfo, DRIInfoPtr pDRIInfo,
int *pDRMFD); int *pDRMFD);
@ -344,6 +352,14 @@ extern char *DRICreatePCIBusID(pciVideoPtr PciInfo);
extern int drmInstallSIGIOHandler(int fd, void (*f)(int, void *, void *)); extern int drmInstallSIGIOHandler(int fd, void (*f)(int, void *, void *));
extern int drmRemoveSIGIOHandler(int fd); extern int drmRemoveSIGIOHandler(int fd);
extern int DRIMasterFD(ScrnInfoPtr pScrn);
extern void *DRIMasterSareaPointer(ScrnInfoPtr pScrn);
extern drm_handle_t DRIMasterSareaHandle(ScrnInfoPtr pScrn);
#define _DRI_H_ #define _DRI_H_
#endif #endif

View File

@ -73,6 +73,11 @@ struct _DRIContextPrivRec
#define DRI_SCREEN_PRIV_FROM_INDEX(screenIndex) ((DRIScreenPrivPtr) \ #define DRI_SCREEN_PRIV_FROM_INDEX(screenIndex) ((DRIScreenPrivPtr) \
(screenInfo.screens[screenIndex]->devPrivates[DRIScreenPrivIndex].ptr)) (screenInfo.screens[screenIndex]->devPrivates[DRIScreenPrivIndex].ptr))
#define DRI_ENT_PRIV(pScrn) \
((DRIEntPrivIndex < 0) ? \
NULL: \
((DRIEntPrivPtr)(xf86GetEntityPrivate((pScrn)->entityList[0], \
DRIEntPrivIndex)->ptr)))
typedef struct _DRIScreenPrivRec typedef struct _DRIScreenPrivRec
{ {
@ -103,6 +108,25 @@ typedef struct _DRIScreenPrivRec
Bool wrapped; Bool wrapped;
Bool windowsTouched; Bool windowsTouched;
int lockRefCount; int lockRefCount;
drm_handle_t hLSAREA; /* Handle to SAREA containing lock, for mapping */
XF86DRILSAREAPtr pLSAREA; /* Mapped pointer to SAREA containing lock */
int* pLockRefCount;
int* pLockingContext;
} DRIScreenPrivRec, *DRIScreenPrivPtr; } DRIScreenPrivRec, *DRIScreenPrivPtr;
typedef struct _DRIEntPrivRec {
int drmFD;
Bool drmOpened;
Bool sAreaGrabbed;
drm_handle_t hLSAREA;
XF86DRILSAREAPtr pLSAREA;
unsigned long sAreaSize;
int lockRefCount;
int lockingContext;
ScreenPtr resOwner;
Bool keepFDOpen;
int refCount;
} DRIEntPrivRec, *DRIEntPrivPtr;
#endif /* DRI_STRUCT_H */ #endif /* DRI_STRUCT_H */

View File

@ -89,4 +89,9 @@ typedef struct _XF86DRISAREA {
drm_context_t dummy_context; drm_context_t dummy_context;
} XF86DRISAREARec, *XF86DRISAREAPtr; } XF86DRISAREARec, *XF86DRISAREAPtr;
typedef struct _XF86DRILSAREA {
drmLock lock;
drmLock otherLocks[31];
} XF86DRILSAREARec, *XF86DRILSAREAPtr;
#endif #endif