diff options
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 45bf6dd158..009deb34ea 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 71f9a1acbf..0000000000 --- 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 2c3016f1e2..0000000000 --- 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 638bfa9524..0000000000 --- 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 <kevin@precisioninsight.com> - * \author Brian Paul <brian@precisioninsight.com> - */ - -/* - * 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 f9cad3994e..0000000000 --- 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 7e78a020dd..31bd9cc034 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 a32429a677..ce0eafe17e 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 319fc530fa..daa61ca73b 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 bbb02e4032..0000000000 --- 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 <faith@valinux.com> - * \author Kevin E. Martin <martin@valinux.com> - */ - -/* - * 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 cee5ca5f69..0000000000 --- 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 faith@precisioninsight.com - * - * 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 <faith@valinux.com> - * - * $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 |