diff options
author | Jon Smirl <[email protected]> | 2004-06-26 17:16:42 +0000 |
---|---|---|
committer | Jon Smirl <[email protected]> | 2004-06-26 17:16:42 +0000 |
commit | c2bffec91a5b6ba72514c875b70dbc96ac97431d (patch) | |
tree | 3c5f963b8cec93217b18cdec35c50f0c45b3339e /src/glx/mini | |
parent | e16f6e3f234391027b300ec2ca8b56fc13aac825 (diff) |
Mesa-solo builds with these changes. There are still more fixups needed to
get individual drivers working again. This converts miniglx to the new
dri interface. Thanks to Erdi Chen for the new interface code.
Diffstat (limited to 'src/glx/mini')
-rw-r--r-- | src/glx/mini/Makefile | 19 | ||||
-rw-r--r-- | src/glx/mini/dri.h | 124 | ||||
-rw-r--r-- | src/glx/mini/dri_util.c | 704 | ||||
-rw-r--r-- | src/glx/mini/dri_util.h | 527 | ||||
-rw-r--r-- | src/glx/mini/drmtest.c | 140 | ||||
-rw-r--r-- | src/glx/mini/miniglx.c | 435 | ||||
-rw-r--r-- | src/glx/mini/miniglxP.h | 19 | ||||
-rw-r--r-- | src/glx/mini/miniglx_events.c | 4 | ||||
-rw-r--r-- | src/glx/mini/xf86drm.c | 1587 | ||||
-rw-r--r-- | src/glx/mini/xf86drm.h | 609 |
10 files changed, 420 insertions, 3748 deletions
diff --git a/src/glx/mini/Makefile b/src/glx/mini/Makefile index 45bf6dd1584..009deb34eaf 100644 --- a/src/glx/mini/Makefile +++ b/src/glx/mini/Makefile @@ -5,13 +5,18 @@ TOP = ../../.. include $(TOP)/configs/current -C_SOURCES = dispatch.c \ - dri_util.c \ - ../../mesa/glapi/glapi.c \ - ../../mesa/glapi/glthread.c \ +DEFINES += -DGLX_DIRECT_RENDERING + +C_SOURCES = \ + $(TOP)/src/mesa/main/dispatch.c \ + $(TOP)/src/mesa/glapi/glapi.c \ + $(TOP)/src/mesa/glapi/glthread.c \ + $(TOP)/src/mesa/drivers/dri/common/glcontextmodes.c \ + $(TOP)/src/mesa/drivers/dri/dri_client/xf86drm.c \ + $(TOP)/src/mesa/drivers/dri/dri_client/xf86drmHash.c \ + $(TOP)/src/mesa/drivers/dri/dri_client/xf86drmRandom.c \ miniglx.c \ - miniglx_events.c \ - xf86drm.c + miniglx_events.c OBJECTS = $(C_SOURCES:.c=.o) @@ -26,6 +31,8 @@ INCLUDE_DIRS = \ -I$(TOP)/src/mesa/transform \ -I$(TOP)/src/mesa/swrast \ -I$(TOP)/src/mesa/swrast_setup \ + -I$(TOP)/src/mesa/drivers/dri/common \ + -I$(TOP)/src/mesa/drivers/dri/dri_client/imports \ -I$(DRM_SOURCE_PATH)/shared diff --git a/src/glx/mini/dri.h b/src/glx/mini/dri.h deleted file mode 100644 index 71f9a1acbf9..00000000000 --- a/src/glx/mini/dri.h +++ /dev/null @@ -1,124 +0,0 @@ -/** - * \file miniglxP.h - * \brief Define replacements for some X data types and define the DRI-related - * data structures. - * - * \note Cut down version of glxclient.h. - * - */ - -#ifndef _dri_h_ -#define _dri_h_ - -#include "driver.h" - -typedef struct __DRIscreenRec __DRIscreen; /**< \copydoc __DRIscreenRec */ -typedef struct __DRIcontextRec __DRIcontext; /**< \copydoc __DRIcontextRec */ -typedef struct __DRIdrawableRec __DRIdrawable; /**< \copydoc __DRIdrawableRec */ - -/** - * \brief Screen dependent methods. - * - * This structure is initialized during the MiniGLXDisplayRec::createScreen - * call. - */ -struct __DRIscreenRec { - /** - * \brief Method to destroy the private DRI screen data. - */ - void (*destroyScreen)(__DRIscreen *screen); - - /** - * \brief Method to create the private DRI context data and initialize the - * context dependent methods. - */ - void *(*createContext)(__DRIscreen *screen, const __GLcontextModes *glVisual, - void *sharedPrivate); - /** - * \brief Method to create the private DRI drawable data and initialize the - * drawable dependent methods. - */ - void *(*createDrawable)(__DRIscreen *screen, - int width, int height, int index, - const __GLcontextModes *glVisual); - - /* - * XXX in the future, implement this: - void *(*createPBuffer)(Display *dpy, int scrn, GLXPbuffer pbuffer, - GLXFBConfig config, __DRIdrawable *pdraw); - */ - - /** - * \brief Opaque pointer to private per screen direct rendering data. - * - * \c NULL if direct rendering is not supported on this screen. Never - * dereferenced in libGL. - */ -}; - -/** - * \brief Context dependent methods. - * - * This structure is initialized during the __DRIscreenRec::createContext call. - */ -struct __DRIcontextRec { - /** - * \brief Method to destroy the private DRI context data. - */ - void (*destroyContext)(__DRIcontext *context); - - /** - * \brief Method to bind a DRI drawable to a DRI graphics context. - * - * \todo XXX in the future, also pass a 'read' GLXDrawable for - * glXMakeCurrentReadSGI() and GLX 1.3's glXMakeContextCurrent(). - */ - GLboolean (*bindContext)(__DRIscreen *screen, __DRIdrawable *drawable, __DRIcontext *context); - - /** - * \brief Method to unbind a DRI drawable to a DRI graphics context. - */ - GLboolean (*unbindContext)(__DRIdrawable *drawable, __DRIcontext *context); - /** - * \brief Opaque pointer to private per context direct rendering data. - * - * NULL if direct rendering is not supported on the display or - * screen used to create this context. Never dereferenced in libGL. - */ -}; - -/** - * \brief Drawable dependent methods. - * - * This structure is initialized during the __DRIscreenRec::createDrawable call. - * - * __DRIscreenRec::createDrawable is not called by libGL at this time. It's - * currently used via the dri_util.c utility code instead. - */ -struct __DRIdrawableRec { - /** - * \brief Method to destroy the private DRI drawable data. - */ - void (*destroyDrawable)(__DRIdrawable *drawable); - - - /** - * \brief Method to swap the front and back buffers. - */ - void (*swapBuffers)(__DRIdrawable *drawable); - - /** - * \brief Opaque pointer to private per drawable direct rendering data. - * - * \c NULL if direct rendering is not supported on the display or - * screen used to create this drawable. Never dereferenced in libGL. - */ -}; - -typedef void *(driCreateScreenFunc)(struct DRIDriverRec *driver, - struct DRIDriverContextRec *driverContext); - -/** This must be implemented in each driver */ -extern driCreateScreenFunc __driCreateScreen; - -#endif /* _dri_h_ */ diff --git a/src/glx/mini/dri_util.c b/src/glx/mini/dri_util.c deleted file mode 100644 index 2c3016f1e27..00000000000 --- a/src/glx/mini/dri_util.c +++ /dev/null @@ -1,704 +0,0 @@ -/** - * \file dri_util.c - * \brief DRI utility functions. - * - * This module acts as glue between GLX and the actual hardware driver. A DRI - * driver doesn't really \e have to use any of this - it's optional. But, some - * useful stuff is done here that otherwise would have to be duplicated in most - * drivers. - * - * Basically, these utility functions take care of some of the dirty details of - * screen initialization, context creation, context binding, DRM setup, etc. - * - * These functions are compiled into each DRI driver so libGL.so knows nothing - * about them. - * - */ - -#include <assert.h> -#include <fcntl.h> -#include <stdarg.h> -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <linux/fb.h> -#include <linux/vt.h> -#include <sys/ioctl.h> -#include <sys/mman.h> -#include <sys/shm.h> - -#include "dri_util.h" - -/** - * \brief Print message to \c stderr if the \c LIBGL_DEBUG environment variable - * is set. - * - * Is called from the drivers. - * - * \param f \e printf like format. - * - * \internal - * This function is a wrapper around vfprintf(). - */ -void -__driUtilMessage(const char *f, ...) -{ - va_list args; - - if (getenv("LIBGL_DEBUG")) { - fprintf(stderr, "libGL error: \n"); - va_start(args, f); - vfprintf(stderr, f, args); - va_end(args); - fprintf(stderr, "\n"); - } -} - - -/*****************************************************************/ -/** \name Visual utility functions */ -/*****************************************************************/ -/*@{*/ - - -/*@}*/ - - -/*****************************************************************/ -/** \name Context (un)binding functions */ -/*****************************************************************/ -/*@{*/ - - -/** - * \brief Unbind context. - * - * \param drawable __DRIdrawable - * \param context __DRIcontext - * \param will_rebind not used. - * - * \return GL_TRUE on success, or GL_FALSE on failure. - * - * \internal - * This function calls __DriverAPIRec::UnbindContext, and then decrements - * __DRIdrawablePrivateRec::refcount which must be non-zero for a successful - * return. - * - * While casting the opaque private pointers associated with the parameters into their - * respective real types it also assures they are not null. - */ -static GLboolean driUnbindContext(__DRIdrawable *drawable, - __DRIcontext *context) -{ - __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *)drawable; - __DRIcontextPrivate *pcp = (__DRIcontextPrivate *)context; - __DRIscreenPrivate *psp; - - if (pdp == NULL || pcp == NULL) - return GL_FALSE; - - if (!(psp = (__DRIscreenPrivate *)pdp->driScreenPriv)) - return GL_FALSE; - - /* Let driver unbind drawable from context */ - (*psp->DriverAPI.UnbindContext)(pcp); - - if (pdp->refcount == 0) - return GL_FALSE; - - --pdp->refcount; - - return GL_TRUE; -} - - -/** - * \brief Unbind context. - * - * \param pDRIScreen __DRIscreen - * \param drawable __DRIdrawable - * \param context __DRIcontext - * - * \internal - * This function and increments __DRIdrawablePrivateRec::refcount and calls - * __DriverAPIRec::MakeCurrent to binds the drawable. - * - * While casting the opaque private pointers into their - * respective real types it also assures they are not null. - */ -static GLboolean driBindContext(__DRIscreen *screen, __DRIdrawable *drawable, - __DRIcontext *context) -{ - __DRIscreenPrivate *psp = (__DRIscreenPrivate *)screen; - __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *)drawable; - __DRIcontextPrivate *pcp = (__DRIcontextPrivate *)context; - - if (psp == NULL) - return GL_FALSE; - - if (pdp == NULL || pcp == NULL) { - (*psp->DriverAPI.MakeCurrent)(0, 0, 0); - return GL_TRUE; - } - - /* Bind the drawable to the context */ - pcp->driDrawablePriv = pdp; - pdp->driContextPriv = pcp; - pdp->refcount++; - - /* Call device-specific MakeCurrent */ - (*psp->DriverAPI.MakeCurrent)(pcp, pdp, pdp); - - return GL_TRUE; -} - -/*@}*/ - - -/*****************************************************************/ -/** \name Drawable handling functions */ -/*****************************************************************/ -/*@{*/ - - -/** - * \brief Update private drawable information. - * - * \param pdp pointer to the private drawable information to update. - * - * \internal - * This function is a no-op. Should never be called but is referenced as an - * external symbol from client drivers. - */ -void __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp) -{ - __DRIscreenPrivate *psp = pdp->driScreenPriv; - - pdp->numClipRects = psp->pSAREA->drawableTable[pdp->index].flags ? 1 : 0; - pdp->lastStamp = *(pdp->pStamp); -} - - -/** - * \brief Swap buffers. - * - * \param pDRIscreen __DRIscreen - * \param drawablePrivate opaque pointer to the per-drawable private info. - * - * \internal - * This function calls __DRIdrawablePrivate::swapBuffers. - * - * Is called directly from glXSwapBuffers(). - */ -static void driSwapBuffers(__DRIdrawable *drawable) -{ - __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *)drawable; - if (pdp) - pdp->swapBuffers(pdp); -} - - -/** - * \brief Destroy per-drawable private information. - * - * \param pDRIscreen __DRIscreen - * \param drawablePrivate opaque pointer to the per-drawable private info. - * - * \internal - * This function calls __DriverAPIRec::DestroyBuffer on \p drawablePrivate, - * frees the clip rects if any, and finally frees \p drawablePrivate itself. - */ -static void driDestroyDrawable(__DRIdrawable *drawable) -{ - __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *)drawable; - __DRIscreenPrivate *psp; - - if (pdp) { - psp = pdp->driScreenPriv; - (*psp->DriverAPI.DestroyBuffer)(pdp); - if (pdp->pClipRects) - free(pdp->pClipRects); - free(pdp); - } -} - - -/** - * \brief Create the per-drawable private driver information. - * - * \param dpy the display handle. - * \param scrn the screen number. - * \param draw the GLX drawable info. - * \param vid visual ID. - * \param pdraw will receive the drawable dependent methods. - * - * - * \returns a opaque pointer to the per-drawable private info on success, or NULL - * on failure. - * - * \internal - * This function allocates and fills a __DRIdrawablePrivateRec structure, - * initializing the invariant window dimensions and clip rects. It obtains the - * visual config, converts it into a __GLcontextModesRec and passes it to - * __DriverAPIRec::CreateBuffer to create a buffer. - */ -static void *driCreateDrawable(__DRIscreen *screen, - int width, int height, int index, - const __GLcontextModes *glVisual) -{ - __DRIscreenPrivate *psp = (__DRIscreenPrivate *)screen; - __DRIdrawablePrivate *pdp; - - if (!psp) - return NULL; - - if (!(pdp = (__DRIdrawablePrivate *)malloc(sizeof(__DRIdrawablePrivate)))) - return NULL; - - pdp->index = index; - pdp->refcount = 0; - pdp->lastStamp = -1; - pdp->numBackClipRects = 0; - pdp->pBackClipRects = NULL; - - /* Initialize with the invariant window dimensions and clip rects here. - */ - pdp->x = 0; - pdp->y = 0; - pdp->w = width; - pdp->h = height; - pdp->numClipRects = 0; - pdp->pClipRects = (drm_clip_rect_t *) malloc(sizeof(drm_clip_rect_t)); - (pdp->pClipRects)[0].x1 = 0; - (pdp->pClipRects)[0].y1 = 0; - (pdp->pClipRects)[0].x2 = width; - (pdp->pClipRects)[0].y2 = height; - - pdp->driScreenPriv = psp; - pdp->driContextPriv = 0; - - pdp->frontBuffer = psp->pFB; - pdp->currentBuffer = pdp->frontBuffer; - pdp->currentPitch = psp->fbStride; - pdp->backBuffer = psp->pFB + psp->fbStride * psp->fbHeight; - - if (!(*psp->DriverAPI.CreateBuffer)(psp, pdp, glVisual, GL_FALSE)) { - free(pdp); - return NULL; - } - - pdp->entry.destroyDrawable = driDestroyDrawable; - pdp->entry.swapBuffers = driSwapBuffers; /* called by glXSwapBuffers() */ - pdp->swapBuffers = psp->DriverAPI.SwapBuffers; - - pdp->pStamp = &(psp->pSAREA->drawableTable[pdp->index].stamp); - return (void *) pdp; -} - -/*@}*/ - - -/*****************************************************************/ -/** \name Context handling functions */ -/*****************************************************************/ -/*@{*/ - - -/** - * \brief Destroy the per-context private information. - * - * \param contextPrivate opaque pointer to the per-drawable private info. - * - * \internal - * This function calls __DriverAPIRec::DestroyContext on \p contextPrivate, calls - * drmDestroyContext(), and finally frees \p contextPrivate. - */ -static void driDestroyContext(__DRIcontext *context) -{ - __DRIcontextPrivate *pcp = (__DRIcontextPrivate *)context; - __DRIscreenPrivate *psp = NULL; - - if (pcp) { - (*pcp->driScreenPriv->DriverAPI.DestroyContext)(pcp); - psp = pcp->driDrawablePriv->driScreenPriv; - if (psp->fd) { - printf(">>> drmDestroyContext(0x%x)\n", (int) pcp->hHWContext); - drmDestroyContext(psp->fd, pcp->hHWContext); - } - free(pcp); - } -} - -/** - * \brief Create the per-drawable private driver information. - * - * \param dpy the display handle. - * \param vis the visual information. - * \param sharedPrivate the shared context dependent methods or NULL if non-existent. - * \param pctx will receive the context dependent methods. - * - * \returns a opaque pointer to the per-context private information on success, or NULL - * on failure. - * - * \internal - * This function allocates and fills a __DRIcontextPrivateRec structure. It - * gets the visual, converts it into a __GLcontextModesRec and passes it - * to __DriverAPIRec::CreateContext to create the context. - */ -static void *driCreateContext(__DRIscreen *screen, - const __GLcontextModes *glVisual, - void *sharedPrivate) -{ - __DRIscreenPrivate *psp = (__DRIscreenPrivate *)screen; - __DRIcontextPrivate *pcp; - __DRIcontextPrivate *pshare = (__DRIcontextPrivate *) sharedPrivate; - void *shareCtx; - - if (!psp) - return NULL; - - if (!(pcp = (__DRIcontextPrivate *)malloc(sizeof(__DRIcontextPrivate)))) - return NULL; - - pcp->driScreenPriv = psp; - pcp->driDrawablePriv = NULL; - - if (psp->fd) { - if (drmCreateContext(psp->fd, &pcp->hHWContext)) { - fprintf(stderr, ">>> drmCreateContext failed\n"); - free(pcp); - return NULL; - } - } - - shareCtx = pshare ? pshare->driverPrivate : NULL; - - if (!(*psp->DriverAPI.CreateContext)(glVisual, pcp, shareCtx)) { - if (psp->fd) - (void) drmDestroyContext(psp->fd, pcp->hHWContext); - free(pcp); - return NULL; - } - - pcp->entry.destroyContext = driDestroyContext; - pcp->entry.bindContext = driBindContext; - pcp->entry.unbindContext = driUnbindContext; - - return pcp; -} - -/*@}*/ - - -/*****************************************************************/ -/** \name Screen handling functions */ -/*****************************************************************/ -/*@{*/ - - -/** - * \brief Destroy the per-screen private information. - * - * \param pDRIscreen __DRIscreen - * - * \internal - * This function calls __DriverAPIRec::DestroyScreen on \p screenPrivate, calls - * drmClose(), and finally frees \p screenPrivate. - */ -static void driDestroyScreen(__DRIscreen *screen) -{ - __DRIscreenPrivate *psp = (__DRIscreenPrivate *)screen; - if (psp) { - if (psp->DriverAPI.DestroyScreen) - (*psp->DriverAPI.DestroyScreen)(psp); - - if (psp->fd) - (void)drmClose(psp->fd); - - free(psp->pDevPriv); - free(psp); - } -} - - -/** - * \brief Create the per-screen private information. - * - * \param dpy the display handle. - * \param scrn the screen number. - * \param psc will receive the screen dependent methods. - * \param numConfigs number of visuals. - * \param config visuals. - * \param driverAPI driver callbacks structure. - * - * \return a pointer to the per-screen private information. - * - * \internal - * This function allocates and fills a __DRIscreenPrivateRec structure. It - * opens the DRM device verifying that the exported version matches the - * expected. It copies the driver callback functions and calls - * __DriverAPIRec::InitDriver. - * - * If a client maps the framebuffer and SAREA regions. - */ -__DRIscreenPrivate * -__driUtilCreateScreen(struct DRIDriverRec *driver, - struct DRIDriverContextRec *driverContext, - const struct __DriverAPIRec *driverAPI) -{ - __DRIscreenPrivate *psp; - - if(!(psp = (__DRIscreenPrivate *)malloc(sizeof(__DRIscreenPrivate)))) - return NULL; - - psp->fd = drmOpen(NULL, driverContext->pciBusID); - if (psp->fd < 0) { - fprintf(stderr, "libGL error: failed to open DRM: %s\n", - strerror(-psp->fd)); - free(psp); - return NULL; - } - - { - drmVersionPtr version = drmGetVersion(psp->fd); - if (version) { - psp->drmMajor = version->version_major; - psp->drmMinor = version->version_minor; - psp->drmPatch = version->version_patchlevel; - drmFreeVersion(version); - } - else { - fprintf(stderr, "libGL error: failed to get drm version: %s\n", - strerror(-psp->fd)); - free(psp); - return NULL; - } - } - - /* install driver's callback functions */ - psp->DriverAPI = *driverAPI; - - /* - * Get device-specific info. pDevPriv will point to a struct - * (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h) - * that has information about the screen size, depth, pitch, - * ancilliary buffers, DRM mmap handles, etc. - */ - psp->fbOrigin = driverContext->shared.fbOrigin; - psp->fbSize = driverContext->shared.fbSize; - psp->fbStride = driverContext->shared.fbStride; - psp->devPrivSize = driverContext->driverClientMsgSize; - psp->pDevPriv = driverContext->driverClientMsg; - psp->fbWidth = driverContext->shared.virtualWidth; - psp->fbHeight = driverContext->shared.virtualHeight; - psp->fbBPP = driverContext->bpp; - - if ((driverContext->FBAddress != NULL) && (driverContext->pSAREA != NULL)) { - /* Already mapped in server */ - psp->pFB = driverContext->FBAddress; - psp->pSAREA = driverContext->pSAREA; - } else { - /* - * Map the framebuffer region. - */ - if (drmMap(psp->fd, driverContext->shared.hFrameBuffer, psp->fbSize, - (drmAddressPtr)&psp->pFB)) { - fprintf(stderr, "libGL error: drmMap of framebuffer failed\n"); - (void)drmClose(psp->fd); - free(psp); - return NULL; - } - - /* - * Map the SAREA region. Further mmap regions may be setup in - * each DRI driver's "createScreen" function. - */ - if (drmMap(psp->fd, driverContext->shared.hSAREA, - driverContext->shared.SAREASize, - (drmAddressPtr)&psp->pSAREA)) { - fprintf(stderr, "libGL error: drmMap of sarea failed\n"); - (void)drmUnmap((drmAddress)psp->pFB, psp->fbSize); - (void)drmClose(psp->fd); - free(psp); - return NULL; - } - -#ifdef _EMBEDDED - mprotect(psp->pSAREA, driverContext->shared.SAREASize, PROT_READ); -#endif - } - - - /* Initialize the screen specific GLX driver */ - if (psp->DriverAPI.InitDriver) { - if (!(*psp->DriverAPI.InitDriver)(psp)) { - fprintf(stderr, "libGL error: InitDriver failed\n"); - free(psp->pDevPriv); - (void)drmClose(psp->fd); - free(psp); - return NULL; - } - } - - psp->entry.destroyScreen = driDestroyScreen; - psp->entry.createContext = driCreateContext; - psp->entry.createDrawable = driCreateDrawable; - - return psp; -} - - - -/** - * \brief Create the per-screen private information. - * - * Version for drivers without a DRM module. - * - * \param dpy the display handle. - * \param scrn the screen number. - * \param numConfigs number of visuals. - * \param config visuals. - * \param driverAPI driver callbacks structure. - * - * \internal - * Same as __driUtilCreateScreen() but without opening the DRM device. - */ -__DRIscreenPrivate * -__driUtilCreateScreenNoDRM(struct DRIDriverRec *driver, - struct DRIDriverContextRec *driverContext, - const struct __DriverAPIRec *driverAPI) -{ - __DRIscreenPrivate *psp; - - psp = (__DRIscreenPrivate *)calloc(1, sizeof(__DRIscreenPrivate)); - if (!psp) - return NULL; - - psp->ddxMajor = 4; - psp->ddxMinor = 0; - psp->ddxPatch = 1; - psp->driMajor = 4; - psp->driMinor = 1; - psp->driPatch = 0; - psp->fd = 0; - - psp->fbOrigin = driverContext->shared.fbOrigin; - psp->fbSize = driverContext->shared.fbSize; - psp->fbStride = driverContext->shared.fbStride; - psp->devPrivSize = driverContext->driverClientMsgSize; - psp->pDevPriv = driverContext->driverClientMsg; - psp->fbWidth = driverContext->shared.virtualWidth; - psp->fbHeight = driverContext->shared.virtualHeight; - psp->fbBPP = driverContext->bpp; - - psp->pFB = driverContext->FBAddress; - - /* install driver's callback functions */ - psp->DriverAPI = *driverAPI; - - if ((driverContext->FBAddress != NULL) && (driverContext->pSAREA != NULL)) { - /* Already mapped in server */ - psp->pFB = driverContext->FBAddress; - psp->pSAREA = driverContext->pSAREA; - } else { - int id; - psp->fd = open("/dev/mem", O_RDWR, 0); - /* - * Map the framebuffer region. - */ - if (drmMap(psp->fd, driverContext->shared.hFrameBuffer, psp->fbSize, - (drmAddressPtr)&psp->pFB)) { - fprintf(stderr, "libGL error: drmMap of framebuffer failed\n"); - (void)drmClose(psp->fd); - free(psp); - return NULL; - } - driverContext->FBAddress = psp->pFB; - - /* - * Map the SAREA region. Non-DRM drivers use a shmem SAREA - */ - id = shmget(driverContext->shared.hSAREA, driverContext->shared.SAREASize, 0); - driverContext->pSAREA = shmat(id, NULL, 0); - if (!driverContext->pSAREA) { - fprintf(stderr, "libGL error: shmget of sarea failed\n"); - (void)drmUnmap((drmAddress)psp->pFB, psp->fbSize); - (void)drmClose(psp->fd); - free(psp); - return NULL; - } - - close(psp->fd); - psp->fd = 0; - } - - /* Initialize the screen specific GLX driver */ - if (psp->DriverAPI.InitDriver) { - if (!(*psp->DriverAPI.InitDriver)(psp)) { - fprintf(stderr, "libGL error: InitDriver failed\n"); - free(psp->pDevPriv); - free(psp); - return NULL; - } - } - - psp->entry.destroyScreen = driDestroyScreen; - psp->entry.createContext = driCreateContext; - psp->entry.createDrawable = driCreateDrawable; - - return psp; -} - -/** - * Calculate amount of swap interval used between GLX buffer swaps. - * - * The usage value, on the range [0,max], is the fraction of total swap - * interval time used between GLX buffer swaps is calculated. - * - * \f$p = t_d / (i * t_r)\f$ - * - * Where \f$t_d\$f is the time since the last GLX buffer swap, \f$i\f$ is the - * swap interval (as set by \c glXSwapIntervalSGI), and \f$t_r\f$ time - * required for a single vertical refresh period (as returned by \c - * glXGetMscRateOML). - * - * See the documentation for the GLX_MESA_swap_frame_usage extension for more - * details. - * - * \param dPriv Pointer to the private drawable structure. - * \return If less than a single swap interval time period was required - * between GLX buffer swaps, a number greater than 0 and less than - * 1.0 is returned. If exactly one swap interval time period is - * required, 1.0 is returned, and if more than one is required then - * a number greater than 1.0 will be returned. - * - * \sa glXSwapIntervalSGI(), glXGetMscRateOML(). - */ -float -driCalculateSwapUsage( __DRIdrawablePrivate *dPriv, int64_t last_swap_ust, - int64_t current_ust ) -{ - return 0.0f; -} - -/** - * Compare the current GLX API version with a driver supplied required version. - * - * The minimum required version is compared with the API version exported by - * the \c __glXGetInternalVersion function (in libGL.so). - * - * \param required_version Minimum required internal GLX API version. - * \return A tri-value return, as from strcmp is returned. A value less - * than, equal to, or greater than zero will be returned if the - * internal GLX API version is less than, equal to, or greater - * than \c required_version. - * - * \sa __glXGetInternalVersion(). - */ -int driCompareGLXAPIVersion( GLuint required_version ) -{ - return 0; -} - -/*@}*/ diff --git a/src/glx/mini/dri_util.h b/src/glx/mini/dri_util.h deleted file mode 100644 index 638bfa95243..00000000000 --- a/src/glx/mini/dri_util.h +++ /dev/null @@ -1,527 +0,0 @@ -/** - * \file dri_util.h - * \brief DRI utility functions definitions. - * - * This module acts as glue between GLX and the actual hardware driver. A DRI - * driver doesn't really \e have to use any of this - it's optional. But, some - * useful stuff is done here that otherwise would have to be duplicated in most - * drivers. - * - * Basically, these utility functions take care of some of the dirty details of - * screen initialization, context creation, context binding, DRM setup, etc. - * - * These functions are compiled into each DRI driver so libGL.so knows nothing - * about them. - * - * Look for more comments in the dri_util.c file. - * - * \author Kevin E. Martin <[email protected]> - * \author Brian Paul <[email protected]> - */ - -/* - * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * 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, sub license, 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 (including the - * next paragraph) 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 NON-INFRINGEMENT. - * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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. - */ - - -#ifndef _DRI_UTIL_H_ -#define _DRI_UTIL_H_ - -#include <inttypes.h> -#include "dri.h" /* public entry points */ -#include "xf86drm.h" -#include "drm.h" -#include "drm_sarea.h" - -#define _SOLO - -typedef unsigned long CARD32; -typedef int (* PFNGLXGETUSTPROC) ( int64_t * ust ); - -typedef struct __DRIdisplayPrivateRec __DRIdisplayPrivate; /**< \brief Alias for __DRIdisplayPrivateRec */ -typedef struct __DRIscreenPrivateRec __DRIscreenPrivate; /**< \brief Alias for __DRIscreenPrivateRec */ -typedef struct __DRIcontextPrivateRec __DRIcontextPrivate; /**< \brief Alias for __DRIcontextPrivateRec */ -typedef struct __DRIdrawablePrivateRec __DRIdrawablePrivate; /**< \brief Alias for __DRIdrawablePrivateRec */ -typedef struct __DRIswapInfoRec __DRIswapInfo; /**< \brief Alias for __DRIswapInfoPrivateRec */ - - -/** - * Used by DRI_VALIDATE_DRAWABLE_INFO - */ -#define DRI_VALIDATE_DRAWABLE_INFO_ONCE(pDrawPriv) \ - do { \ - if (*(pDrawPriv->pStamp) != pDrawPriv->lastStamp) { \ - __driUtilUpdateDrawableInfo(pDrawPriv); \ - } \ - } while (0) - - -/** - * \brief Utility macro to validate the drawable information. - * - * See __DRIdrawablePrivateRec::pStamp and __DRIdrawablePrivateRec::lastStamp. - */ -#define DRI_VALIDATE_DRAWABLE_INFO(psp, pdp) \ -do { \ - DRI_VALIDATE_DRAWABLE_INFO_ONCE(pdp); \ -} while (0) - - -/** - * Driver callback functions. - * - * Each DRI driver must have one of these structures with all the pointers set - * to appropriate functions within the driver. - * - * When glXCreateContext() is called, for example, it'll call a helper function - * dri_util.c which in turn will jump through the \a CreateContext pointer in - * this structure. - */ -struct __DriverAPIRec { - /** - * Driver initialization callback - */ - GLboolean (*InitDriver)(__DRIscreenPrivate *driScrnPriv); - - /** - * Screen destruction callback - */ - void (*DestroyScreen)(__DRIscreenPrivate *driScrnPriv); - - /** - * Context creation callback - */ - GLboolean (*CreateContext)(const __GLcontextModes *glVis, - __DRIcontextPrivate *driContextPriv, - void *sharedContextPrivate); - - /** - * Context destruction callback - */ - void (*DestroyContext)(__DRIcontextPrivate *driContextPriv); - - /** - * Buffer (drawable) creation callback - */ - GLboolean (*CreateBuffer)(__DRIscreenPrivate *driScrnPriv, - __DRIdrawablePrivate *driDrawPriv, - const __GLcontextModes *glVis, - GLboolean pixmapBuffer); - - /** - * Buffer (drawable) destruction callback - */ - void (*DestroyBuffer)(__DRIdrawablePrivate *driDrawPriv); - - /** - * Buffer swapping callback - */ - void (*SwapBuffers)(__DRIdrawablePrivate *driDrawPriv); - - /** - * Context activation callback - */ - GLboolean (*MakeCurrent)(__DRIcontextPrivate *driContextPriv, - __DRIdrawablePrivate *driDrawPriv, - __DRIdrawablePrivate *driReadPriv); - - /** - * Context unbinding callback - */ - GLboolean (*UnbindContext)(__DRIcontextPrivate *driContextPriv); - - /** - * Full screen mode opening callback. - * - * \deprecated Full screen functionality is no longer used by DRI. - * Drivers should simply install a function returning - * \c GL_TRUE for backwards compatability. - */ - GLboolean (*OpenFullScreen)(__DRIcontextPrivate *driContextPriv); - - /** - * Full screen mode closing callback. - * - * \deprecated Full screen functionality is no longer used by DRI. - * Drivers should simply install a function returning - * \c GL_TRUE for backwards compatability. - */ - GLboolean (*CloseFullScreen)(__DRIcontextPrivate *driContextPriv); - - /* Retrieves statistics about buffer swap operations. Required if - * GLX_OML_sync_control or GLX_MESA_swap_frame_usage is supported. - */ - int (*GetSwapInfo)( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo ); - - - /* Required if GLX_SGI_video_sync or GLX_OML_sync_control is - * supported. - */ - int (*GetMSC)( __DRIscreenPrivate * priv, int64_t * count ); - - /** - * These are required if GLX_OML_sync_control is supported. - */ - /*@{*/ - int (*WaitForMSC)( __DRIdrawablePrivate *priv, int64_t target_msc, - int64_t divisor, int64_t remainder, - int64_t * msc ); - int (*WaitForSBC)( __DRIdrawablePrivate *priv, int64_t target_sbc, - int64_t * msc, int64_t * sbc ); - - int64_t (*SwapBuffersMSC)( __DRIdrawablePrivate *priv, int64_t target_msc, - int64_t divisor, int64_t remainder ); - /*@}*/ -}; - - -struct __DRIswapInfoRec { - /** - * Number of swapBuffers operations that have been *completed*. - */ - uint64_t swap_count; - - /* - * Unadjusted system time of the last buffer swap. This is the time - * when the swap completed, not the time when swapBuffers was called. - */ - int64_t swap_ust; - - /* - * Number of swap operations that occurred after the swap deadline. That - * is if a swap happens more than swap_interval frames after the previous - * swap, it has missed its deadline. If swap_interval is 0, then the - * swap deadline is 1 frame after the previous swap. - */ - uint64_t swap_missed_count; - - /* - * Amount of time used by the last swap that missed its deadline. This - * is calculated as (__glXGetUST() - swap_ust) / (swap_interval * - * time_for_single_vrefresh)). If the actual value of swap_interval is - * 0, then 1 is used instead. If swap_missed_count is non-zero, this - * should be greater-than 1.0. - */ - float swap_missed_usage; -}; - - -/** - * \brief Per-drawable private DRI driver information. - * - */ -struct __DRIdrawablePrivateRec { - - /** - * \brief Public entry points - */ - __DRIdrawable entry; - - /** - * \brief Kernel drawable handle - * - * \note Not currently used. - */ - drmDrawable hHWDrawable; - - /** - * \brief Driver's private drawable information. - * - * This structure is opaque. - */ - void *driverPrivate; - - /** - * \brief Reference count for number of context's currently bound to this - * drawable. - * - * Once it reaches zero, the drawable can be destroyed. - * - * \note This behavior will change with GLX 1.3. - */ - int refcount; - - /** - * \brief Index of this drawable information in the SAREA. - */ - unsigned int index; - - /** - * \brief Pointer to the "drawable has changed ID" stamp in the SAREA. - */ - unsigned int *pStamp; - - /** - * \brief Last value of the stamp. - * - * If this differs from the value stored at - * __DRIdrawablePrivateRec::pStamp, then the drawable information has been - * modified by the X server, and the drawable information (below) should be - * retrieved from the X server. - */ - unsigned int lastStamp; - - /** - * \name Drawable - * Drawable information used in software fallbacks. - */ - /*@{*/ - int x; - int y; - int w; - int h; - int numClipRects; - drm_clip_rect_t *pClipRects; - /*@}*/ - - /** - * \name Back and depthbuffer - * Information about the back and depthbuffer where different from above. - */ - /*@{*/ - int backX; - int backY; - int backClipRectType; - int numBackClipRects; - drm_clip_rect_t *pBackClipRects; - /*@}*/ - - /** - * \brief Pointer to context to which this drawable is currently bound. - */ - __DRIcontextPrivate *driContextPriv; - - /** - * \brief Pointer to screen on which this drawable was created. - */ - __DRIscreenPrivate *driScreenPriv; - - int cpp; - void *frontBuffer; - void *backBuffer; - void *currentBuffer; - int currentPitch; - - int depthCpp; - void *depthBuffer; - int depthPitch; - - /** - * \brief Called via glXSwapBuffers(). - */ - void (*swapBuffers)( __DRIdrawablePrivate *dPriv ); -}; - -/** - * \brief Per-context private driver information. - */ -struct __DRIcontextPrivateRec { - /** - * \brief Public entry points - */ - __DRIcontext entry; - - /** - * \brief Kernel context handle used to access the device lock. - */ - drmContext hHWContext; - - /** - * \brief Device driver's private context data. This structure is opaque. - */ - void *driverPrivate; - - /** - * \brief Pointer to drawable currently bound to this context. - */ - __DRIdrawablePrivate *driDrawablePriv; - - /** - * \brief Pointer to screen on which this context was created. - */ - __DRIscreenPrivate *driScreenPriv; -}; - -/** - * \brief Per-screen private driver information. - */ -struct __DRIscreenPrivateRec { - - /** - * \brief Public entry points - */ - __DRIscreen entry; - - /** - * \brief Callback functions into the hardware-specific DRI driver code. - */ - struct __DriverAPIRec DriverAPI; - - /** - * \name DDX version - * DDX / 2D driver version information. - */ - /*@{*/ - int ddxMajor; - int ddxMinor; - int ddxPatch; - /*@}*/ - - /** - * \name DRI version - * DRI X extension version information. - */ - /*@{*/ - int driMajor; - int driMinor; - int driPatch; - /*@}*/ - - /** - * \name DRM version - * DRM (kernel module) version information. - */ - /*@{*/ - int drmMajor; - int drmMinor; - int drmPatch; - /*@}*/ - - /** - * \brief ID used when the client sets the drawable lock. - * - * The X server uses this value to detect if the client has died while - * holding the drawable lock. - */ - int drawLockID; - - /** - * \brief File descriptor returned when the kernel device driver is opened. - * - * Used to: - * - authenticate client to kernel - * - map the frame buffer, SAREA, etc. - * - close the kernel device driver - */ - int fd; - - /** - * \brief SAREA pointer - * - * Used to access: - * - the device lock - * - the device-independent per-drawable and per-context(?) information - */ - drm_sarea_t *pSAREA; - - /** - * \name Direct frame buffer access information - * Used for software fallbacks. - */ - /*@{*/ - unsigned char *pFB; - int fbSize; - int fbOrigin; - int fbStride; - int fbWidth; - int fbHeight; - int fbBPP; - /*@}*/ - - /** - * \name Device-dependent private information (stored in the SAREA). - * - * This data is accessed by the client driver only. - */ - /*@{*/ - void *pDevPriv; - int devPrivSize; - /*@}*/ - - /** - * \brief Dummy context to which drawables are bound when not bound to any - * other context. - * - * A dummy hHWContext is created for this context, and is used by the GL - * core when a hardware lock is required but the drawable is not currently - * bound (e.g., potentially during a SwapBuffers request). The dummy - * context is created when the first "real" context is created on this - * screen. - */ - __DRIcontextPrivate dummyContextPriv; - - /** - * \brief Hash table to hold the drawable information for this screen. - */ - void *drawHash; - - /** - * \brief Device-dependent private information (not stored in the SAREA). - * - * This pointer is never touched by the DRI layer. - */ - void *private; - - /** - * \brief Full screen mode. - * - * If we're in full screen mode (via DRIOpenFullScreen()), this points to - * the drawable that was bound. Otherwise, this is NULL. - */ - __DRIdrawablePrivate *fullscreen; - - - /** - * \brief Screen number for when multiple screens are supported - */ - int myNum; -}; - -extern void -__driUtilMessage(const char *f, ...); - - -extern void -__driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp); - - -extern __DRIscreenPrivate * -__driUtilCreateScreen(struct DRIDriverRec *driver, - struct DRIDriverContextRec *driverContext, - const struct __DriverAPIRec *driverAPI); - -__DRIscreenPrivate * -__driUtilCreateScreenNoDRM(struct DRIDriverRec *driver, - struct DRIDriverContextRec *driverContext, - const struct __DriverAPIRec *driverAPI); - -extern float -driCalculateSwapUsage( __DRIdrawablePrivate *dPriv, - int64_t last_swap_ust, int64_t current_ust ); - -/* Test the version of the internal GLX API. Returns a value like strcmp. */ -extern int -driCompareGLXAPIVersion( GLuint required_version ); - -#endif /* _DRI_UTIL_H_ */ diff --git a/src/glx/mini/drmtest.c b/src/glx/mini/drmtest.c deleted file mode 100644 index f9cad3994e0..00000000000 --- a/src/glx/mini/drmtest.c +++ /dev/null @@ -1,140 +0,0 @@ -#include <assert.h> -#include <unistd.h> -#include <stdio.h> -#include <string.h> -#include "xf86drm.h" - -char *pciBusID = "PCI:1:0:0"; -#define DRM_PAGE_SIZE 4096 -void *pSAREA; - - -static int client( void ) -{ - int fd, ret, err; - drmContext clientContext; - - fprintf(stderr, "Opening client drm\n"); - - fd = drmOpen(NULL,pciBusID); - if (fd < 0) { - fprintf(stderr, "failed to open DRM: %s\n", strerror(-fd)); - return 1; - } - - - fprintf(stderr, "Create server context\n"); - if ((err = drmCreateContext(fd, &clientContext)) != 0) { - fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err); - return 0; - } - - - fprintf(stderr, "DRM_LOCK( %d %p %d )\n", fd, pSAREA, clientContext); - DRM_LOCK(fd, pSAREA, clientContext, 0); - fprintf(stderr, "locked\n"); - DRM_UNLOCK(fd, pSAREA, clientContext); - fprintf(stderr, "DRM_UNLOCK finished\n"); - - - fprintf(stderr, "Closing client drm: %d\n", fd); - ret = drmClose(fd); - fprintf(stderr, "done %d\n", ret); - - return ret; -} - -int main( int argc, char *argv[] ) -{ - char *drmModuleName = "radeon"; - int drmFD; - int err; - int SAREASize; - drmHandle hSAREA; - drmContext serverContext; - - /* Note that drmOpen will try to load the kernel module, if needed. */ - drmFD = drmOpen(drmModuleName, NULL ); - if (drmFD < 0) { - /* failed to open DRM */ - fprintf(stderr, "[drm] drmOpen failed\n"); - return 0; - } - - - if ((err = drmSetBusid(drmFD, pciBusID)) < 0) { - drmClose(drmFD); - fprintf(stderr, "[drm] drmSetBusid failed (%d, %s), %s\n", - drmFD, pciBusID, strerror(-err)); - return 0; - } - - - SAREASize = DRM_PAGE_SIZE; - - if (drmAddMap( drmFD, - 0, - SAREASize, - DRM_SHM, - DRM_CONTAINS_LOCK, - &hSAREA) < 0) - { - drmClose(drmFD); - fprintf(stderr, "[drm] drmAddMap failed\n"); - return 0; - } - - fprintf(stderr, "[drm] added %d byte SAREA at 0x%08lx\n", - SAREASize, hSAREA); - - if (drmMap( drmFD, - hSAREA, - SAREASize, - (drmAddressPtr)(&pSAREA)) < 0) - { - drmClose(drmFD); - fprintf(stderr, "[drm] drmMap failed\n"); - return 0; - } - - memset(pSAREA, 0, SAREASize); - fprintf(stderr, "[drm] mapped SAREA 0x%08lx to %p, size %d\n", - hSAREA, pSAREA, SAREASize); - - fprintf(stderr, "Create server context\n"); - if ((err = drmCreateContext(drmFD, &serverContext)) != 0) { - fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err); - return 0; - } - - - fprintf(stderr, "DRM_LOCK( %d %p %d )\n", drmFD, pSAREA, serverContext); - DRM_LOCK(drmFD, pSAREA, serverContext, 0); - fprintf(stderr, "locked\n"); - DRM_UNLOCK(drmFD, pSAREA, serverContext); - fprintf(stderr, "DRM_UNLOCK finished\n"); - - - client(); - - - fprintf(stderr, "DRM_LOCK( %d %p %d )\n", drmFD, pSAREA, serverContext); - DRM_LOCK(drmFD, pSAREA, serverContext, 0); - fprintf(stderr, "locked\n"); - DRM_UNLOCK(drmFD, pSAREA, serverContext); - fprintf(stderr, "DRM_UNLOCK finished\n"); - - - drmUnmap(pSAREA, SAREASize); - fprintf(stderr, "[drm] unmapped SAREA 0x%08lx from %p, size %d\n", - hSAREA, pSAREA, SAREASize); - pSAREA = 0; - - fprintf(stderr, "%s: Closing DRM fd\n", __FUNCTION__); - (void)drmClose(drmFD); - - return 0; -} - - - diff --git a/src/glx/mini/miniglx.c b/src/glx/mini/miniglx.c index 7e78a020ddb..31bd9cc034e 100644 --- a/src/glx/mini/miniglx.c +++ b/src/glx/mini/miniglx.c @@ -108,10 +108,45 @@ #include <linux/vt.h> #include "miniglxP.h" -#include "dri.h" +#include "dri_util.h" +#include "imports.h" +#include "glcontextmodes.h" #include "glapi.h" -#include "xf86drm.h" + + +extern GLboolean __glXCreateContextWithConfig(__DRInativeDisplay *dpy, + int screen, int fbconfigID, void *contextID, + drm_context_t *hHWContext); + +extern GLboolean __glXGetDrawableInfo(__DRInativeDisplay *dpy, int scrn, + __DRIid draw, unsigned int * index, unsigned int * stamp, + int * x, int * y, int * width, int * height, + int * numClipRects, drm_clip_rect_t ** pClipRects, + int * backX, int * backY, + int * numBackClipRects, drm_clip_rect_t ** pBackClipRects); + + +/** Wrapper around either malloc() */ +void * +_mesa_malloc(size_t bytes) +{ + return malloc(bytes); +} + +/** Wrapper around either calloc() */ +void * +_mesa_calloc(size_t bytes) +{ + return calloc(1, bytes); +} + +/** Wrapper around either free() */ +void +_mesa_free(void *ptr) +{ + free(ptr); +} /** @@ -664,10 +699,10 @@ CloseFBDev( Display *dpy ) * Returns the MiniGLXDisplayRec::driScreen attribute. */ __DRIscreen * -__glXFindDRIScreen(Display *dpy, int scrn) +__glXFindDRIScreen(__DRInativeDisplay *dpy, int scrn) { (void) scrn; - return dpy->driScreen; + return &((Display*)dpy)->driScreen; } /** @@ -681,9 +716,10 @@ __glXFindDRIScreen(Display *dpy, int scrn) * the MiniGLXDisplayRec::TheWindow attribute. */ Bool -__glXWindowExists(Display *dpy, GLXDrawable draw) +__glXWindowExists(__DRInativeDisplay *dpy, GLXDrawable draw) { - if (dpy->TheWindow == draw) + Display* display = (Display*)dpy; + if (display->TheWindow == draw) return True; else return False; @@ -875,6 +911,24 @@ static int __read_config_file( Display *dpy ) static int InitDriver( Display *dpy ) { + char * str; + char * srvLibname = NULL; + + srvLibname = strdup(dpy->clientDriverName); + if (!srvLibname) { + goto failed; + } + + /* + * Construct server library name. Assume clientDriverName ends + * with dri.so. Replace dri.so with srv.so. + */ + str = strstr(srvLibname, "dri.so"); + if (!str) { + goto failed; + } + strcpy(str, "srv.so"); + /* * Begin DRI setup. * We're kind of combining the per-display and per-screen information @@ -884,32 +938,51 @@ static int InitDriver( Display *dpy ) if (!dpy->dlHandle) { fprintf(stderr, "Unable to open %s: %s\n", dpy->clientDriverName, dlerror()); - return GL_FALSE; + goto failed; + } + + dpy->dlHandleSrv = dlopen(srvLibname, RTLD_NOW | RTLD_GLOBAL); + if (!dpy->dlHandleSrv) { + fprintf(stderr, "Unable to open %s: %s\n", dpy->clientDriverName, + dlerror()); + goto failed; } /* Pull in Mini GLX specific hooks: */ - dpy->driver = (struct DRIDriverRec *) dlsym(dpy->dlHandle, + dpy->driver = (struct DRIDriverRec *) dlsym(dpy->dlHandleSrv, "__driDriver"); if (!dpy->driver) { fprintf(stderr, "Couldn't find __driDriver in %s\n", dpy->clientDriverName); - dlclose(dpy->dlHandle); - return GL_FALSE; + goto failed; } /* Pull in standard DRI client-side driver hooks: */ - dpy->createScreen = (driCreateScreenFunc*) dlsym(dpy->dlHandle, - "__driCreateScreen"); - if (!dpy->createScreen) { + dpy->createNewScreen = (PFNCREATENEWSCREENFUNC) + dlsym(dpy->dlHandle, "__driCreateNewScreen"); + if (!dpy->createNewScreen) { fprintf(stderr, "Couldn't find __driCreateScreen in %s\n", dpy->clientDriverName); - dlclose(dpy->dlHandle); - return GL_FALSE; + goto failed; } return GL_TRUE; + +failed: + if (srvLibname) { + free(srvLibname); + } + if (dpy->dlHandleSrv) { + dlclose(dpy->dlHandleSrv); + dpy->dlHandleSrv = 0; + } + if (dpy->dlHandle) { + dlclose(dpy->dlHandle); + dpy->dlHandle = 0; + } + return GL_FALSE; } @@ -1014,6 +1087,199 @@ __miniglx_StartServer( const char *display_name ) } +static void * +CallCreateNewScreen(Display *dpy, int scrn, __DRIscreen *psc) +{ + int directCapable; + void *psp = NULL; + drm_handle_t hSAREA; + drmAddress pSAREA; + const char *BusID; + __GLcontextModes *modes; + __GLcontextModes *temp; + int i; + __DRIversion ddx_version; + __DRIversion dri_version; + __DRIversion drm_version; + __DRIframebuffer framebuffer; + int fd = -1; + int status; + const char * err_msg; + const char * err_extra; + drmVersionPtr version; + drm_handle_t hFB; + int junk; + + + /* Create the linked list of context modes, and populate it with the + * GLX visual information passed in by libGL. + */ + + modes = _gl_context_modes_create( dpy->numModes, sizeof(__GLcontextModes) ); + if ( modes == NULL ) { + return NULL; + } + + temp = modes; + for ( i = 0 ; i < dpy->numModes ; i++ ) { + __GLcontextModes * next; + assert( temp != NULL ); + next = temp->next; + *temp = dpy->modes[i]; + temp->next = next; + temp->screen = scrn; + + temp = temp->next; + } + + err_msg = "XF86DRIOpenConnection"; + err_extra = NULL; + + hSAREA = dpy->driverContext.shared.hSAREA; + BusID = dpy->driverContext.pciBusID; + + fd = drmOpen(NULL, BusID); + + err_msg = "open DRM"; + err_extra = strerror( -fd ); + + if (fd < 0) goto done; + + drm_magic_t magic; + + err_msg = "drmGetMagic"; + err_extra = NULL; + + if (drmGetMagic(fd, &magic)) goto done; + + version = drmGetVersion(fd); + if (version) { + drm_version.major = version->version_major; + drm_version.minor = version->version_minor; + drm_version.patch = version->version_patchlevel; + drmFreeVersion(version); + } + else { + drm_version.major = -1; + drm_version.minor = -1; + drm_version.patch = -1; + } + + /* + * Get device name (like "tdfx") and the ddx version numbers. + * We'll check the version in each DRI driver's "createScreen" + * function. + */ + err_msg = "XF86DRIGetClientDriverName"; + ddx_version.major = 4; + ddx_version.minor = 0; + ddx_version.patch = 0; + + /* + * Get the DRI X extension version. + */ + err_msg = "XF86DRIQueryVersion"; + dri_version.major = 4; + dri_version.minor = 0; + dri_version.patch = 0; + + /* + * Get device-specific info. pDevPriv will point to a struct + * (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h) + * that has information about the screen size, depth, pitch, + * ancilliary buffers, DRM mmap handles, etc. + */ + err_msg = "XF86DRIGetDeviceInfo"; + hFB = dpy->driverContext.shared.hFrameBuffer; + framebuffer.size = dpy->driverContext.shared.fbSize; + framebuffer.stride = dpy->driverContext.shared.fbStride; + framebuffer.dev_priv_size = dpy->driverContext.driverClientMsgSize; + framebuffer.dev_priv = dpy->driverContext.driverClientMsg; + framebuffer.width = dpy->driverContext.shared.virtualWidth; + framebuffer.height = dpy->driverContext.shared.virtualHeight; + + /* + * Map the framebuffer region. + */ + status = drmMap(fd, hFB, framebuffer.size, + (drmAddressPtr)&framebuffer.base); + + err_msg = "drmMap of framebuffer"; + err_extra = strerror( -status ); + + if ( status != 0 ) goto done; + + /* + * Map the SAREA region. Further mmap regions may be setup in + * each DRI driver's "createScreen" function. + */ + status = drmMap(fd, hSAREA, SAREA_MAX, &pSAREA); + + err_msg = "drmMap of sarea"; + err_extra = strerror( -status ); + + if ( status == 0 ) { + PFNGLXGETINTERNALVERSIONPROC get_ver; + + get_ver = (PFNGLXGETINTERNALVERSIONPROC) + glXGetProcAddress( (const GLubyte *) "__glXGetInternalVersion" ); + + err_msg = "InitDriver"; + err_extra = NULL; + psp = dpy->createNewScreen(dpy, scrn, psc, modes, + & ddx_version, + & dri_version, + & drm_version, + & framebuffer, + pSAREA, + fd, + (get_ver != NULL) ? (*get_ver)() : 20040602, + (__GLcontextModes **) &dpy->driver_modes); + if (dpy->driver_modes == NULL) { + dpy->driver_modes = modes; + } + else { + _gl_context_modes_destroy(modes); + modes = NULL; + } + } + +done: + if ( psp == NULL ) { + if ( pSAREA != MAP_FAILED ) { + (void)drmUnmap(pSAREA, SAREA_MAX); + } + + if ( framebuffer.base != MAP_FAILED ) { + (void)drmUnmap((drmAddress)framebuffer.base, framebuffer.size); + } + + if ( framebuffer.dev_priv != NULL ) { + free(framebuffer.dev_priv); + } + + if ( fd >= 0 ) { + (void)drmClose(fd); + } + + if ( modes != NULL ) { + _gl_context_modes_destroy( modes ); + } + + if ( err_extra != NULL ) { + fprintf(stderr, "libGL error: %s failed (%s)\n", err_msg, + err_extra); + } + else { + fprintf(stderr, "libGL error: %s failed\n", err_msg ); + } + + fprintf(stderr, "libGL error: reverting to (slow) indirect rendering\n"); + } + + return psp; +} + /** * \brief Initialize the graphics system. * @@ -1083,9 +1349,8 @@ XOpenDisplay( const char *display_name ) * * Need to shut down DRM and free DRI data in XDestroyWindow(), too. */ - dpy->driScreen = (*dpy->createScreen)(dpy->driver, - &dpy->driverContext); - if (!dpy->driScreen) { + dpy->driScreen.private = CallCreateNewScreen(dpy, 0, &dpy->driScreen); + if (!dpy->driScreen.private) { fprintf(stderr, "%s: __driCreateScreen failed\n", __FUNCTION__); dlclose(dpy->dlHandle); free(dpy); @@ -1124,7 +1389,7 @@ XCloseDisplay( Display *dpy ) /* As this is done in XOpenDisplay, need to undo it here: */ - (*dpy->driScreen->destroyScreen)(dpy->driScreen); + dpy->driScreen.destroyScreen(dpy, 0, dpy->driScreen.private); __miniglx_close_connections( dpy ); @@ -1187,6 +1452,8 @@ XCreateWindow( Display *dpy, Window parent, int x, int y, Visual *visual, unsigned long valuemask, XSetWindowAttributes *attributes ) { + const int empty_attribute_list[1] = { None }; + Window win; /* ignored */ @@ -1252,11 +1519,10 @@ XCreateWindow( Display *dpy, Window parent, int x, int y, win->curBottom = win->frontBottom; } - win->driDrawable = dpy->driScreen->createDrawable(dpy->driScreen, - width, height, - dpy->clientID, visual->mode); + dpy->driScreen.createNewDrawable(dpy, dpy->driver_modes, (int) win, + &win->driDrawable, GLX_WINDOW_BIT, empty_attribute_list); - if (!win->driDrawable) { + if (!win->driDrawable.private) { fprintf(stderr, "%s: dri.createDrawable failed\n", __FUNCTION__); free(win); return NULL; @@ -1293,7 +1559,7 @@ XDestroyWindow( Display *display, Window win ) XUnmapWindow( display, win ); /* Destroy the drawable. */ - (*win->driDrawable->destroyDrawable)(win->driDrawable); + win->driDrawable.destroyDrawable(display, win->driDrawable.private); free(win); /* unlink window from display */ @@ -1748,14 +2014,14 @@ glXCreateContext( Display *dpy, XVisualInfo *vis, ctx->vid = vis->visualid; if (shareList) - sharePriv = shareList->driContext; + sharePriv = shareList->driContext.private; else sharePriv = NULL; - - ctx->driContext = (*dpy->driScreen->createContext)(dpy->driScreen, - vis->visual->mode, - sharePriv); - if (!ctx->driContext) { + + ctx->driContext.private = dpy->driScreen.createNewContext(dpy, vis->visual->mode, + GLX_WINDOW_BIT, sharePriv, &ctx->driContext); + + if (!ctx->driContext.private) { free(ctx); return NULL; } @@ -1782,10 +2048,10 @@ glXDestroyContext( Display *dpy, GLXContext ctx ) if (ctx) { if (glxctx == ctx) { /* destroying current context */ - (*ctx->driContext->bindContext)(dpy->driScreen, 0, 0); + ctx->driContext.bindContext3(dpy, 0, 0, 0, 0); CurrentContext = 0; } - (*ctx->driContext->destroyContext)(ctx->driContext); + ctx->driContext.destroyContext(dpy, 0, ctx->driContext.private); free(ctx); } } @@ -1825,17 +2091,20 @@ glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx) GLXDrawable oldDrawable = glXGetCurrentDrawable(); /* unbind old */ if (oldContext) { - (*oldContext->driContext->unbindContext)(oldDrawable->driDrawable, oldContext->driContext); + oldContext->driContext.unbindContext3(dpy, 0, + (__DRIid) oldDrawable, (__DRIid) oldDrawable, + &oldContext->driContext); } /* bind new */ CurrentContext = ctx; - (*ctx->driContext->bindContext)(dpy->driScreen, drawable->driDrawable, ctx->driContext); + ctx->driContext.bindContext3(dpy, 0, (__DRIid) drawable, + (__DRIid) drawable, &ctx->driContext); ctx->drawBuffer = drawable; ctx->curBuffer = drawable; } else if (ctx && dpy) { /* unbind */ - (*ctx->driContext->bindContext)(dpy->driScreen, 0, 0); + ctx->driContext.bindContext3(dpy, 0, 0, 0, 0); } else if (dpy) { CurrentContext = 0; /* kw: this seems to be intended??? */ @@ -1865,7 +2134,7 @@ glXSwapBuffers( Display *dpy, GLXDrawable drawable ) if (!dpy || !drawable) return; - (*drawable->driDrawable->swapBuffers)(drawable->driDrawable); + drawable->driDrawable.swapBuffers(dpy, drawable->driDrawable.private); } @@ -1906,6 +2175,90 @@ glXGetCurrentDrawable( void ) } +GLboolean +__glXCreateContextWithConfig(__DRInativeDisplay *dpy, int screen, + int fbconfigID, void *contextID, drm_context_t *hHWContext) +{ + __DRIscreen *pDRIScreen; + __DRIscreenPrivate *psp; + + pDRIScreen = __glXFindDRIScreen(dpy, screen); + if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) { + return GL_FALSE; + } + + psp = (__DRIscreenPrivate *) pDRIScreen->private; + + if (psp->fd) { + if (drmCreateContext(psp->fd, hHWContext)) { + fprintf(stderr, ">>> drmCreateContext failed\n"); + return GL_FALSE; + } + *(void**)contextID = (void*) *hHWContext; + } + + return GL_TRUE; +} + + +GLboolean +__glXGetDrawableInfo(__DRInativeDisplay *dpy, int scrn, + __DRIid draw, unsigned int * index, unsigned int * stamp, + int * x, int * y, int * width, int * height, + int * numClipRects, drm_clip_rect_t ** pClipRects, + int * backX, int * backY, + int * numBackClipRects, drm_clip_rect_t ** pBackClipRects) +{ + GLXDrawable drawable = (GLXDrawable) draw; + drm_clip_rect_t * cliprect; + + if (drawable == 0) { + return GL_FALSE; + } + + cliprect = (drm_clip_rect_t*) _mesa_malloc(sizeof(drm_clip_rect_t)); + cliprect->x1 = drawable->x; + cliprect->y1 = drawable->y; + cliprect->x2 = drawable->x + drawable->w; + cliprect->y2 = drawable->y + drawable->h; + + *x = drawable->x; + *y = drawable->y; + *width = drawable->w; + *height = drawable->h; + *numClipRects = 1; + *pClipRects = cliprect; + *backX = 0; + *backY = 0; + *numBackClipRects = 0; + *pBackClipRects = 0; + + return GL_TRUE; +} + + +GLboolean +XF86DRIDestroyContext(__DRInativeDisplay *dpy, int screen, __DRIid context_id ) +{ + return GL_TRUE; +} + + +GLboolean +XF86DRICreateDrawable(__DRInativeDisplay *dpy, int screen, __DRIid drawable, + drm_drawable_t *hHWDrawable ) +{ + return GL_TRUE; +} + + +GLboolean +XF86DRIDestroyDrawable(__DRInativeDisplay *dpy, int screen, __DRIid drawable) +{ + return GL_TRUE; +} + + /** * \brief Query function address. * @@ -1926,8 +2279,7 @@ glXGetCurrentDrawable( void ) * Returns the function address by looking up its name in a static (name, * address) pair list. */ -const void * -glXGetProcAddress( const GLubyte *procName ) +void (*glXGetProcAddress(const GLubyte *procname))( void ) { struct name_address { const char *name; @@ -1955,15 +2307,18 @@ glXGetProcAddress( const GLubyte *procName ) { "glXDestroyPbuffer", (void *) glXDestroyPbuffer }, { "glXChooseFBConfig", (void *) glXChooseFBConfig }, { "glXGetVisualFromFBConfig", (void *) glXGetVisualFromFBConfig }, + { "__glXCreateContextWithConfig", (void *) __glXCreateContextWithConfig }, + { "__glXGetDrawableInfo", (void *) __glXGetDrawableInfo }, + { "__glXWindowExists", (void *) __glXWindowExists }, { NULL, NULL } }; const struct name_address *entry; for (entry = functions; entry->name; entry++) { - if (strcmp(entry->name, (const char *) procName) == 0) { + if (strcmp(entry->name, (const char *) procname) == 0) { return entry->func; } } - return _glapi_get_proc_address((const char *) procName); + return _glapi_get_proc_address((const char *) procname); } diff --git a/src/glx/mini/miniglxP.h b/src/glx/mini/miniglxP.h index a32429a677c..ce0eafe17e3 100644 --- a/src/glx/mini/miniglxP.h +++ b/src/glx/mini/miniglxP.h @@ -18,7 +18,7 @@ #include "mtypes.h" #include "driver.h" -#include "dri.h" +#include "GL/internal/dri_interface.h" /** * \brief Supported pixel formats. @@ -71,7 +71,7 @@ struct MiniGLXWindowRec { GLubyte *frontBottom; /**< \brief pointer to last row */ GLubyte *backBottom; /**< \brief pointer to last row */ GLubyte *curBottom; /**< = frontBottom or backBottom */ - __DRIdrawable *driDrawable; + __DRIdrawable driDrawable; GLuint ismapped; }; @@ -85,7 +85,7 @@ struct MiniGLXContextRec { Window drawBuffer; /**< \brief drawing buffer */ Window curBuffer; /**< \brief current buffer */ VisualID vid; /**< \brief visual ID */ - __DRIcontext *driContext; /**< \brief context dependent methods */ + __DRIcontext driContext; /**< \brief context dependent methods */ }; #define MINIGLX_BUF_SIZE 512 @@ -153,18 +153,23 @@ struct MiniGLXDisplayRec { /*@{*/ int numModes; /**< \brief Number of modes. */ const __GLcontextModes *modes; /**< \brief Modes list pointer. */ + const __GLcontextModes *driver_modes; /**< \brief Modes filtered by driver. */ /*@}*/ /** * \name From __GLXdisplayPrivate */ /*@{*/ - driCreateScreenFunc *createScreen; /**< \brief \e __driCreateScreen hook */ - __DRIscreen *driScreen; /**< \brief Screen dependent methods */ + PFNCREATENEWSCREENFUNC createNewScreen; /**< \brief \e __driCreateScreen hook */ + __DRIscreen driScreen; /**< \brief Screen dependent methods */ void *dlHandle; /**< * \brief handle to the client dynamic * library */ + void *dlHandleSrv; /**< + * \brief handle to the server dynamic + * library + */ /*@}*/ /** @@ -184,9 +189,7 @@ struct MiniGLXDisplayRec { /*@}*/ }; -extern __DRIscreen *__glXFindDRIScreen(Display *dpy, int scrn); - -extern Bool __glXWindowExists(Display *dpy, GLXDrawable draw); +extern Bool __glXWindowExists(__DRInativeDisplay *dpy, GLXDrawable draw); extern int __miniglx_open_connections( Display *dpy ); extern void __miniglx_close_connections( Display *dpy ); diff --git a/src/glx/mini/miniglx_events.c b/src/glx/mini/miniglx_events.c index 319fc530fa1..daa61ca73b5 100644 --- a/src/glx/mini/miniglx_events.c +++ b/src/glx/mini/miniglx_events.c @@ -38,7 +38,7 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/* $Id: miniglx_events.c,v 1.2 2004/03/11 20:35:38 jonsmirl Exp $ */ +/* $Id: miniglx_events.c,v 1.3 2004/06/26 17:16:42 jonsmirl Exp $ */ #include <assert.h> @@ -64,8 +64,6 @@ #include "miniglxP.h" -#include "xf86drm.h" -#include "dri_util.h" #define MINIGLX_FIFO_NAME "/tmp/miniglx.fifo" diff --git a/src/glx/mini/xf86drm.c b/src/glx/mini/xf86drm.c deleted file mode 100644 index bbb02e4032b..00000000000 --- a/src/glx/mini/xf86drm.c +++ /dev/null @@ -1,1587 +0,0 @@ -/** - * \file xf86drm.c - * \brief User-level interface to DRM device - * - * This file is an user-friendly interface to the DRM ioctls defined in drm.h. - * - * This covers only the device-independent ioctls -- it is up to the driver to - * wrap the device-dependent ioctls. - * - * \author Rickard E. (Rik) Faith <[email protected]> - * \author Kevin E. Martin <[email protected]> - */ - -/* - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * 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 (including the next - * paragraph) 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 - * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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. - */ - -# include <stdio.h> -# include <stdlib.h> -# include <unistd.h> -# include <string.h> -# include <ctype.h> -# include <fcntl.h> -# include <errno.h> -# include <signal.h> -# include <sys/types.h> -# include <sys/stat.h> -# include <sys/ioctl.h> -# include <sys/mman.h> -# include <sys/time.h> -# include <stdarg.h> -# include "drm.h" - -/* Not all systems have MAP_FAILED defined */ -#ifndef MAP_FAILED -#define MAP_FAILED ((void *)-1) -#endif - -#include "xf86drm.h" - -#ifndef DRM_MAJOR -#define DRM_MAJOR 226 /* Linux */ -#endif - -#ifndef __linux__ -#undef DRM_MAJOR -#define DRM_MAJOR 145 /* Should set in drm.h for *BSD */ -#endif - -#ifndef DRM_MAX_MINOR -#define DRM_MAX_MINOR 16 -#endif - -#ifdef __linux__ -#include <sys/sysmacros.h> /* for makedev() */ -#endif - -#ifndef makedev - /* This definition needs to be changed on - some systems if dev_t is a structure. - If there is a header file we can get it - from, there would be best. */ -#define makedev(x,y) ((dev_t)(((x) << 8) | (y))) -#endif - - -/** - * \brief Output a message to stderr. - * - * \param format printf() like format string. - * - * \internal - * This function is a wrapper around vfprintf(). - */ -static void -drmMsg(const char *format, ...) -{ - va_list ap; - - const char *env; - if ((env = getenv("LIBGL_DEBUG")) && strstr(env, "verbose")) - { - va_start(ap, format); - vfprintf(stderr, format, ap); - va_end(ap); - } -} - - - -/** - * \brief Open the DRM device, creating it if necessary. - * - * \param dev major and minor numbers of the device. - * \param minor minor number of the device. - * - * \return a file descriptor on success, or a negative value on error. - * - * \internal - * Assembles the device name from \p minor and opens it, creating the device - * special file node with the major and minor numbers specified by \p dev and - * parent directory if necessary and was called by root. - */ -static int drmOpenDevice(long dev, int minor) -{ - struct stat st; - char buf[64]; - int fd; - mode_t devmode = DRM_DEV_MODE; - int isroot = !geteuid(); -#if defined(XFree86Server) - uid_t user = DRM_DEV_UID; - gid_t group = DRM_DEV_GID; -#endif - - drmMsg("drmOpenDevice: minor is %d\n", minor); - -#if defined(XFree86Server) - devmode = xf86ConfigDRI.mode ? xf86ConfigDRI.mode : DRM_DEV_MODE; - devmode &= ~(S_IXUSR|S_IXGRP|S_IXOTH); - group = (xf86ConfigDRI.group >= 0) ? xf86ConfigDRI.group : DRM_DEV_GID; -#endif - - if (stat(DRM_DIR_NAME, &st)) { - if (!isroot) return DRM_ERR_NOT_ROOT; - mkdir(DRM_DIR_NAME, DRM_DEV_DIRMODE); - chown(DRM_DIR_NAME, 0, 0); /* root:root */ - chmod(DRM_DIR_NAME, DRM_DEV_DIRMODE); - } - - sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, minor); - drmMsg("drmOpenDevice: node name is %s\n", buf); - if (stat(buf, &st)) { - if (!isroot) return DRM_ERR_NOT_ROOT; - remove(buf); - mknod(buf, S_IFCHR | devmode, dev); - } -#if defined(XFree86Server) - chown(buf, user, group); - chmod(buf, devmode); -#endif - - fd = open(buf, O_RDWR, 0); - drmMsg("drmOpenDevice: open result is %d, (%s)\n", - fd, fd < 0 ? strerror(errno) : "OK"); - if (fd >= 0) return fd; - - if (st.st_rdev != dev) { - if (!isroot) return DRM_ERR_NOT_ROOT; - remove(buf); - mknod(buf, S_IFCHR | devmode, dev); - } - fd = open(buf, O_RDWR, 0); - drmMsg("drmOpenDevice: open result is %d, (%s)\n", - fd, fd < 0 ? strerror(errno) : "OK"); - if (fd >= 0) return fd; - - drmMsg("drmOpenDevice: Open failed\n"); - remove(buf); - return -errno; -} - - -/** - * \brief Open the DRM device - * - * \param minor device minor number. - * \param create allow to create the device if set. - * - * \return a file descriptor on success, or a negative value on error. - * - * \internal - * Calls drmOpenDevice() if \p create is set, otherwise assembles the device - * name from \p minor and opens it. - */ -static int drmOpenMinor(int minor, int create) -{ - int fd; - char buf[64]; - - if (create) return drmOpenDevice(makedev(DRM_MAJOR, minor), minor); - - sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, minor); - if ((fd = open(buf, O_RDWR, 0)) >= 0) return fd; - drmMsg("drmOpenMinor: open result is %d, (%s)\n", - fd, fd < 0 ? strerror(errno) : "OK"); - return -errno; -} - - -/** - * \brief Determine whether the DRM kernel driver has been loaded. - * - * \return 1 if the DRM driver is loaded, 0 otherwise. - * - * \internal - * Determine the presence of the kernel driver by attempting to open the 0 - * minor and get version information. For backward compatibility with older - * Linux implementations, /proc/dri is also checked. - */ -int drmAvailable(void) -{ - drmVersionPtr version; - int retval = 0; - int fd; - - if ((fd = drmOpenMinor(0, 1)) < 0) { - /* Try proc for backward Linux compatibility */ - if (!access("/proc/dri/0", R_OK)) return 1; - return 0; - } - - if ((version = drmGetVersion(fd))) { - retval = 1; - drmFreeVersion(version); - } - close(fd); - drmMsg("close %d\n", fd); - - return retval; -} - - -/** - * \brief Open the device by bus ID. - * - * \param busid bus ID. - * - * \return a file descriptor on success, or a negative value on error. - * - * \internal - * This function attempts to open every possible minor (up to DRM_MAX_MINOR), - * comparing the device bus ID with the one supplied. - * - * \sa drmOpenMinor() and drmGetBusid(). - */ -static int drmOpenByBusid(const char *busid) -{ - int i; - int fd; - const char *buf; - - drmMsg("drmOpenByBusid: busid is %s\n", busid); - for (i = 0; i < DRM_MAX_MINOR; i++) { - fd = drmOpenMinor(i, 1); - drmMsg("drmOpenByBusid: drmOpenMinor returns %d\n", fd); - if (fd >= 0) { - buf = drmGetBusid(fd); - drmMsg("drmOpenByBusid: drmGetBusid reports %s\n", buf); - if (buf && !strcmp(buf, busid)) { - drmFreeBusid(buf); - return fd; - } - if (buf) drmFreeBusid(buf); - close(fd); - drmMsg("close %d\n", fd); - } - } - return -1; -} - - -/** - * \brief Open the device by name. - * - * \param name driver name. - * - * \return a file descriptor on success, or a negative value on error. - * - * \internal - * This function opens the first minor number that matches the driver name and - * isn't already in use. If it's in use it then it will already have a bus ID - * assigned. - * - * \sa drmOpenMinor(), drmGetVersion() and drmGetBusid(). - */ -static int drmOpenByName(const char *name) -{ - int i; - int fd; - drmVersionPtr version; - char * id; - - if (!drmAvailable()) { -#if !defined(XFree86Server) - return -1; -#else - /* try to load the kernel module now */ - if (!xf86LoadKernelModule(name)) { - ErrorF("[drm] failed to load kernel module \"%s\"\n", - name); - return -1; - } -#endif - } - - for (i = 0; i < DRM_MAX_MINOR; i++) { - if ((fd = drmOpenMinor(i, 1)) >= 0) { - if ((version = drmGetVersion(fd))) { - if (!strcmp(version->name, name)) { - drmFreeVersion(version); - -/* return fd; */ - - id = drmGetBusid(fd); - drmMsg("drmGetBusid returned '%s'\n", id ? id : "NULL"); - if (!id || !*id) { - if (id) { - drmFreeBusid(id); - } - return fd; - } else { - drmFreeBusid(id); - } - } else { - drmFreeVersion(version); - } - } - close(fd); - drmMsg("close %d\n", fd); - } - } - - return -1; -} - - -/** - * \brief Open the DRM device. - * - * Looks up the specified name and bus ID, and opens the device found. The - * entry in /dev/dri is created if necessary and if called by root. - * - * \param name driver name. Not referenced if bus ID is supplied. - * \param busid bus ID. Zero if not known. - * - * \return a file descriptor on success, or a negative value on error. - * - * \internal - * It calls drmOpenByBusid() if \p busid is specified or drmOpenByName() - * otherwise. - */ -int drmOpen(const char *name, const char *busid) -{ - - if (busid) return drmOpenByBusid(busid); - return drmOpenByName(name); -} - - -/** - * \brief Free the version information returned by drmGetVersion(). - * - * \param v pointer to the version information. - * - * \internal - * It frees the memory pointed by \p %v as well as all the non-null strings - * pointers in it. - */ -void drmFreeVersion(drmVersionPtr v) -{ - if (!v) return; - if (v->name) free(v->name); - if (v->date) free(v->date); - if (v->desc) free(v->desc); - free(v); -} - - -/** - * \brief Free the non-public version information returned by the kernel. - * - * \param v pointer to the version information. - * - * \internal - * Used by drmGetVersion() to free the memory pointed by \p %v as well as all - * the non-null strings pointers in it. - */ -static void drmFreeKernelVersion(drm_version_t *v) -{ - if (!v) return; - if (v->name) free(v->name); - if (v->date) free(v->date); - if (v->desc) free(v->desc); - free(v); -} - - -/** - * \brief Copy version information. - * - * \param d destination pointer. - * \param s source pointer. - * - * \internal - * Used by drmGetVersion() to translate the information returned by the ioctl - * interface in a private structure into the public structure counterpart. - */ -static void drmCopyVersion(drmVersionPtr d, const drm_version_t *s) -{ - d->version_major = s->version_major; - d->version_minor = s->version_minor; - d->version_patchlevel = s->version_patchlevel; - d->name_len = s->name_len; - d->name = strdup(s->name); - d->date_len = s->date_len; - d->date = strdup(s->date); - d->desc_len = s->desc_len; - d->desc = strdup(s->desc); -} - - -/** - * \brief Query the driver version information. - * - * \param fd file descriptor. - * - * \return pointer to a drmVersion structure which should be freed with - * drmFreeVersion(). - * - * \note Similar information is available via /proc/dri. - * - * \internal - * It gets the version information via successive DRM_IOCTL_VERSION ioctls, - * first with zeros to get the string lengths, and then the actually strings. - * It also null-terminates them since they might not be already. - */ -drmVersionPtr drmGetVersion(int fd) -{ - drmVersionPtr retval; - drm_version_t *version = malloc(sizeof(*version)); - - /* First, get the lengths */ - version->name_len = 0; - version->name = NULL; - version->date_len = 0; - version->date = NULL; - version->desc_len = 0; - version->desc = NULL; - - if (ioctl(fd, DRM_IOCTL_VERSION, version)) { - drmFreeKernelVersion(version); - return NULL; - } - - /* Now, allocate space and get the data */ - if (version->name_len) - version->name = malloc(version->name_len + 1); - if (version->date_len) - version->date = malloc(version->date_len + 1); - if (version->desc_len) - version->desc = malloc(version->desc_len + 1); - - if (ioctl(fd, DRM_IOCTL_VERSION, version)) { - drmFreeKernelVersion(version); - return NULL; - } - - /* The results might not be null-terminated - strings, so terminate them. */ - - if (version->name_len) version->name[version->name_len] = '\0'; - if (version->date_len) version->date[version->date_len] = '\0'; - if (version->desc_len) version->desc[version->desc_len] = '\0'; - - /* Now, copy it all back into the - client-visible data structure... */ - retval = malloc(sizeof(*retval)); - drmCopyVersion(retval, version); - drmFreeKernelVersion(version); - return retval; -} - - -/** - * \brief Get version information for the DRM user space library. - * - * This version number is driver independent. - * - * \param fd file descriptor. - * - * \return version information. - * - * \internal - * This function allocates and fills a drm_version structure with a hard coded - * version number. - */ -drmVersionPtr drmGetLibVersion(int fd) -{ - drm_version_t *version = malloc(sizeof(*version)); - - /* Version history: - * revision 1.0.x = original DRM interface with no drmGetLibVersion - * entry point and many drm<Device> extensions - * revision 1.1.x = added drmCommand entry points for device extensions - * added drmGetLibVersion to identify libdrm.a version - */ - version->version_major = 1; - version->version_minor = 1; - version->version_patchlevel = 0; - - return (drmVersionPtr)version; -} - - -/** - * \brief Free the bus ID information. - * - * \param busid bus ID information string as given by drmGetBusid(). - * - * \internal - * This function is just frees the memory pointed by \p busid. - */ -void drmFreeBusid(const char *busid) -{ - free((void *)busid); -} - - -/** - * \brief Get the bus ID of the device. - * - * \param fd file descriptor. - * - * \return bus ID string. - * - * \internal - * This function gets the bus ID via successive DRM_IOCTL_GET_UNIQUE ioctls to - * get the string length and data, passing the arguments in a drm_unique - * structure. - */ -char *drmGetBusid(int fd) -{ - drm_unique_t u; - - u.unique_len = 0; - u.unique = NULL; - - if (ioctl(fd, DRM_IOCTL_GET_UNIQUE, &u)) return NULL; - u.unique = malloc(u.unique_len + 1); - if (ioctl(fd, DRM_IOCTL_GET_UNIQUE, &u)) return NULL; - u.unique[u.unique_len] = '\0'; - return u.unique; -} - - -/** - * \brief Set the bus ID of the device. - * - * \param fd file descriptor. - * \param busid bus ID string. - * - * \return zero on success, negative on failure. - * - * \internal - * This function is a wrapper around the DRM_IOCTL_SET_UNIQUE ioctl, passing - * the arguments in a drm_unique structure. - */ -int drmSetBusid(int fd, const char *busid) -{ - drm_unique_t u; - - u.unique = (char *)busid; - u.unique_len = strlen(busid); - - if (ioctl(fd, DRM_IOCTL_SET_UNIQUE, &u)) { - return -errno; - } - return 0; -} - - -/** - * \brief Specifies a range of memory that is available for mapping by a - * non-root process. - * - * \param fd file descriptor. - * \param offset usually the physical address. The actual meaning depends of - * the \p type parameter. See below. - * \param size of the memory in bytes. - * \param type type of the memory to be mapped. - * \param flags combination of several flags to modify the function actions. - * \param handle will be set to a value that may be used as the offset - * parameter for mmap(). - * - * \return zero on success or a negative value on error. - * - * \par Mapping the frame buffer - * For the frame buffer - * - \p offset will be the physical address of the start of the frame buffer, - * - \p size will be the size of the frame buffer in bytes, and - * - \p type will be DRM_FRAME_BUFFER. - * - * \par - * The area mapped will be uncached. If MTRR support is available in the - * kernel, the frame buffer area will be set to write combining. - * - * \par Mapping the MMIO register area - * For the MMIO register area, - * - \p offset will be the physical address of the start of the register area, - * - \p size will be the size of the register area bytes, and - * - \p type will be DRM_REGISTERS. - * \par - * The area mapped will be uncached. - * - * \par Mapping the SAREA - * For the SAREA, - * - \p offset will be ignored and should be set to zero, - * - \p size will be the desired size of the SAREA in bytes, - * - \p type will be DRM_SHM. - * - * \par - * A shared memory area of the requested size will be created and locked in - * kernel memory. This area may be mapped into client-space by using the handle - * returned. - * - * \note May only be called by root. - * - * \internal - * This function is a wrapper around the DRM_IOCTL_ADD_MAP ioctl, passing - * the arguments in a drm_map structure. - */ -int drmAddMap(int fd, - drmHandle offset, - drmSize size, - drmMapType type, - drmMapFlags flags, - drmHandlePtr handle) -{ - drm_map_t map; - - map.offset = offset; - map.size = size; - map.handle = 0; - map.type = type; - map.flags = flags; - if (ioctl(fd, DRM_IOCTL_ADD_MAP, &map)) return -errno; - if (handle) *handle = (drmHandle)map.handle; - return 0; -} - - -/** - * \brief Make buffers available for DMA transfers. - * - * \param fd file descriptor. - * \param count number of buffers. - * \param size size of each buffer. - * \param flags buffer allocation flags. - * \param agp_offset offset in the AGP aperture - * - * \return number of buffers allocated, negative on error. - * - * \internal - * This function is a wrapper around DRM_IOCTL_ADD_BUFS ioctl. - * - * \sa drm_buf_desc. - */ -int drmAddBufs(int fd, int count, int size, drmBufDescFlags flags, - int agp_offset) -{ - drm_buf_desc_t request; - - request.count = count; - request.size = size; - request.low_mark = 0; - request.high_mark = 0; - request.flags = flags; - request.agp_start = agp_offset; - - if (ioctl(fd, DRM_IOCTL_ADD_BUFS, &request)) return -errno; - return request.count; -} - - -/** - * \brief Free buffers. - * - * \param fd file descriptor. - * \param count number of buffers to free. - * \param list list of buffers to be freed. - * - * \return zero on success, or a negative value on failure. - * - * \note This function is primarily used for debugging. - * - * \internal - * This function is a wrapper around the DRM_IOCTL_FREE_BUFS ioctl, passing - * the arguments in a drm_buf_free structure. - */ -int drmFreeBufs(int fd, int count, int *list) -{ - drm_buf_free_t request; - - request.count = count; - request.list = list; - if (ioctl(fd, DRM_IOCTL_FREE_BUFS, &request)) return -errno; - return 0; -} - - -/** - * \brief Close the device. - * - * \param fd file descriptor. - * - * \internal - * This function closes the file descriptor. - */ -int drmClose(int fd) -{ - drmMsg("close %d\n", fd); - return close(fd); -} - - -/** - * \brief Map a region of memory. - * - * \param fd file descriptor. - * \param handle handle returned by drmAddMap(). - * \param size size in bytes. Must match the size used by drmAddMap(). - * \param address will contain the user-space virtual address where the mapping - * begins. - * - * \return zero on success, or a negative value on failure. - * - * \internal - * This function is a wrapper for mmap(). - */ -int drmMap(int fd, - drmHandle handle, - drmSize size, - drmAddressPtr address) -{ - static unsigned long pagesize_mask = 0; - - if (fd < 0) return -EINVAL; - - if (!pagesize_mask) - pagesize_mask = getpagesize() - 1; - - size = (size + pagesize_mask) & ~pagesize_mask; - - *address = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, handle); - if (*address == MAP_FAILED) return -errno; - return 0; -} - - -/** - * \brief Unmap mappings obtained with drmMap(). - * - * \param address address as given by drmMap(). - * \param size size in bytes. Must match the size used by drmMap(). - * - * \return zero on success, or a negative value on failure. - * - * \internal - * This function is a wrapper for unmap(). - */ -int drmUnmap(drmAddress address, drmSize size) -{ - return munmap(address, size); -} - - -/** - * \brief Map all DMA buffers into client-virtual space. - * - * \param fd file descriptor. - * - * \return a pointer to a ::drmBufMap structure. - * - * \note The client may not use these buffers until obtaining buffer indices - * with drmDMA(). - * - * \internal - * This function calls the DRM_IOCTL_MAP_BUFS ioctl and copies the returned - * information about the buffers in a drm_buf_map structure into the - * client-visible data structures. - */ -drmBufMapPtr drmMapBufs(int fd) -{ - drm_buf_map_t bufs; - drmBufMapPtr retval; - int i; - - bufs.count = 0; - bufs.list = NULL; - if (ioctl(fd, DRM_IOCTL_MAP_BUFS, &bufs)) return NULL; - - if (bufs.count) { - if (!(bufs.list = malloc(bufs.count * sizeof(*bufs.list)))) - return NULL; - - if (ioctl(fd, DRM_IOCTL_MAP_BUFS, &bufs)) { - free(bufs.list); - return NULL; - } - /* Now, copy it all back into the - client-visible data structures... */ - retval = malloc(sizeof(*retval)); - retval->count = bufs.count; - retval->list = malloc(bufs.count * sizeof(*retval->list)); - for (i = 0; i < bufs.count; i++) { - retval->list[i].idx = bufs.list[i].idx; - retval->list[i].total = bufs.list[i].total; - retval->list[i].used = 0; - retval->list[i].address = bufs.list[i].address; - } - return retval; - } - return NULL; -} - - -/** - * \brief Unmap buffers allocated with drmMapBufs(). - * - * \return zero on success, or negative value on failure. - * - * \internal - * Calls munmap() for every buffer stored in \p bufs. - */ -int drmUnmapBufs(drmBufMapPtr bufs) -{ - int i; - - for (i = 0; i < bufs->count; i++) { - munmap(bufs->list[i].address, bufs->list[i].total); - } - return 0; -} - - -#define DRM_DMA_RETRY 16 - -/** - * \brief Reserve DMA buffers. - * - * \param fd file descriptor. - * \param request - * - * \return zero on success, or a negative value on failure. - * - * \internal - * Assemble the arguments into a drm_dma structure and keeps issuing the - * DRM_IOCTL_DMA ioctl until success or until maximum number of retries. - */ -int drmDMA(int fd, drmDMAReqPtr request) -{ - drm_dma_t dma; - int ret, i = 0; - - /* Copy to hidden structure */ - dma.context = request->context; - dma.send_count = request->send_count; - dma.send_indices = request->send_list; - dma.send_sizes = request->send_sizes; - dma.flags = request->flags; - dma.request_count = request->request_count; - dma.request_size = request->request_size; - dma.request_indices = request->request_list; - dma.request_sizes = request->request_sizes; - - do { - ret = ioctl( fd, DRM_IOCTL_DMA, &dma ); - } while ( ret && errno == EAGAIN && i++ < DRM_DMA_RETRY ); - - if ( ret == 0 ) { - request->granted_count = dma.granted_count; - return 0; - } else { - return -errno; - } -} - - -/** - * \brief Obtain heavyweight hardware lock. - * - * \param fd file descriptor. - * \param context context. - * \param flags flags that determine the sate of the hardware when the function - * returns. - * - * \return always zero. - * - * \internal - * This function translates the arguments into a drm_lock structure and issue - * the DRM_IOCTL_LOCK ioctl until the lock is successfully acquired. - */ -int drmGetLock(int fd, drmContext context, drmLockFlags flags) -{ - drm_lock_t lock; - - lock.context = context; - lock.flags = 0; - if (flags & DRM_LOCK_READY) lock.flags |= _DRM_LOCK_READY; - if (flags & DRM_LOCK_QUIESCENT) lock.flags |= _DRM_LOCK_QUIESCENT; - if (flags & DRM_LOCK_FLUSH) lock.flags |= _DRM_LOCK_FLUSH; - if (flags & DRM_LOCK_FLUSH_ALL) lock.flags |= _DRM_LOCK_FLUSH_ALL; - if (flags & DRM_HALT_ALL_QUEUES) lock.flags |= _DRM_HALT_ALL_QUEUES; - if (flags & DRM_HALT_CUR_QUEUES) lock.flags |= _DRM_HALT_CUR_QUEUES; - - while (ioctl(fd, DRM_IOCTL_LOCK, &lock)) - ; - return 0; -} - -static void (*drm_unlock_callback)( void ) = 0; - -/** - * \brief Release the hardware lock. - * - * \param fd file descriptor. - * \param context context. - * - * \return zero on success, or a negative value on failure. - * - * \internal - * This function is a wrapper around the DRM_IOCTL_UNLOCK ioctl, passing the - * argument in a drm_lock structure. - */ -int drmUnlock(int fd, drmContext context) -{ - drm_lock_t lock; - int ret; - - lock.context = context; - lock.flags = 0; - ret = ioctl(fd, DRM_IOCTL_UNLOCK, &lock); - - /* Need this to synchronize vt releasing. Could also teach fbdev - * about the drm lock... - */ - if (drm_unlock_callback) { - drm_unlock_callback(); - } - - return ret; -} - - -/** - * \brief Create context. - * - * Used by the X server during GLXContext initialization. This causes - * per-context kernel-level resources to be allocated. - * - * \param fd file descriptor. - * \param handle is set on success. To be used by the client when requesting DMA - * dispatch with drmDMA(). - * - * \return zero on success, or a negative value on failure. - * - * \note May only be called by root. - * - * \internal - * This function is a wrapper around the DRM_IOCTL_ADD_CTX ioctl, passing the - * argument in a drm_ctx structure. - */ -int drmCreateContext(int fd, drmContextPtr handle) -{ - drm_ctx_t ctx; - - ctx.flags = 0; /* Modified with functions below */ - if (ioctl(fd, DRM_IOCTL_ADD_CTX, &ctx)) return -errno; - *handle = ctx.handle; - return 0; -} - - -/** - * \brief Destroy context. - * - * Free any kernel-level resources allocated with drmCreateContext() associated - * with the context. - * - * \param fd file descriptor. - * \param handle handle given by drmCreateContext(). - * - * \return zero on success, or a negative value on failure. - * - * \note May only be called by root. - * - * \internal - * This function is a wrapper around the DRM_IOCTL_RM_CTX ioctl, passing the - * argument in a drm_ctx structure. - */ -int drmDestroyContext(int fd, drmContext handle) -{ - drm_ctx_t ctx; - ctx.handle = handle; - if (ioctl(fd, DRM_IOCTL_RM_CTX, &ctx)) return -errno; - return 0; -} - - -/** - * \brief Acquire the AGP device. - * - * Must be called before any of the other AGP related calls. - * - * \param fd file descriptor. - * - * \return zero on success, or a negative value on failure. - * - * \internal - * This function is a wrapper around the DRM_IOCTL_AGP_ACQUIRE ioctl. - */ -int drmAgpAcquire(int fd) -{ - if (ioctl(fd, DRM_IOCTL_AGP_ACQUIRE, NULL)) return -errno; - return 0; -} - - -/** - * \brief Release the AGP device. - * - * \param fd file descriptor. - * - * \return zero on success, or a negative value on failure. - * - * \internal - * This function is a wrapper around the DRM_IOCTL_AGP_RELEASE ioctl. - */ -int drmAgpRelease(int fd) -{ - if (ioctl(fd, DRM_IOCTL_AGP_RELEASE, NULL)) return -errno; - return 0; -} - - -/** - * \brief Set the AGP mode. - * - * \param fd file descriptor. - * \param mode AGP mode. - * - * \return zero on success, or a negative value on failure. - * - * \internal - * This function is a wrapper around the DRM_IOCTL_AGP_ENABLE ioctl, passing the - * argument in a drm_agp_mode structure. - */ -int drmAgpEnable(int fd, unsigned long mode) -{ - drm_agp_mode_t m; - - m.mode = mode; - if (ioctl(fd, DRM_IOCTL_AGP_ENABLE, &m)) return -errno; - return 0; -} - - -/** - * \brief Allocate a chunk of AGP memory. - * - * \param fd file descriptor. - * \param size requested memory size in bytes. Will be rounded to page boundary. - * \param type type of memory to allocate. - * \param address if not zero, will be set to the physical address of the - * allocated memory. - * \param handle on success will be set to a handle of the allocated memory. - * - * \return zero on success, or a negative value on failure. - * - * \internal - * This function is a wrapper around the DRM_IOCTL_AGP_ALLOC ioctl, passing the - * arguments in a drm_agp_buffer structure. - */ -int drmAgpAlloc(int fd, unsigned long size, unsigned long type, - unsigned long *address, unsigned long *handle) -{ - drm_agp_buffer_t b; - *handle = 0; - b.size = size; - b.handle = 0; - b.type = type; - if (ioctl(fd, DRM_IOCTL_AGP_ALLOC, &b)) return -errno; - if (address != 0UL) *address = b.physical; - *handle = b.handle; - return 0; -} - - -/** - * \brief Free a chunk of AGP memory. - * - * \param fd file descriptor. - * \param handle handle to the allocated memory, as given by drmAgpAllocate(). - * - * \return zero on success, or a negative value on failure. - * - * \internal - * This function is a wrapper around the DRM_IOCTL_AGP_FREE ioctl, passing the - * argument in a drm_agp_buffer structure. - */ -int drmAgpFree(int fd, unsigned long handle) -{ - drm_agp_buffer_t b; - - b.size = 0; - b.handle = handle; - if (ioctl(fd, DRM_IOCTL_AGP_FREE, &b)) return -errno; - return 0; -} - - -/** - * \brief Bind a chunk of AGP memory. - * - * \param fd file descriptor. - * \param handle handle to the allocated memory, as given by drmAgpAllocate(). - * \param offset offset in bytes. It will round to page boundary. - * - * \return zero on success, or a negative value on failure. - * - * \internal - * This function is a wrapper around the DRM_IOCTL_AGP_BIND ioctl, passing the - * argument in a drm_agp_binding structure. - */ -int drmAgpBind(int fd, unsigned long handle, unsigned long offset) -{ - drm_agp_binding_t b; - - b.handle = handle; - b.offset = offset; - if (ioctl(fd, DRM_IOCTL_AGP_BIND, &b)) return -errno; - return 0; -} - - -/** - * \brief Unbind a chunk of AGP memory. - * - * \param fd file descriptor. - * \param handle handle to the allocated memory, as given by drmAgpAllocate(). - * - * \return zero on success, or a negative value on failure. - * - * \internal - * This function is a wrapper around the DRM_IOCTL_AGP_UNBIND ioctl, passing - * the argument in a drm_agp_binding structure. - */ -int drmAgpUnbind(int fd, unsigned long handle) -{ - drm_agp_binding_t b; - - b.handle = handle; - b.offset = 0; - if (ioctl(fd, DRM_IOCTL_AGP_UNBIND, &b)) return -errno; - return 0; -} - - -/** - * \brief Get AGP driver major version number. - * - * \param fd file descriptor. - * - * \return major version number on success, or a negative value on failure.. - * - * \internal - * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the - * necessary information in a drm_agp_info structure. - */ -int drmAgpVersionMajor(int fd) -{ - drm_agp_info_t i; - - if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return -errno; - return i.agp_version_major; -} - - -/** - * \brief Get AGP driver minor version number. - * - * \param fd file descriptor. - * - * \return minor version number on success, or a negative value on failure. - * - * \internal - * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the - * necessary information in a drm_agp_info structure. - */ -int drmAgpVersionMinor(int fd) -{ - drm_agp_info_t i; - - if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return -errno; - return i.agp_version_minor; -} - - -/** - * \brief Get AGP mode. - * - * \param fd file descriptor. - * - * \return mode on success, or zero on failure. - * - * \internal - * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the - * necessary information in a drm_agp_info structure. - */ -unsigned long drmAgpGetMode(int fd) -{ - drm_agp_info_t i; - - if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0; - return i.mode; -} - - -/** - * \brief Get AGP aperture base. - * - * \param fd file descriptor. - * - * \return aperture base on success, zero on failure. - * - * \internal - * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the - * necessary information in a drm_agp_info structure. - */ -unsigned long drmAgpBase(int fd) -{ - drm_agp_info_t i; - - if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0; - return i.aperture_base; -} - - -/** - * \brief Get AGP aperture size. - * - * \param fd file descriptor. - * - * \return aperture size on success, zero on failure. - * - * \internal - * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the - * necessary information in a drm_agp_info structure. - */ -unsigned long drmAgpSize(int fd) -{ - drm_agp_info_t i; - - if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0; - return i.aperture_size; -} - - -/** - * \brief Get used AGP memory. - * - * \param fd file descriptor. - * - * \return memory used on success, or zero on failure. - * - * \internal - * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the - * necessary information in a drm_agp_info structure. - */ -unsigned long drmAgpMemoryUsed(int fd) -{ - drm_agp_info_t i; - - if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0; - return i.memory_used; -} - - -/** - * \brief Get available AGP memory. - * - * \param fd file descriptor. - * - * \return memory available on success, or zero on failure. - * - * \internal - * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the - * necessary information in a drm_agp_info structure. - */ -unsigned long drmAgpMemoryAvail(int fd) -{ - drm_agp_info_t i; - - if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0; - return i.memory_allowed; -} - - -/** - * \brief Get hardware vendor ID. - * - * \param fd file descriptor. - * - * \return vendor ID on success, or zero on failure. - * - * \internal - * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the - * necessary information in a drm_agp_info structure. - */ -unsigned int drmAgpVendorId(int fd) -{ - drm_agp_info_t i; - - if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0; - return i.id_vendor; -} - - -/** - * \brief Get hardware device ID. - * - * \param fd file descriptor. - * - * \return zero on success, or zero on failure. - * - * \internal - * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the - * necessary information in a drm_agp_info structure. - */ -unsigned int drmAgpDeviceId(int fd) -{ - drm_agp_info_t i; - - if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0; - return i.id_device; -} - -int drmScatterGatherAlloc(int fd, unsigned long size, unsigned long *handle) -{ - drm_scatter_gather_t sg; - - *handle = 0; - sg.size = size; - sg.handle = 0; - if (ioctl(fd, DRM_IOCTL_SG_ALLOC, &sg)) return -errno; - *handle = sg.handle; - return 0; -} - -int drmScatterGatherFree(int fd, unsigned long handle) -{ - drm_scatter_gather_t sg; - - sg.size = 0; - sg.handle = handle; - if (ioctl(fd, DRM_IOCTL_SG_FREE, &sg)) return -errno; - return 0; -} - -/** - * \brief Wait for VBLANK. - * - * \param fd file descriptor. - * \param vbl pointer to a drmVBlank structure. - * - * \return zero on success, or a negative value on failure. - * - * \internal - * This function is a wrapper around the DRM_IOCTL_WAIT_VBLANK ioctl. - */ -int drmWaitVBlank(int fd, drmVBlankPtr vbl) -{ - int ret; - - do { - ret = ioctl(fd, DRM_IOCTL_WAIT_VBLANK, vbl); - } while (ret && errno == EINTR); - - return ret; -} - - -/** - * \brief Install IRQ handler. - * - * \param fd file descriptor. - * \param irq IRQ number. - * - * \return zero on success, or a negative value on failure. - * - * \internal - * This function is a wrapper around the DRM_IOCTL_CONTROL ioctl, passing the - * argument in a drm_control structure. - */ -int drmCtlInstHandler(int fd, int irq) -{ - drm_control_t ctl; - - ctl.func = DRM_INST_HANDLER; - ctl.irq = irq; - if (ioctl(fd, DRM_IOCTL_CONTROL, &ctl)) return -errno; - return 0; -} - - -/** - * \brief Uninstall IRQ handler. - * - * \param fd file descriptor. - * - * \return zero on success, or a negative value on failure. - * - * \internal - * This function is a wrapper around the DRM_IOCTL_CONTROL ioctl, passing the - * argument in a drm_control structure. - */ -int drmCtlUninstHandler(int fd) -{ - drm_control_t ctl; - - ctl.func = DRM_UNINST_HANDLER; - ctl.irq = 0; - if (ioctl(fd, DRM_IOCTL_CONTROL, &ctl)) return -errno; - return 0; -} - - -/** - * \brief Get IRQ from bus ID. - * - * \param fd file descriptor. - * \param busnum bus number. - * \param devnum device number. - * \param funcnum function number. - * - * \return IRQ number on success, or a negative value on failure. - * - * \internal - * This function is a wrapper around the DRM_IOCTL_IRQ_BUSID ioctl, passing the - * arguments in a drm_irq_busid structure. - */ -int drmGetInterruptFromBusID(int fd, int busnum, int devnum, int funcnum) -{ - drm_irq_busid_t p; - - p.busnum = busnum; - p.devnum = devnum; - p.funcnum = funcnum; - if (ioctl(fd, DRM_IOCTL_IRQ_BUSID, &p)) return -errno; - return p.irq; -} - - -/** - * \brief Send a device-specific command. - * - * \param fd file descriptor. - * \param drmCommandIndex command index - * - * \return zero on success, or a negative value on failure. - * - * \internal - * It issues a ioctl given by - * \code DRM_COMMAND_BASE + drmCommandIndex \endcode. - */ -int drmCommandNone(int fd, unsigned long drmCommandIndex) -{ - void *data = NULL; /* dummy */ - unsigned long request; - - request = DRM_IO( DRM_COMMAND_BASE + drmCommandIndex); - - if (ioctl(fd, request, data)) { - return -errno; - } - return 0; -} - - -/** - * \brief Send a device-specific read command. - * - * \param fd file descriptor. - * \param drmCommandIndex command index - * \param data destination pointer of the data to be read. - * \param size size of the data to be read. - * - * \return zero on success, or a negative value on failure. - * - * \internal - * It issues a read ioctl given by - * \code DRM_COMMAND_BASE + drmCommandIndex \endcode. - */ -int drmCommandRead(int fd, unsigned long drmCommandIndex, - void *data, unsigned long size ) -{ - unsigned long request; - - request = DRM_IOC( DRM_IOC_READ, DRM_IOCTL_BASE, - DRM_COMMAND_BASE + drmCommandIndex, size); - - if (ioctl(fd, request, data)) { - return -errno; - } - return 0; -} - - -/** - * \brief Send a device-specific write command. - * - * \param fd file descriptor. - * \param drmCommandIndex command index - * \param data source pointer of the data to be written. - * \param size size of the data to be written. - * - * \return zero on success, or a negative value on failure. - * - * \internal - * It issues a write ioctl given by - * \code DRM_COMMAND_BASE + drmCommandIndex \endcode. - */ -int drmCommandWrite(int fd, unsigned long drmCommandIndex, - void *data, unsigned long size ) -{ - unsigned long request; - - request = DRM_IOC( DRM_IOC_WRITE, DRM_IOCTL_BASE, - DRM_COMMAND_BASE + drmCommandIndex, size); - - if (ioctl(fd, request, data)) { - return -errno; - } - return 0; -} - - -/** - * \brief Send a device-specific read-write command. - * - * \param fd file descriptor. - * \param drmCommandIndex command index - * \param data source pointer of the data to be read and written. - * \param size size of the data to be read and written. - * - * \return zero on success, or a negative value on failure. - * - * \internal - * It issues a read-write ioctl given by - * \code DRM_COMMAND_BASE + drmCommandIndex \endcode. - */ -int drmCommandWriteRead(int fd, unsigned long drmCommandIndex, - void *data, unsigned long size ) -{ - unsigned long request; - - request = DRM_IOC( DRM_IOC_READ|DRM_IOC_WRITE, DRM_IOCTL_BASE, - DRM_COMMAND_BASE + drmCommandIndex, size); - - if (ioctl(fd, request, data)) { - return -errno; - } - return 0; -} - diff --git a/src/glx/mini/xf86drm.h b/src/glx/mini/xf86drm.h deleted file mode 100644 index cee5ca5f696..00000000000 --- a/src/glx/mini/xf86drm.h +++ /dev/null @@ -1,609 +0,0 @@ -/* xf86drm.h -- OS-independent header for DRM user-level library interface - * Created: Tue Jan 5 08:17:23 1999 by [email protected] - * - * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * 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 (including the next - * paragraph) 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 - * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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. - * - * Author: Rickard E. (Rik) Faith <[email protected]> - * - * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h,v 1.22 2003/06/12 14:12:35 eich Exp $ - * - */ - -#ifndef _XF86DRM_H_ -#define _XF86DRM_H_ - - /* Defaults, if nothing set in xf86config */ -#define DRM_DEV_UID 0 -#define DRM_DEV_GID 0 -/* Default /dev/dri directory permissions 0755 */ -#define DRM_DEV_DIRMODE \ - (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) -#define DRM_DEV_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) - -#define DRM_DIR_NAME "/dev/dri" -#define DRM_DEV_NAME "%s/card%d" -#define DRM_PROC_NAME "/proc/dri/" /* For backware Linux compatibility */ - -#define DRM_ERR_NO_DEVICE (-1001) -#define DRM_ERR_NO_ACCESS (-1002) -#define DRM_ERR_NOT_ROOT (-1003) -#define DRM_ERR_INVALID (-1004) -#define DRM_ERR_NO_FD (-1005) - -#define DRM_AGP_NO_HANDLE 0 - -typedef unsigned long drmHandle, *drmHandlePtr; /* To mapped regions */ -typedef unsigned int drmSize, *drmSizePtr; /* For mapped regions */ -typedef void *drmAddress, **drmAddressPtr; /* For mapped regions */ -typedef unsigned int drmContext, *drmContextPtr; /* GLXContext handle */ -typedef unsigned int drmDrawable, *drmDrawablePtr; /* Unused */ -typedef unsigned int drmMagic, *drmMagicPtr; /* Magic for auth */ - -typedef struct _drmVersion { - int version_major; /* Major version */ - int version_minor; /* Minor version */ - int version_patchlevel; /* Patch level */ - int name_len; /* Length of name buffer */ - char *name; /* Name of driver */ - int date_len; /* Length of date buffer */ - char *date; /* User-space buffer to hold date */ - int desc_len; /* Length of desc buffer */ - char *desc; /* User-space buffer to hold desc */ -} drmVersion, *drmVersionPtr; - -typedef struct _drmStats { - unsigned long count; /* Number of data */ - struct { - unsigned long value; /* Value from kernel */ - const char *long_format; /* Suggested format for long_name */ - const char *long_name; /* Long name for value */ - const char *rate_format; /* Suggested format for rate_name */ - const char *rate_name; /* Short name for value per second */ - int isvalue; /* True if value (vs. counter) */ - const char *mult_names; /* Multiplier names (e.g., "KGM") */ - int mult; /* Multiplier value (e.g., 1024) */ - int verbose; /* Suggest only in verbose output */ - } data[15]; -} drmStatsT; - - - /* All of these enums *MUST* match with the - kernel implementation -- so do *NOT* - change them! (The drmlib implementation - will just copy the flags instead of - translating them.) */ -typedef enum { - DRM_FRAME_BUFFER = 0, /* WC, no caching, no core dump */ - DRM_REGISTERS = 1, /* no caching, no core dump */ - DRM_SHM = 2, /* shared, cached */ - DRM_AGP = 3, /* AGP/GART */ - DRM_SCATTER_GATHER = 4 /* PCI scatter/gather */ -} drmMapType; - -typedef enum { - DRM_RESTRICTED = 0x0001, /* Cannot be mapped to client-virtual */ - DRM_READ_ONLY = 0x0002, /* Read-only in client-virtual */ - DRM_LOCKED = 0x0004, /* Physical pages locked */ - DRM_KERNEL = 0x0008, /* Kernel requires access */ - DRM_WRITE_COMBINING = 0x0010, /* Use write-combining, if available */ - DRM_CONTAINS_LOCK = 0x0020, /* SHM page that contains lock */ - DRM_REMOVABLE = 0x0040 /* Removable mapping */ -} drmMapFlags; - -typedef enum { /* These values *MUST* match drm.h */ - /* Flags for DMA buffer dispatch */ - DRM_DMA_BLOCK = 0x01, /* Block until buffer dispatched. Note, - the buffer may not yet have been - processed by the hardware -- getting a - hardware lock with the hardware - quiescent will ensure that the buffer - has been processed. */ - DRM_DMA_WHILE_LOCKED = 0x02, /* Dispatch while lock held */ - DRM_DMA_PRIORITY = 0x04, /* High priority dispatch */ - - /* Flags for DMA buffer request */ - DRM_DMA_WAIT = 0x10, /* Wait for free buffers */ - DRM_DMA_SMALLER_OK = 0x20, /* Smaller-than-requested buffers ok */ - DRM_DMA_LARGER_OK = 0x40 /* Larger-than-requested buffers ok */ -} drmDMAFlags; - -typedef enum { - DRM_PAGE_ALIGN = 0x01, - DRM_AGP_BUFFER = 0x02, - DRM_SG_BUFFER = 0x04 -} drmBufDescFlags; - -typedef enum { - DRM_LOCK_READY = 0x01, /* Wait until hardware is ready for DMA */ - DRM_LOCK_QUIESCENT = 0x02, /* Wait until hardware quiescent */ - DRM_LOCK_FLUSH = 0x04, /* Flush this context's DMA queue first */ - DRM_LOCK_FLUSH_ALL = 0x08, /* Flush all DMA queues first */ - /* These *HALT* flags aren't supported yet - -- they will be used to support the - full-screen DGA-like mode. */ - DRM_HALT_ALL_QUEUES = 0x10, /* Halt all current and future queues */ - DRM_HALT_CUR_QUEUES = 0x20 /* Halt all current queues */ -} drmLockFlags; - -typedef enum { - DRM_CONTEXT_PRESERVED = 0x01, /* This context is preserved and - never swapped. */ - DRM_CONTEXT_2DONLY = 0x02 /* This context is for 2D rendering only. */ -} drmContextFlags, *drmContextFlagsPtr; - -typedef struct _drmBufDesc { - int count; /* Number of buffers of this size */ - int size; /* Size in bytes */ - int low_mark; /* Low water mark */ - int high_mark; /* High water mark */ -} drmBufDesc, *drmBufDescPtr; - -typedef struct _drmBufInfo { - int count; /* Number of buffers described in list */ - drmBufDescPtr list; /* List of buffer descriptions */ -} drmBufInfo, *drmBufInfoPtr; - -typedef struct _drmBuf { - int idx; /* Index into master buflist */ - int total; /* Buffer size */ - int used; /* Amount of buffer in use (for DMA) */ - drmAddress address; /* Address */ -} drmBuf, *drmBufPtr; - -typedef struct _drmBufMap { - int count; /* Number of buffers mapped */ - drmBufPtr list; /* Buffers */ -} drmBufMap, *drmBufMapPtr; - -typedef struct _drmLock { - volatile unsigned int lock; - char padding[60]; - /* This is big enough for most current (and future?) architectures: - DEC Alpha: 32 bytes - Intel Merced: ? - Intel P5/PPro/PII/PIII: 32 bytes - Intel StrongARM: 32 bytes - Intel i386/i486: 16 bytes - MIPS: 32 bytes (?) - Motorola 68k: 16 bytes - Motorola PowerPC: 32 bytes - Sun SPARC: 32 bytes - */ -} drmLock, *drmLockPtr; - -typedef struct _drmDMAReq { - /* Indices here refer to the offset into - list in drmBufInfo */ - drmContext context; /* Context handle */ - int send_count; /* Number of buffers to send */ - int *send_list; /* List of handles to buffers */ - int *send_sizes; /* Lengths of data to send, in bytes */ - drmDMAFlags flags; /* Flags */ - int request_count; /* Number of buffers requested */ - int request_size; /* Desired size of buffers requested */ - int *request_list; /* Buffer information */ - int *request_sizes; /* Minimum acceptable sizes */ - int granted_count; /* Number of buffers granted at this size */ -} drmDMAReq, *drmDMAReqPtr; - -typedef struct _drmRegion { - drmHandle handle; - unsigned int offset; - drmSize size; - drmAddress map; -} drmRegion, *drmRegionPtr; - -typedef struct _drmTextureRegion { - unsigned char next; - unsigned char prev; - unsigned char in_use; - unsigned char padding; /* Explicitly pad this out */ - unsigned int age; -} drmTextureRegion, *drmTextureRegionPtr; - - -typedef struct _drmClipRect { - unsigned short x1; /* Upper left: inclusive */ - unsigned short y1; - unsigned short x2; /* Lower right: exclusive */ - unsigned short y2; -} drmClipRect, *drmClipRectPtr; - - -typedef enum { - DRM_VBLANK_ABSOLUTE = 0x0, /* Wait for specific vblank sequence number */ - DRM_VBLANK_RELATIVE = 0x1, /* Wait for given number of vblanks */ - DRM_VBLANK_SIGNAL = 0x40000000 /* Send signal instead of blocking */ -} drmVBlankSeqType; - -typedef struct _drmVBlankReq { - drmVBlankSeqType type; - unsigned int sequence; - unsigned long signal; -} drmVBlankReq, *drmVBlankReqPtr; - -typedef struct _drmVBlankReply { - drmVBlankSeqType type; - unsigned int sequence; - long tval_sec; - long tval_usec; -} drmVBlankReply, *drmVBlankReplyPtr; - -typedef union _drmVBlank { - drmVBlankReq request; - drmVBlankReply reply; -} drmVBlank, *drmVBlankPtr; - - - -#define __drm_dummy_lock(lock) (*(__volatile__ unsigned int *)lock) - -#define DRM_LOCK_HELD 0x80000000 /* Hardware lock is held */ -#define DRM_LOCK_CONT 0x40000000 /* Hardware lock is contended */ - -#if defined(__GNUC__) && (__GNUC__ >= 2) -# if defined(__i386) || defined(__AMD64__) - /* Reflect changes here to drmP.h */ -#define DRM_CAS(lock,old,new,__ret) \ - do { \ - int __dummy; /* Can't mark eax as clobbered */ \ - __asm__ __volatile__( \ - "lock ; cmpxchg %4,%1\n\t" \ - "setnz %0" \ - : "=d" (__ret), \ - "=m" (__drm_dummy_lock(lock)), \ - "=a" (__dummy) \ - : "2" (old), \ - "r" (new)); \ - } while (0) - -#elif defined(__alpha__) - -#define DRM_CAS(lock, old, new, ret) \ - do { \ - int old32; \ - int cur32; \ - __asm__ __volatile__( \ - " mb\n" \ - " zap %4, 0xF0, %0\n" \ - " ldl_l %1, %2\n" \ - " zap %1, 0xF0, %1\n" \ - " cmpeq %0, %1, %1\n" \ - " beq %1, 1f\n" \ - " bis %5, %5, %1\n" \ - " stl_c %1, %2\n" \ - "1: xor %1, 1, %1\n" \ - " stl %1, %3" \ - : "+r" (old32), \ - "+&r" (cur32), \ - "=m" (__drm_dummy_lock(lock)),\ - "=m" (ret) \ - : "r" (old), \ - "r" (new)); \ - } while(0) - -#elif defined(__sparc__) - -#define DRM_CAS(lock,old,new,__ret) \ -do { register unsigned int __old __asm("o0"); \ - register unsigned int __new __asm("o1"); \ - register volatile unsigned int *__lock __asm("o2"); \ - __old = old; \ - __new = new; \ - __lock = (volatile unsigned int *)lock; \ - __asm__ __volatile__( \ - /*"cas [%2], %3, %0"*/ \ - ".word 0xd3e29008\n\t" \ - /*"membar #StoreStore | #StoreLoad"*/ \ - ".word 0x8143e00a" \ - : "=&r" (__new) \ - : "0" (__new), \ - "r" (__lock), \ - "r" (__old) \ - : "memory"); \ - __ret = (__new != __old); \ -} while(0) - -#elif defined(__ia64__) - -#if 0 -/* this currently generates bad code (missing stop bits)... */ -#include <ia64intrin.h> - -#define DRM_CAS(lock,old,new,__ret) \ - do { \ - __ret = (__sync_val_compare_and_swap(&__drm_dummy_lock(lock), \ - (old), (new)) \ - != (old)); \ - } while (0) - -#else -#define DRM_CAS(lock,old,new,__ret) \ - do { \ - unsigned int __result, __old = (old); \ - __asm__ __volatile__( \ - "mf\n" \ - "mov ar.ccv=%2\n" \ - ";;\n" \ - "cmpxchg4.acq %0=%1,%3,ar.ccv" \ - : "=r" (__result), "=m" (__drm_dummy_lock(lock)) \ - : "r" (__old), "r" (new) \ - : "memory"); \ - __ret = (__result) != (__old); \ - } while (0) - -#endif - -#elif defined(__powerpc__) - -#define DRM_CAS(lock,old,new,__ret) \ - do { \ - __asm__ __volatile__( \ - "sync;" \ - "0: lwarx %0,0,%1;" \ - " xor. %0,%3,%0;" \ - " bne 1f;" \ - " stwcx. %2,0,%1;" \ - " bne- 0b;" \ - "1: " \ - "sync;" \ - : "=&r"(__ret) \ - : "r"(lock), "r"(new), "r"(old) \ - : "cr0", "memory"); \ - } while (0) - -#endif /* architecture */ -#endif /* __GNUC__ >= 2 */ - -#ifndef DRM_CAS -#define DRM_CAS(lock,old,new,ret) do { ret=1; } while (0) /* FAST LOCK FAILS */ -#endif - -#if defined(__alpha__) || defined(__powerpc__) -#define DRM_CAS_RESULT(_result) int _result -#else -#define DRM_CAS_RESULT(_result) char _result -#endif - -#define DRM_LIGHT_LOCK(fd,lock,context) \ - do { \ - DRM_CAS_RESULT(__ret); \ - DRM_CAS(lock,context,DRM_LOCK_HELD|context,__ret); \ - if (__ret) drmGetLock(fd,context,0); \ - } while(0) - - /* This one counts fast locks -- for - benchmarking only. */ -#define DRM_LIGHT_LOCK_COUNT(fd,lock,context,count) \ - do { \ - DRM_CAS_RESULT(__ret); \ - DRM_CAS(lock,context,DRM_LOCK_HELD|context,__ret); \ - if (__ret) drmGetLock(fd,context,0); \ - else ++count; \ - } while(0) - -#define DRM_LOCK(fd,lock,context,flags) \ - do { \ - if (flags) drmGetLock(fd,context,flags); \ - else DRM_LIGHT_LOCK(fd,lock,context); \ - } while(0) - -#define DRM_UNLOCK(fd,lock,context) \ - do { \ - DRM_CAS_RESULT(__ret); \ - DRM_CAS(lock,DRM_LOCK_HELD|context,context,__ret); \ - if (__ret) drmUnlock(fd,context); \ - } while(0) - - /* Simple spin locks */ -#define DRM_SPINLOCK(spin,val) \ - do { \ - DRM_CAS_RESULT(__ret); \ - do { \ - DRM_CAS(spin,0,val,__ret); \ - if (__ret) while ((spin)->lock); \ - } while (__ret); \ - } while(0) - -#define DRM_SPINLOCK_TAKE(spin,val) \ - do { \ - DRM_CAS_RESULT(__ret); \ - int cur; \ - do { \ - cur = (*spin).lock; \ - DRM_CAS(spin,cur,val,__ret); \ - } while (__ret); \ - } while(0) - -#define DRM_SPINLOCK_COUNT(spin,val,count,__ret) \ - do { \ - int __i; \ - __ret = 1; \ - for (__i = 0; __ret && __i < count; __i++) { \ - DRM_CAS(spin,0,val,__ret); \ - if (__ret) for (;__i < count && (spin)->lock; __i++); \ - } \ - } while(0) - -#define DRM_SPINUNLOCK(spin,val) \ - do { \ - DRM_CAS_RESULT(__ret); \ - if ((*spin).lock == val) { /* else server stole lock */ \ - do { \ - DRM_CAS(spin,val,0,__ret); \ - } while (__ret); \ - } \ - } while(0) - -/* General user-level programmer's API: unprivileged */ -extern int drmAvailable(void); -extern int drmOpen(const char *name, const char *busid); -extern int drmClose(int fd); -extern drmVersionPtr drmGetVersion(int fd); -extern drmVersionPtr drmGetLibVersion(int fd); -extern void drmFreeVersion(drmVersionPtr); -extern int drmGetMagic(int fd, drmMagicPtr magic); -extern char *drmGetBusid(int fd); -extern int drmGetInterruptFromBusID(int fd, int busnum, int devnum, - int funcnum); -extern int drmGetMap(int fd, int idx, drmHandle *offset, - drmSize *size, drmMapType *type, - drmMapFlags *flags, drmHandle *handle, - int *mtrr); -extern int drmGetClient(int fd, int idx, int *auth, int *pid, - int *uid, unsigned long *magic, - unsigned long *iocs); -extern int drmGetStats(int fd, drmStatsT *stats); -extern int drmCommandNone(int fd, unsigned long drmCommandIndex); -extern int drmCommandRead(int fd, unsigned long drmCommandIndex, - void *data, unsigned long size); -extern int drmCommandWrite(int fd, unsigned long drmCommandIndex, - void *data, unsigned long size); -extern int drmCommandWriteRead(int fd, unsigned long drmCommandIndex, - void *data, unsigned long size); - -/* General user-level programmer's API: X server (root) only */ -extern void drmFreeBusid(const char *busid); -extern int drmSetBusid(int fd, const char *busid); -extern int drmAuthMagic(int fd, drmMagic magic); -extern int drmAddMap(int fd, - drmHandle offset, - drmSize size, - drmMapType type, - drmMapFlags flags, - drmHandlePtr handle); -extern int drmRmMap(int fd, drmHandle handle); -extern int drmAddContextPrivateMapping(int fd, drmContext ctx_id, - drmHandle handle); - -extern int drmAddBufs(int fd, int count, int size, - drmBufDescFlags flags, - int agp_offset); -extern int drmMarkBufs(int fd, double low, double high); -extern int drmCreateContext(int fd, drmContextPtr handle); -extern int drmSetContextFlags(int fd, drmContext context, - drmContextFlags flags); -extern int drmGetContextFlags(int fd, drmContext context, - drmContextFlagsPtr flags); -extern int drmAddContextTag(int fd, drmContext context, void *tag); -extern int drmDelContextTag(int fd, drmContext context); -extern void *drmGetContextTag(int fd, drmContext context); -extern drmContextPtr drmGetReservedContextList(int fd, int *count); -extern void drmFreeReservedContextList(drmContextPtr); -extern int drmSwitchToContext(int fd, drmContext context); -extern int drmDestroyContext(int fd, drmContext handle); -extern int drmCreateDrawable(int fd, drmDrawablePtr handle); -extern int drmDestroyDrawable(int fd, drmDrawable handle); -extern int drmCtlInstHandler(int fd, int irq); -extern int drmCtlUninstHandler(int fd); -extern int drmInstallSIGIOHandler(int fd, - void (*f)(int fd, - void *oldctx, - void *newctx)); -extern int drmRemoveSIGIOHandler(int fd); - -/* General user-level programmer's API: authenticated client and/or X */ -extern int drmMap(int fd, - drmHandle handle, - drmSize size, - drmAddressPtr address); -extern int drmUnmap(drmAddress address, drmSize size); -extern drmBufInfoPtr drmGetBufInfo(int fd); -extern drmBufMapPtr drmMapBufs(int fd); -extern int drmUnmapBufs(drmBufMapPtr bufs); -extern int drmDMA(int fd, drmDMAReqPtr request); -extern int drmFreeBufs(int fd, int count, int *list); -extern int drmGetLock(int fd, - drmContext context, - drmLockFlags flags); -extern int drmUnlock(int fd, drmContext context); -extern int drmFinish(int fd, int context, drmLockFlags flags); -extern int drmGetContextPrivateMapping(int fd, drmContext ctx_id, - drmHandlePtr handle); - -/* AGP/GART support: X server (root) only */ -extern int drmAgpAcquire(int fd); -extern int drmAgpRelease(int fd); -extern int drmAgpEnable(int fd, unsigned long mode); -extern int drmAgpAlloc(int fd, unsigned long size, - unsigned long type, unsigned long *address, - unsigned long *handle); -extern int drmAgpFree(int fd, unsigned long handle); -extern int drmAgpBind(int fd, unsigned long handle, - unsigned long offset); -extern int drmAgpUnbind(int fd, unsigned long handle); - -/* AGP/GART info: authenticated client and/or X */ -extern int drmAgpVersionMajor(int fd); -extern int drmAgpVersionMinor(int fd); -extern unsigned long drmAgpGetMode(int fd); -extern unsigned long drmAgpBase(int fd); /* Physical location */ -extern unsigned long drmAgpSize(int fd); /* Bytes */ -extern unsigned long drmAgpMemoryUsed(int fd); -extern unsigned long drmAgpMemoryAvail(int fd); -extern unsigned int drmAgpVendorId(int fd); -extern unsigned int drmAgpDeviceId(int fd); - -/* PCI scatter/gather support: X server (root) only */ -extern int drmScatterGatherAlloc(int fd, unsigned long size, - unsigned long *handle); -extern int drmScatterGatherFree(int fd, unsigned long handle); - -extern int drmWaitVBlank(int fd, drmVBlankPtr vbl); - -/* Support routines */ -extern int drmError(int err, const char *label); -extern void *drmMalloc(int size); -extern void drmFree(void *pt); - -/* Hash table routines */ -extern void *drmHashCreate(void); -extern int drmHashDestroy(void *t); -extern int drmHashLookup(void *t, unsigned long key, void **value); -extern int drmHashInsert(void *t, unsigned long key, void *value); -extern int drmHashDelete(void *t, unsigned long key); -extern int drmHashFirst(void *t, unsigned long *key, void **value); -extern int drmHashNext(void *t, unsigned long *key, void **value); - -/* PRNG routines */ -extern void *drmRandomCreate(unsigned long seed); -extern int drmRandomDestroy(void *state); -extern unsigned long drmRandom(void *state); -extern double drmRandomDouble(void *state); - -/* Skip list routines */ - -extern void *drmSLCreate(void); -extern int drmSLDestroy(void *l); -extern int drmSLLookup(void *l, unsigned long key, void **value); -extern int drmSLInsert(void *l, unsigned long key, void *value); -extern int drmSLDelete(void *l, unsigned long key); -extern int drmSLNext(void *l, unsigned long *key, void **value); -extern int drmSLFirst(void *l, unsigned long *key, void **value); -extern void drmSLDump(void *l); -extern int drmSLLookupNeighbors(void *l, unsigned long key, - unsigned long *prev_key, void **prev_value, - unsigned long *next_key, void **next_value); - -#endif |