diff options
Diffstat (limited to 'src/mesa/drivers')
-rw-r--r-- | src/mesa/drivers/dri/fb/fb_dri.c | 231 |
1 files changed, 111 insertions, 120 deletions
diff --git a/src/mesa/drivers/dri/fb/fb_dri.c b/src/mesa/drivers/dri/fb/fb_dri.c index afadb9bce0e..696bf9e2e15 100644 --- a/src/mesa/drivers/dri/fb/fb_dri.c +++ b/src/mesa/drivers/dri/fb/fb_dri.c @@ -65,12 +65,27 @@ typedef struct { __DRIdrawablePrivate *drawable; /* drawable bound to this ctx */ } dri; +} fbContext, *fbContextPtr; + +typedef struct { + GLframebuffer *mesa_framebuffer; void *currentBuffer; void *frontBuffer; void *backBuffer; int currentPitch; -} fbContext, *fbContextPtr; +} fbDrawable, *fbDrawablePtr; +typedef struct { + unsigned long hFrameBuffer; + int fbOrigin; + int fbSize; + int fbStride; + int fbWidth; + int fbHeight; + int bpp; + int drmFD; + drmAddress fbMap; +} fbDRI, *fbDRIPtr; #define FB_CONTEXT(ctx) ((fbContextPtr)(ctx->DriverCtx)) @@ -130,18 +145,19 @@ set_buffer( GLcontext *ctx, GLframebuffer *buffer, GLuint bufferBit ) { fbContextPtr fbdevctx = FB_CONTEXT(ctx); __DRIdrawablePrivate *dPriv = fbdevctx->dri.drawable; + fbDrawablePtr fbdrawable = (fbDrawablePtr)dPriv->driverPrivate; /* What a twisted mess of private structs */ - assert(buffer == dPriv->driverPrivate); + assert(buffer == fbdrawable->mesa_framebuffer); switch (bufferBit) { case DD_FRONT_LEFT_BIT: - fbdevctx->currentBuffer = fbdevctx->frontBuffer; + fbdrawable->currentBuffer = fbdrawable->frontBuffer; break; case DD_BACK_LEFT_BIT: - fbdevctx->currentBuffer = fbdevctx->backBuffer; + fbdrawable->currentBuffer = fbdrawable->backBuffer; break; default: /* This happens a lot if the client renders to the frontbuffer */ @@ -171,9 +187,10 @@ init_core_functions( struct dd_function_table *functions ) #define NAME(PREFIX) PREFIX##_B8G8R8 #define SPAN_VARS \ const fbContextPtr fbdevctx = FB_CONTEXT(ctx); \ - __DRIdrawablePrivate *dPriv = fbdevctx->dri.drawable; + __DRIdrawablePrivate *dPriv = fbdevctx->dri.drawable; \ + const fbDrawablePtr fbdrawable = (fbDrawablePtr)dPriv->driverPrivate; #define INIT_PIXEL_PTR(P, X, Y) \ - GLubyte *P = (GLubyte *)fbdevctx->currentBuffer + (Y) * fbdevctx->currentPitch + (X) * 3 + GLubyte *P = (GLubyte *)fbdrawable->currentBuffer + (Y) * fbdrawable->currentPitch + (X) * 3 #define INC_PIXEL_PTR(P) P += 3 #define STORE_RGB_PIXEL(P, X, Y, R, G, B) \ P[0] = B; P[1] = G; P[2] = R @@ -189,9 +206,10 @@ init_core_functions( struct dd_function_table *functions ) #define NAME(PREFIX) PREFIX##_B8G8R8A8 #define SPAN_VARS \ const fbContextPtr fbdevctx = FB_CONTEXT(ctx); \ - __DRIdrawablePrivate *dPriv = fbdevctx->dri.drawable; + __DRIdrawablePrivate *dPriv = fbdevctx->dri.drawable; \ + const fbDrawablePtr fbdrawable = (fbDrawablePtr)dPriv->driverPrivate; #define INIT_PIXEL_PTR(P, X, Y) \ - GLubyte *P = (GLubyte *)fbdevctx->currentBuffer + (Y) * fbdevctx->currentPitch + (X) * 4; + GLubyte *P = (GLubyte *)fbdrawable->currentBuffer + (Y) * fbdrawable->currentPitch + (X) * 4; #define INC_PIXEL_PTR(P) P += 4 #define STORE_RGB_PIXEL(P, X, Y, R, G, B) \ P[0] = B; P[1] = G; P[2] = R; P[3] = 255 @@ -207,9 +225,10 @@ init_core_functions( struct dd_function_table *functions ) #define NAME(PREFIX) PREFIX##_B5G6R5 #define SPAN_VARS \ const fbContextPtr fbdevctx = FB_CONTEXT(ctx); \ - __DRIdrawablePrivate *dPriv = fbdevctx->dri.drawable; + __DRIdrawablePrivate *dPriv = fbdevctx->dri.drawable; \ + const fbDrawablePtr fbdrawable = (fbDrawablePtr)dPriv->driverPrivate; #define INIT_PIXEL_PTR(P, X, Y) \ - GLushort *P = (GLushort *) ((char *)fbdevctx->currentBuffer + (Y) * fbdevctx->currentPitch + (X) * 2) + GLushort *P = (GLushort *) ((char *)fbdrawable->currentBuffer + (Y) * fbdrawable->currentPitch + (X) * 2) #define INC_PIXEL_PTR(P) P += 1 #define STORE_RGB_PIXEL(P, X, Y, R, G, B) \ *P = ( (((R) & 0xf8) << 8) | (((G) & 0xfc) << 3) | ((B) >> 3) ) @@ -228,9 +247,10 @@ init_core_functions( struct dd_function_table *functions ) #define NAME(PREFIX) PREFIX##_B5G5R5 #define SPAN_VARS \ const fbContextPtr fbdevctx = FB_CONTEXT(ctx); \ - __DRIdrawablePrivate *dPriv = fbdevctx->dri.drawable; + __DRIdrawablePrivate *dPriv = fbdevctx->dri.drawable; \ + const fbDrawablePtr fbdrawable = (fbDrawablePtr)dPriv->driverPrivate; #define INIT_PIXEL_PTR(P, X, Y) \ - GLushort *P = (GLushort *) ((char *)fbdevctx->currentBuffer + (Y) * fbdevctx->currentPitch + (X) * 2) + GLushort *P = (GLushort *) ((char *)fbdrawable->currentBuffer + (Y) * fbdrawable->currentPitch + (X) * 2) #define INC_PIXEL_PTR(P) P += 1 #define STORE_RGB_PIXEL(P, X, Y, R, G, B) \ *P = ( (((R) & 0xf8) << 7) | (((G) & 0xf8) << 2) | ((B) >> 3) ) @@ -249,9 +269,10 @@ init_core_functions( struct dd_function_table *functions ) #define NAME(PREFIX) PREFIX##_CI8 #define SPAN_VARS \ const fbContextPtr fbdevctx = FB_CONTEXT(ctx); \ - __DRIdrawablePrivate *dPriv = fbdevctx->dri.drawable; + __DRIdrawablePrivate *dPriv = fbdevctx->dri.drawable; \ + const fbDrawablePtr fbdrawable = (fbDrawablePtr)dPriv->driverPrivate; #define INIT_PIXEL_PTR(P, X, Y) \ - GLubyte *P = (GLubyte *)fbdevctx->currentBuffer + (Y) * fbdevctx->currentPitch + (X) + GLubyte *P = (GLubyte *)fbdrawable->currentBuffer + (Y) * fbdrawable->currentPitch + (X) #define INC_PIXEL_PTR(P) P += 1 #define STORE_CI_PIXEL(P, CI) \ P[0] = CI @@ -261,19 +282,46 @@ init_core_functions( struct dd_function_table *functions ) #include "swrast/s_spantemp.h" - /* Initialize the driver specific screen private data. */ static GLboolean fbInitDriver( __DRIscreenPrivate *sPriv ) { - sPriv->private = NULL; + fbDRIPtr dri_priv = (fbDRIPtr)sPriv->pDevPriv; + fbDRIPtr priv; + int drmFD; + + drmFD = drmOpen("radeon", NULL ); + if (drmFD < 0) { + fprintf(stderr, "[drm] drmOpen failed\n"); + return GL_FALSE; + } + + priv = _mesa_malloc(sizeof(*priv)); + if (!priv) + return GL_FALSE; + + *priv = *dri_priv; + + priv->drmFD = drmFD; + if (drmMap(drmFD, priv->hFrameBuffer, priv->fbSize, &priv->fbMap) < 0) { + fprintf(stderr, "[drm] drmMap framebuffer failed\n"); + free(priv); + return GL_FALSE; + } + + sPriv->private = priv; return GL_TRUE; } static void fbDestroyScreen( __DRIscreenPrivate *sPriv ) { + fbDRIPtr priv = (fbDRIPtr)sPriv->private; + + drmUnmap(priv->fbMap, priv->fbSize); + drmClose(priv->drmFD); + _mesa_free(priv); } /* Create the device specific context. @@ -434,7 +482,8 @@ fbCreateBuffer( __DRIscreenPrivate *driScrnPriv, const __GLcontextModes *mesaVis, GLboolean isPixmap ) { - fbContextPtr fbmesa = (fbContextPtr) driDrawPriv->driContextPriv->driverPrivate; + fbDRIPtr spriv = (fbDRIPtr)driScrnPriv->private; + fbDrawablePtr fbdrawable; if (isPixmap) { return GL_FALSE; /* not implemented */ @@ -444,21 +493,31 @@ fbCreateBuffer( __DRIscreenPrivate *driScrnPriv, const GLboolean swAlpha = mesaVis->alphaBits > 0; const GLboolean swAccum = mesaVis->accumRedBits > 0; const GLboolean swStencil = mesaVis->stencilBits > 0; - driDrawPriv->driverPrivate = (void *) + + fbdrawable = _mesa_calloc(sizeof(*fbdrawable)); + if (!fbdrawable) + return 0; + + fbdrawable->mesa_framebuffer = (void *) _mesa_create_framebuffer( mesaVis, swDepth, swStencil, swAccum, swAlpha ); - if (!driDrawPriv->driverPrivate) - return 0; + if (!fbdrawable->mesa_framebuffer) { + _mesa_free(fbdrawable); + return 0; + } + driDrawPriv->driverPrivate = fbdrawable; + + fbdrawable->frontBuffer = fbdrawable->currentBuffer = spriv->fbMap; + fbdrawable->currentPitch = spriv->fbWidth; /* Replace the framebuffer back buffer with a malloc'ed one -- * big speedup. */ - if (fbmesa->backBuffer) - fbmesa->backBuffer = _mesa_malloc(fbmesa->currentPitch * driDrawPriv->h); + fbdrawable->backBuffer = _mesa_malloc(fbdrawable->currentPitch * driDrawPriv->h); return 1; } @@ -468,10 +527,12 @@ fbCreateBuffer( __DRIscreenPrivate *driScrnPriv, static void fbDestroyBuffer(__DRIdrawablePrivate *driDrawPriv) { - fbContextPtr fbmesa = (fbContextPtr) driDrawPriv->driContextPriv->driverPrivate; + fbDrawablePtr fbdrawable = (fbDrawablePtr)driDrawPriv->driverPrivate; - _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate)); - _mesa_free(fbmesa->backBuffer); + _mesa_destroy_framebuffer(fbdrawable->mesa_framebuffer); + _mesa_free(fbdrawable->backBuffer); + _mesa_free(fbdrawable); + driDrawPriv->driverPrivate = NULL; } @@ -481,6 +542,7 @@ fbDestroyBuffer(__DRIdrawablePrivate *driDrawPriv) static void fbSwapBuffers( __DRIdrawablePrivate *dPriv ) { + fbDrawablePtr fbdrawable = (fbDrawablePtr)dPriv->driverPrivate; if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { fbContextPtr fbmesa; @@ -490,19 +552,19 @@ fbSwapBuffers( __DRIdrawablePrivate *dPriv ) if (ctx->Visual.doubleBufferMode) { int i; int offset = 0; - char *tmp = _mesa_malloc(fbmesa->currentPitch); + char *tmp = _mesa_malloc(fbdrawable->currentPitch); _mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */ - ASSERT(fbmesa->frontBuffer); - ASSERT(fbmesa->backBuffer); + ASSERT(fbdrawable->frontBuffer); + ASSERT(fbdrawable->backBuffer); for (i = 0; i < dPriv->h; i++) { - _mesa_memcpy(tmp, (char *) fbmesa->backBuffer + offset, - fbmesa->currentPitch); - _mesa_memcpy((char *) fbmesa->frontBuffer + offset, tmp, - fbmesa->currentPitch); - offset += fbmesa->currentPitch; + _mesa_memcpy(tmp, (char *) fbdrawable->backBuffer + offset, + fbdrawable->currentPitch); + _mesa_memcpy((char *) fbdrawable->frontBuffer + offset, tmp, + fbdrawable->currentPitch); + offset += fbdrawable->currentPitch; } _mesa_free(tmp); @@ -530,8 +592,8 @@ fbMakeCurrent( __DRIcontextPrivate *driContextPriv, newFbCtx->dri.drawable = driDrawPriv; _mesa_make_current2( newFbCtx->glCtx, - (GLframebuffer *) driDrawPriv->driverPrivate, - (GLframebuffer *) driReadPriv->driverPrivate ); + ((fbDrawablePtr)driDrawPriv->driverPrivate)->mesa_framebuffer, + ((fbDrawablePtr)driReadPriv->driverPrivate)->mesa_framebuffer); } else { _mesa_make_current( 0, 0 ); } @@ -562,69 +624,6 @@ static struct __DriverAPIRec fbAPI = { -#ifndef DRI_NEW_INTERFACE_ONLY -/* - * This is the bootstrap function for the driver. - * The __driCreateScreen name is the symbol that libGL.so fetches. - * Return: pointer to a __DRIscreenPrivate. - */ -void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc, - int numConfigs, __GLXvisualConfig *config) -{ - __DRIscreenPrivate *psp; - psp = __driUtilCreateScreenNoDRM(dpy, scrn, psc, numConfigs, config, &fbAPI); - return (void *) psp; -} -#endif /* DRI_NEW_INTERFACE_ONLY */ - -/** - * \brief Establish the set of modes available for the display. - * - * \param ctx display handle. - * \param numModes will receive the number of supported modes. - * \param modes will point to the list of supported modes. - * - * \return one on success, or zero on failure. - * - * Allocates a single visual and fills it with information according to the - * display bit depth. Supports only 16 and 32 bpp bit depths, aborting - * otherwise. - */ -const __GLcontextModes __glModes[] = { - - /* 32 bit, RGBA Depth=24 Stencil=8 */ - {.rgbMode = GL_TRUE, .colorIndexMode = GL_FALSE, .doubleBufferMode = GL_TRUE, .stereoMode = GL_FALSE, - .haveAccumBuffer = GL_FALSE, .haveDepthBuffer = GL_TRUE, .haveStencilBuffer = GL_TRUE, - .redBits = 8, .greenBits = 8, .blueBits = 8, .alphaBits = 8, - .redMask = 0xff0000, .greenMask = 0xff00, .blueMask = 0xff, .alphaMask = 0xff000000, - .rgbBits = 32, .indexBits = 0, - .accumRedBits = 0, .accumGreenBits = 0, .accumBlueBits = 0, .accumAlphaBits = 0, - .depthBits = 24, .stencilBits = 8, - .numAuxBuffers= 0, .level = 0, .pixmapMode = GL_FALSE, }, - - /* 16 bit, RGB Depth=16 */ - {.rgbMode = GL_TRUE, .colorIndexMode = GL_FALSE, .doubleBufferMode = GL_TRUE, .stereoMode = GL_FALSE, - .haveAccumBuffer = GL_FALSE, .haveDepthBuffer = GL_TRUE, .haveStencilBuffer = GL_FALSE, - .redBits = 5, .greenBits = 6, .blueBits = 5, .alphaBits = 0, - .redMask = 0xf800, .greenMask = 0x07e0, .blueMask = 0x001f, .alphaMask = 0x0, - .rgbBits = 16, .indexBits = 0, - .accumRedBits = 0, .accumGreenBits = 0, .accumBlueBits = 0, .accumAlphaBits = 0, - .depthBits = 16, .stencilBits = 0, - .numAuxBuffers= 0, .level = 0, .pixmapMode = GL_FALSE, }, -}; - - -static int -__driInitScreenModes( const DRIDriverContext *ctx, - int *numModes, const __GLcontextModes **modes) -{ - *numModes = sizeof(__glModes)/sizeof(__GLcontextModes *); - *modes = &__glModes[0]; - return 1; -} - - - static int __driValidateMode(const DRIDriverContext *ctx ) { @@ -634,6 +633,8 @@ __driValidateMode(const DRIDriverContext *ctx ) static int __driInitFBDev( struct DRIDriverContextRec *ctx ) { + fbDRIPtr pfbDRI; + /* Note that drmOpen will try to load the kernel module, if needed. */ /* we need a fbdev drm driver - it will only track maps */ ctx->drmFD = drmOpen("radeon", NULL ); @@ -689,28 +690,18 @@ __driInitFBDev( struct DRIDriverContextRec *ctx ) fprintf(stderr, "[drm] framebuffer handle = 0x%08lx\n", ctx->shared.hFrameBuffer); -#if 0 - int id; - ctx->shared.hFrameBuffer = ctx->FBStart; - ctx->shared.fbSize = ctx->FBSize; - ctx->shared.hSAREA = 0xB37D; - ctx->shared.SAREASize = SAREA_MAX; - id = shmget(ctx->shared.hSAREA, ctx->shared.SAREASize, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR); - if (id == -1) { - /* segment will already exist if previous server segfaulted */ - id = shmget(ctx->shared.hSAREA, ctx->shared.SAREASize, 0); - if (id == -1) { - fprintf(stderr, "fb: shmget failed\n"); - return 0; - } - } - ctx->pSAREA = shmat(id, NULL, 0); - if (ctx->pSAREA == (void *)-1) { - fprintf(stderr, "fb: shmat failed\n"); - return 0; - } - memset(ctx->pSAREA, 0, SAREA_MAX); -#endif + pfbDRI = (fbDRIPtr)malloc(sizeof(*pfbDRI)); + pfbDRI->hFrameBuffer = ctx->shared.hFrameBuffer; + pfbDRI->fbOrigin = ctx->shared.fbOrigin; + pfbDRI->fbSize = ctx->shared.fbSize; + pfbDRI->fbStride = ctx->shared.fbStride; + pfbDRI->fbWidth = ctx->shared.virtualWidth; + pfbDRI->fbHeight = ctx->shared.virtualHeight; + pfbDRI->bpp = ctx->bpp; + + ctx->driverClientMsg = pfbDRI; + ctx->driverClientMsgSize = sizeof(*pfbDRI); + return 1; } |