105b261ecSmrg/* 235c4bbdfSmrg * Copyright © 2006 Intel Corporation 305b261ecSmrg * 405b261ecSmrg * Permission is hereby granted, free of charge, to any person obtaining a 505b261ecSmrg * copy of this software and associated documentation files (the "Software"), 605b261ecSmrg * to deal in the Software without restriction, including without limitation 705b261ecSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 805b261ecSmrg * and/or sell copies of the Software, and to permit persons to whom the 905b261ecSmrg * Software is furnished to do so, subject to the following conditions: 1005b261ecSmrg * 1105b261ecSmrg * The above copyright notice and this permission notice (including the next 1205b261ecSmrg * paragraph) shall be included in all copies or substantial portions of the 1305b261ecSmrg * Software. 1405b261ecSmrg * 1505b261ecSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1605b261ecSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1705b261ecSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1805b261ecSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1905b261ecSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 2005b261ecSmrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 2105b261ecSmrg * SOFTWARE. 2205b261ecSmrg * 2305b261ecSmrg * Authors: 2405b261ecSmrg * Eric Anholt <eric@anholt.net> 2505b261ecSmrg * 2605b261ecSmrg */ 2705b261ecSmrg 281b5d61b8Smrg#ifdef HAVE_DIX_CONFIG_H 291b5d61b8Smrg#include <dix-config.h> 3005b261ecSmrg#endif 3105b261ecSmrg 3205b261ecSmrg#include "ephyr.h" 3305b261ecSmrg#include "exa_priv.h" 3405b261ecSmrg#include "fbpict.h" 3505b261ecSmrg 3605b261ecSmrg#define EPHYR_TRACE_DRAW 0 3705b261ecSmrg 3805b261ecSmrg#if EPHYR_TRACE_DRAW 3905b261ecSmrg#define TRACE_DRAW() ErrorF("%s\n", __FUNCTION__); 4005b261ecSmrg#else 4105b261ecSmrg#define TRACE_DRAW() do { } while (0) 4205b261ecSmrg#endif 4305b261ecSmrg 4405b261ecSmrg/* Use some oddball alignments, to expose issues in alignment handling in EXA. */ 4505b261ecSmrg#define EPHYR_OFFSET_ALIGN 24 4605b261ecSmrg#define EPHYR_PITCH_ALIGN 24 4705b261ecSmrg 4805b261ecSmrg#define EPHYR_OFFSCREEN_SIZE (16 * 1024 * 1024) 4905b261ecSmrg#define EPHYR_OFFSCREEN_BASE (1 * 1024 * 1024) 5005b261ecSmrg 5105b261ecSmrg/** 5205b261ecSmrg * Forces a real devPrivate.ptr for hidden pixmaps, so that we can call down to 5305b261ecSmrg * fb functions. 5405b261ecSmrg */ 5505b261ecSmrgstatic void 5605b261ecSmrgephyrPreparePipelinedAccess(PixmapPtr pPix, int index) 5705b261ecSmrg{ 5805b261ecSmrg KdScreenPriv(pPix->drawable.pScreen); 5905b261ecSmrg KdScreenInfo *screen = pScreenPriv->screen; 6005b261ecSmrg EphyrScrPriv *scrpriv = screen->driver; 6105b261ecSmrg EphyrFakexaPriv *fakexa = scrpriv->fakexa; 6205b261ecSmrg 6305b261ecSmrg assert(fakexa->saved_ptrs[index] == NULL); 6405b261ecSmrg fakexa->saved_ptrs[index] = pPix->devPrivate.ptr; 6505b261ecSmrg 6605b261ecSmrg if (pPix->devPrivate.ptr != NULL) 6735c4bbdfSmrg return; 6805b261ecSmrg 6905b261ecSmrg pPix->devPrivate.ptr = fakexa->exa->memoryBase + exaGetPixmapOffset(pPix); 7005b261ecSmrg} 7105b261ecSmrg 7205b261ecSmrg/** 7305b261ecSmrg * Restores the original devPrivate.ptr of the pixmap from before we messed with 7405b261ecSmrg * it. 7505b261ecSmrg */ 7605b261ecSmrgstatic void 7705b261ecSmrgephyrFinishPipelinedAccess(PixmapPtr pPix, int index) 7805b261ecSmrg{ 7905b261ecSmrg KdScreenPriv(pPix->drawable.pScreen); 8005b261ecSmrg KdScreenInfo *screen = pScreenPriv->screen; 8105b261ecSmrg EphyrScrPriv *scrpriv = screen->driver; 8205b261ecSmrg EphyrFakexaPriv *fakexa = scrpriv->fakexa; 8305b261ecSmrg 8405b261ecSmrg pPix->devPrivate.ptr = fakexa->saved_ptrs[index]; 8505b261ecSmrg fakexa->saved_ptrs[index] = NULL; 8605b261ecSmrg} 8705b261ecSmrg 8805b261ecSmrg/** 8905b261ecSmrg * Sets up a scratch GC for fbFill, and saves other parameters for the 9005b261ecSmrg * ephyrSolid implementation. 9105b261ecSmrg */ 9205b261ecSmrgstatic Bool 9305b261ecSmrgephyrPrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg) 9405b261ecSmrg{ 9505b261ecSmrg ScreenPtr pScreen = pPix->drawable.pScreen; 9635c4bbdfSmrg 9705b261ecSmrg KdScreenPriv(pScreen); 9805b261ecSmrg KdScreenInfo *screen = pScreenPriv->screen; 9905b261ecSmrg EphyrScrPriv *scrpriv = screen->driver; 10005b261ecSmrg EphyrFakexaPriv *fakexa = scrpriv->fakexa; 1016747b715Smrg ChangeGCVal tmpval[3]; 10205b261ecSmrg 10305b261ecSmrg ephyrPreparePipelinedAccess(pPix, EXA_PREPARE_DEST); 10405b261ecSmrg 10505b261ecSmrg fakexa->pDst = pPix; 10605b261ecSmrg fakexa->pGC = GetScratchGC(pPix->drawable.depth, pScreen); 10705b261ecSmrg 1086747b715Smrg tmpval[0].val = alu; 1096747b715Smrg tmpval[1].val = pm; 1106747b715Smrg tmpval[2].val = fg; 11135c4bbdfSmrg ChangeGC(NullClient, fakexa->pGC, GCFunction | GCPlaneMask | GCForeground, 11235c4bbdfSmrg tmpval); 11305b261ecSmrg 11405b261ecSmrg ValidateGC(&pPix->drawable, fakexa->pGC); 11505b261ecSmrg 11605b261ecSmrg TRACE_DRAW(); 11705b261ecSmrg 11805b261ecSmrg return TRUE; 11905b261ecSmrg} 12005b261ecSmrg 12105b261ecSmrg/** 12205b261ecSmrg * Does an fbFill of the rectangle to be drawn. 12305b261ecSmrg */ 12405b261ecSmrgstatic void 12505b261ecSmrgephyrSolid(PixmapPtr pPix, int x1, int y1, int x2, int y2) 12605b261ecSmrg{ 12705b261ecSmrg ScreenPtr pScreen = pPix->drawable.pScreen; 12835c4bbdfSmrg 12905b261ecSmrg KdScreenPriv(pScreen); 13005b261ecSmrg KdScreenInfo *screen = pScreenPriv->screen; 13105b261ecSmrg EphyrScrPriv *scrpriv = screen->driver; 13205b261ecSmrg EphyrFakexaPriv *fakexa = scrpriv->fakexa; 13305b261ecSmrg 13405b261ecSmrg fbFill(&fakexa->pDst->drawable, fakexa->pGC, x1, y1, x2 - x1, y2 - y1); 13505b261ecSmrg} 13605b261ecSmrg 13705b261ecSmrg/** 13805b261ecSmrg * Cleans up the scratch GC created in ephyrPrepareSolid. 13905b261ecSmrg */ 14005b261ecSmrgstatic void 14105b261ecSmrgephyrDoneSolid(PixmapPtr pPix) 14205b261ecSmrg{ 14305b261ecSmrg ScreenPtr pScreen = pPix->drawable.pScreen; 14435c4bbdfSmrg 14505b261ecSmrg KdScreenPriv(pScreen); 14605b261ecSmrg KdScreenInfo *screen = pScreenPriv->screen; 14705b261ecSmrg EphyrScrPriv *scrpriv = screen->driver; 14805b261ecSmrg EphyrFakexaPriv *fakexa = scrpriv->fakexa; 14905b261ecSmrg 15005b261ecSmrg FreeScratchGC(fakexa->pGC); 15105b261ecSmrg 15205b261ecSmrg ephyrFinishPipelinedAccess(pPix, EXA_PREPARE_DEST); 15305b261ecSmrg} 15405b261ecSmrg 15505b261ecSmrg/** 15605b261ecSmrg * Sets up a scratch GC for fbCopyArea, and saves other parameters for the 15705b261ecSmrg * ephyrCopy implementation. 15805b261ecSmrg */ 15905b261ecSmrgstatic Bool 16005b261ecSmrgephyrPrepareCopy(PixmapPtr pSrc, PixmapPtr pDst, int dx, int dy, int alu, 16135c4bbdfSmrg Pixel pm) 16205b261ecSmrg{ 16305b261ecSmrg ScreenPtr pScreen = pDst->drawable.pScreen; 16435c4bbdfSmrg 16505b261ecSmrg KdScreenPriv(pScreen); 16605b261ecSmrg KdScreenInfo *screen = pScreenPriv->screen; 16705b261ecSmrg EphyrScrPriv *scrpriv = screen->driver; 16805b261ecSmrg EphyrFakexaPriv *fakexa = scrpriv->fakexa; 1696747b715Smrg ChangeGCVal tmpval[2]; 17005b261ecSmrg 17105b261ecSmrg ephyrPreparePipelinedAccess(pDst, EXA_PREPARE_DEST); 17205b261ecSmrg ephyrPreparePipelinedAccess(pSrc, EXA_PREPARE_SRC); 17305b261ecSmrg 17405b261ecSmrg fakexa->pSrc = pSrc; 17505b261ecSmrg fakexa->pDst = pDst; 17605b261ecSmrg fakexa->pGC = GetScratchGC(pDst->drawable.depth, pScreen); 17705b261ecSmrg 1786747b715Smrg tmpval[0].val = alu; 1796747b715Smrg tmpval[1].val = pm; 18035c4bbdfSmrg ChangeGC(NullClient, fakexa->pGC, GCFunction | GCPlaneMask, tmpval); 18105b261ecSmrg 18205b261ecSmrg ValidateGC(&pDst->drawable, fakexa->pGC); 18305b261ecSmrg 18405b261ecSmrg TRACE_DRAW(); 18505b261ecSmrg 18605b261ecSmrg return TRUE; 18705b261ecSmrg} 18805b261ecSmrg 18905b261ecSmrg/** 19005b261ecSmrg * Does an fbCopyArea to take care of the requested copy. 19105b261ecSmrg */ 19205b261ecSmrgstatic void 19305b261ecSmrgephyrCopy(PixmapPtr pDst, int srcX, int srcY, int dstX, int dstY, int w, int h) 19405b261ecSmrg{ 19505b261ecSmrg ScreenPtr pScreen = pDst->drawable.pScreen; 19635c4bbdfSmrg 19705b261ecSmrg KdScreenPriv(pScreen); 19805b261ecSmrg KdScreenInfo *screen = pScreenPriv->screen; 19905b261ecSmrg EphyrScrPriv *scrpriv = screen->driver; 20005b261ecSmrg EphyrFakexaPriv *fakexa = scrpriv->fakexa; 20105b261ecSmrg 20205b261ecSmrg fbCopyArea(&fakexa->pSrc->drawable, &fakexa->pDst->drawable, fakexa->pGC, 20335c4bbdfSmrg srcX, srcY, w, h, dstX, dstY); 20405b261ecSmrg} 20505b261ecSmrg 20605b261ecSmrg/** 20705b261ecSmrg * Cleans up the scratch GC created in ephyrPrepareCopy. 20805b261ecSmrg */ 20905b261ecSmrgstatic void 21005b261ecSmrgephyrDoneCopy(PixmapPtr pDst) 21105b261ecSmrg{ 21205b261ecSmrg ScreenPtr pScreen = pDst->drawable.pScreen; 21335c4bbdfSmrg 21405b261ecSmrg KdScreenPriv(pScreen); 21505b261ecSmrg KdScreenInfo *screen = pScreenPriv->screen; 21605b261ecSmrg EphyrScrPriv *scrpriv = screen->driver; 21705b261ecSmrg EphyrFakexaPriv *fakexa = scrpriv->fakexa; 21805b261ecSmrg 21935c4bbdfSmrg FreeScratchGC(fakexa->pGC); 22005b261ecSmrg 22105b261ecSmrg ephyrFinishPipelinedAccess(fakexa->pSrc, EXA_PREPARE_SRC); 22205b261ecSmrg ephyrFinishPipelinedAccess(fakexa->pDst, EXA_PREPARE_DEST); 22305b261ecSmrg} 22405b261ecSmrg 22505b261ecSmrg/** 22605b261ecSmrg * Reports that we can always accelerate the given operation. This may not be 22705b261ecSmrg * desirable from an EXA testing standpoint -- testing the fallback paths would 22805b261ecSmrg * be useful, too. 22905b261ecSmrg */ 23005b261ecSmrgstatic Bool 23105b261ecSmrgephyrCheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, 23235c4bbdfSmrg PicturePtr pDstPicture) 23305b261ecSmrg{ 23405b261ecSmrg /* Exercise the component alpha helper, so fail on this case like a normal 23505b261ecSmrg * driver 23605b261ecSmrg */ 23705b261ecSmrg if (pMaskPicture && pMaskPicture->componentAlpha && op == PictOpOver) 23835c4bbdfSmrg return FALSE; 23905b261ecSmrg 24005b261ecSmrg return TRUE; 24105b261ecSmrg} 24205b261ecSmrg 24305b261ecSmrg/** 24405b261ecSmrg * Saves off the parameters for ephyrComposite. 24505b261ecSmrg */ 24605b261ecSmrgstatic Bool 24705b261ecSmrgephyrPrepareComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, 24835c4bbdfSmrg PicturePtr pDstPicture, PixmapPtr pSrc, PixmapPtr pMask, 24935c4bbdfSmrg PixmapPtr pDst) 25005b261ecSmrg{ 25105b261ecSmrg KdScreenPriv(pDst->drawable.pScreen); 25205b261ecSmrg KdScreenInfo *screen = pScreenPriv->screen; 25305b261ecSmrg EphyrScrPriv *scrpriv = screen->driver; 25405b261ecSmrg EphyrFakexaPriv *fakexa = scrpriv->fakexa; 25505b261ecSmrg 25605b261ecSmrg ephyrPreparePipelinedAccess(pDst, EXA_PREPARE_DEST); 2571b5d61b8Smrg if (pSrc != NULL) 2581b5d61b8Smrg ephyrPreparePipelinedAccess(pSrc, EXA_PREPARE_SRC); 25905b261ecSmrg if (pMask != NULL) 26035c4bbdfSmrg ephyrPreparePipelinedAccess(pMask, EXA_PREPARE_MASK); 26105b261ecSmrg 26205b261ecSmrg fakexa->op = op; 26305b261ecSmrg fakexa->pSrcPicture = pSrcPicture; 26405b261ecSmrg fakexa->pMaskPicture = pMaskPicture; 26505b261ecSmrg fakexa->pDstPicture = pDstPicture; 26605b261ecSmrg fakexa->pSrc = pSrc; 26705b261ecSmrg fakexa->pMask = pMask; 26805b261ecSmrg fakexa->pDst = pDst; 26905b261ecSmrg 27005b261ecSmrg TRACE_DRAW(); 27105b261ecSmrg 27205b261ecSmrg return TRUE; 27305b261ecSmrg} 27405b261ecSmrg 27505b261ecSmrg/** 27605b261ecSmrg * Does an fbComposite to complete the requested drawing operation. 27705b261ecSmrg */ 27805b261ecSmrgstatic void 27905b261ecSmrgephyrComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, 28035c4bbdfSmrg int dstX, int dstY, int w, int h) 28105b261ecSmrg{ 28205b261ecSmrg KdScreenPriv(pDst->drawable.pScreen); 28305b261ecSmrg KdScreenInfo *screen = pScreenPriv->screen; 28405b261ecSmrg EphyrScrPriv *scrpriv = screen->driver; 28505b261ecSmrg EphyrFakexaPriv *fakexa = scrpriv->fakexa; 28605b261ecSmrg 28705b261ecSmrg fbComposite(fakexa->op, fakexa->pSrcPicture, fakexa->pMaskPicture, 28835c4bbdfSmrg fakexa->pDstPicture, srcX, srcY, maskX, maskY, dstX, dstY, 28935c4bbdfSmrg w, h); 29005b261ecSmrg} 29105b261ecSmrg 29205b261ecSmrgstatic void 29305b261ecSmrgephyrDoneComposite(PixmapPtr pDst) 29405b261ecSmrg{ 29505b261ecSmrg KdScreenPriv(pDst->drawable.pScreen); 29605b261ecSmrg KdScreenInfo *screen = pScreenPriv->screen; 29705b261ecSmrg EphyrScrPriv *scrpriv = screen->driver; 29805b261ecSmrg EphyrFakexaPriv *fakexa = scrpriv->fakexa; 29905b261ecSmrg 30005b261ecSmrg if (fakexa->pMask != NULL) 30135c4bbdfSmrg ephyrFinishPipelinedAccess(fakexa->pMask, EXA_PREPARE_MASK); 3021b5d61b8Smrg if (fakexa->pSrc != NULL) 3031b5d61b8Smrg ephyrFinishPipelinedAccess(fakexa->pSrc, EXA_PREPARE_SRC); 30405b261ecSmrg ephyrFinishPipelinedAccess(fakexa->pDst, EXA_PREPARE_DEST); 30505b261ecSmrg} 30605b261ecSmrg 30705b261ecSmrg/** 30805b261ecSmrg * Does fake acceleration of DownloadFromScren using memcpy. 30905b261ecSmrg */ 31005b261ecSmrgstatic Bool 31105b261ecSmrgephyrDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, char *dst, 31235c4bbdfSmrg int dst_pitch) 31305b261ecSmrg{ 31405b261ecSmrg KdScreenPriv(pSrc->drawable.pScreen); 31505b261ecSmrg KdScreenInfo *screen = pScreenPriv->screen; 31605b261ecSmrg EphyrScrPriv *scrpriv = screen->driver; 31705b261ecSmrg EphyrFakexaPriv *fakexa = scrpriv->fakexa; 3184642e01fSmrg unsigned char *src; 31905b261ecSmrg int src_pitch, cpp; 32005b261ecSmrg 32105b261ecSmrg if (pSrc->drawable.bitsPerPixel < 8) 32235c4bbdfSmrg return FALSE; 32305b261ecSmrg 32405b261ecSmrg ephyrPreparePipelinedAccess(pSrc, EXA_PREPARE_SRC); 32505b261ecSmrg 32605b261ecSmrg cpp = pSrc->drawable.bitsPerPixel / 8; 32705b261ecSmrg src_pitch = exaGetPixmapPitch(pSrc); 32805b261ecSmrg src = fakexa->exa->memoryBase + exaGetPixmapOffset(pSrc); 32905b261ecSmrg src += y * src_pitch + x * cpp; 33005b261ecSmrg 33105b261ecSmrg for (; h > 0; h--) { 33235c4bbdfSmrg memcpy(dst, src, w * cpp); 33335c4bbdfSmrg dst += dst_pitch; 33435c4bbdfSmrg src += src_pitch; 33505b261ecSmrg } 33605b261ecSmrg 33705b261ecSmrg exaMarkSync(pSrc->drawable.pScreen); 33805b261ecSmrg 33905b261ecSmrg ephyrFinishPipelinedAccess(pSrc, EXA_PREPARE_SRC); 34005b261ecSmrg 34105b261ecSmrg return TRUE; 34205b261ecSmrg} 34305b261ecSmrg 34405b261ecSmrg/** 34505b261ecSmrg * Does fake acceleration of UploadToScreen using memcpy. 34605b261ecSmrg */ 34705b261ecSmrgstatic Bool 34805b261ecSmrgephyrUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src, 34935c4bbdfSmrg int src_pitch) 35005b261ecSmrg{ 35105b261ecSmrg KdScreenPriv(pDst->drawable.pScreen); 35205b261ecSmrg KdScreenInfo *screen = pScreenPriv->screen; 35305b261ecSmrg EphyrScrPriv *scrpriv = screen->driver; 35405b261ecSmrg EphyrFakexaPriv *fakexa = scrpriv->fakexa; 3554642e01fSmrg unsigned char *dst; 35605b261ecSmrg int dst_pitch, cpp; 35705b261ecSmrg 35805b261ecSmrg if (pDst->drawable.bitsPerPixel < 8) 35935c4bbdfSmrg return FALSE; 36005b261ecSmrg 36105b261ecSmrg ephyrPreparePipelinedAccess(pDst, EXA_PREPARE_DEST); 36205b261ecSmrg 36305b261ecSmrg cpp = pDst->drawable.bitsPerPixel / 8; 36405b261ecSmrg dst_pitch = exaGetPixmapPitch(pDst); 36505b261ecSmrg dst = fakexa->exa->memoryBase + exaGetPixmapOffset(pDst); 36605b261ecSmrg dst += y * dst_pitch + x * cpp; 36705b261ecSmrg 36805b261ecSmrg for (; h > 0; h--) { 36935c4bbdfSmrg memcpy(dst, src, w * cpp); 37035c4bbdfSmrg dst += dst_pitch; 37135c4bbdfSmrg src += src_pitch; 37205b261ecSmrg } 37305b261ecSmrg 37405b261ecSmrg exaMarkSync(pDst->drawable.pScreen); 37505b261ecSmrg 37605b261ecSmrg ephyrFinishPipelinedAccess(pDst, EXA_PREPARE_DEST); 37705b261ecSmrg 37805b261ecSmrg return TRUE; 37905b261ecSmrg} 38005b261ecSmrg 38105b261ecSmrgstatic Bool 38205b261ecSmrgephyrPrepareAccess(PixmapPtr pPix, int index) 38305b261ecSmrg{ 38405b261ecSmrg /* Make sure we don't somehow end up with a pointer that is in framebuffer 38505b261ecSmrg * and hasn't been readied for us. 38605b261ecSmrg */ 38705b261ecSmrg assert(pPix->devPrivate.ptr != NULL); 38805b261ecSmrg 38905b261ecSmrg return TRUE; 39005b261ecSmrg} 39105b261ecSmrg 39205b261ecSmrg/** 39305b261ecSmrg * In fakexa, we currently only track whether we have synced to the latest 39405b261ecSmrg * "accelerated" drawing that has happened or not. It's not used for anything 39505b261ecSmrg * yet. 39605b261ecSmrg */ 39705b261ecSmrgstatic int 39805b261ecSmrgephyrMarkSync(ScreenPtr pScreen) 39905b261ecSmrg{ 40005b261ecSmrg KdScreenPriv(pScreen); 40105b261ecSmrg KdScreenInfo *screen = pScreenPriv->screen; 40205b261ecSmrg EphyrScrPriv *scrpriv = screen->driver; 40305b261ecSmrg EphyrFakexaPriv *fakexa = scrpriv->fakexa; 40405b261ecSmrg 40505b261ecSmrg fakexa->is_synced = FALSE; 40605b261ecSmrg 40705b261ecSmrg return 0; 40805b261ecSmrg} 40905b261ecSmrg 41005b261ecSmrg/** 41105b261ecSmrg * Assumes that we're waiting on the latest marker. When EXA gets smarter and 41205b261ecSmrg * starts using markers in a fine-grained way (for example, waiting on drawing 41305b261ecSmrg * to required pixmaps to complete, rather than waiting for all drawing to 41405b261ecSmrg * complete), we'll want to make the ephyrMarkSync/ephyrWaitMarker 41505b261ecSmrg * implementation fine-grained as well. 41605b261ecSmrg */ 41705b261ecSmrgstatic void 41805b261ecSmrgephyrWaitMarker(ScreenPtr pScreen, int marker) 41905b261ecSmrg{ 42005b261ecSmrg KdScreenPriv(pScreen); 42105b261ecSmrg KdScreenInfo *screen = pScreenPriv->screen; 42205b261ecSmrg EphyrScrPriv *scrpriv = screen->driver; 42305b261ecSmrg EphyrFakexaPriv *fakexa = scrpriv->fakexa; 42405b261ecSmrg 42505b261ecSmrg fakexa->is_synced = TRUE; 42605b261ecSmrg} 42705b261ecSmrg 42805b261ecSmrg/** 42905b261ecSmrg * This function initializes EXA to use the fake acceleration implementation 43005b261ecSmrg * which just falls through to software. The purpose is to have a reliable, 43105b261ecSmrg * correct driver with which to test changes to the EXA core. 43205b261ecSmrg */ 43305b261ecSmrgBool 43405b261ecSmrgephyrDrawInit(ScreenPtr pScreen) 43505b261ecSmrg{ 43605b261ecSmrg KdScreenPriv(pScreen); 43705b261ecSmrg KdScreenInfo *screen = pScreenPriv->screen; 43805b261ecSmrg EphyrScrPriv *scrpriv = screen->driver; 4396747b715Smrg EphyrPriv *priv = screen->card->driver; 44005b261ecSmrg EphyrFakexaPriv *fakexa; 44105b261ecSmrg Bool success; 44205b261ecSmrg 4436747b715Smrg fakexa = calloc(1, sizeof(*fakexa)); 44405b261ecSmrg if (fakexa == NULL) 44535c4bbdfSmrg return FALSE; 44605b261ecSmrg 44705b261ecSmrg fakexa->exa = exaDriverAlloc(); 44805b261ecSmrg if (fakexa->exa == NULL) { 44935c4bbdfSmrg free(fakexa); 45035c4bbdfSmrg return FALSE; 45105b261ecSmrg } 45205b261ecSmrg 4536747b715Smrg fakexa->exa->memoryBase = (CARD8 *) (priv->base); 4546747b715Smrg fakexa->exa->memorySize = priv->bytes_per_line * ephyrBufferHeight(screen); 4556747b715Smrg fakexa->exa->offScreenBase = priv->bytes_per_line * screen->height; 45605b261ecSmrg 45705b261ecSmrg /* Since we statically link against EXA, we shouldn't have to be smart about 45805b261ecSmrg * versioning. 45905b261ecSmrg */ 46005b261ecSmrg fakexa->exa->exa_major = 2; 46105b261ecSmrg fakexa->exa->exa_minor = 0; 46205b261ecSmrg 46305b261ecSmrg fakexa->exa->PrepareSolid = ephyrPrepareSolid; 46405b261ecSmrg fakexa->exa->Solid = ephyrSolid; 46505b261ecSmrg fakexa->exa->DoneSolid = ephyrDoneSolid; 46605b261ecSmrg 46705b261ecSmrg fakexa->exa->PrepareCopy = ephyrPrepareCopy; 46805b261ecSmrg fakexa->exa->Copy = ephyrCopy; 46905b261ecSmrg fakexa->exa->DoneCopy = ephyrDoneCopy; 47005b261ecSmrg 47105b261ecSmrg fakexa->exa->CheckComposite = ephyrCheckComposite; 47205b261ecSmrg fakexa->exa->PrepareComposite = ephyrPrepareComposite; 47305b261ecSmrg fakexa->exa->Composite = ephyrComposite; 47405b261ecSmrg fakexa->exa->DoneComposite = ephyrDoneComposite; 47505b261ecSmrg 47605b261ecSmrg fakexa->exa->DownloadFromScreen = ephyrDownloadFromScreen; 47705b261ecSmrg fakexa->exa->UploadToScreen = ephyrUploadToScreen; 47805b261ecSmrg 47905b261ecSmrg fakexa->exa->MarkSync = ephyrMarkSync; 48005b261ecSmrg fakexa->exa->WaitMarker = ephyrWaitMarker; 48105b261ecSmrg 48205b261ecSmrg fakexa->exa->PrepareAccess = ephyrPrepareAccess; 48305b261ecSmrg 48405b261ecSmrg fakexa->exa->pixmapOffsetAlign = EPHYR_OFFSET_ALIGN; 48505b261ecSmrg fakexa->exa->pixmapPitchAlign = EPHYR_PITCH_ALIGN; 48605b261ecSmrg 48705b261ecSmrg fakexa->exa->maxX = 1023; 48805b261ecSmrg fakexa->exa->maxY = 1023; 48905b261ecSmrg 49005b261ecSmrg fakexa->exa->flags = EXA_OFFSCREEN_PIXMAPS; 49105b261ecSmrg 49205b261ecSmrg success = exaDriverInit(pScreen, fakexa->exa); 49305b261ecSmrg if (success) { 49435c4bbdfSmrg ErrorF("Initialized fake EXA acceleration\n"); 49535c4bbdfSmrg scrpriv->fakexa = fakexa; 49635c4bbdfSmrg } 49735c4bbdfSmrg else { 49835c4bbdfSmrg ErrorF("Failed to initialize EXA\n"); 49935c4bbdfSmrg free(fakexa->exa); 50035c4bbdfSmrg free(fakexa); 50105b261ecSmrg } 50205b261ecSmrg 50305b261ecSmrg return success; 50405b261ecSmrg} 50505b261ecSmrg 50605b261ecSmrgvoid 50705b261ecSmrgephyrDrawEnable(ScreenPtr pScreen) 50805b261ecSmrg{ 50905b261ecSmrg} 51005b261ecSmrg 51105b261ecSmrgvoid 51205b261ecSmrgephyrDrawDisable(ScreenPtr pScreen) 51305b261ecSmrg{ 51405b261ecSmrg} 51505b261ecSmrg 51605b261ecSmrgvoid 51705b261ecSmrgephyrDrawFini(ScreenPtr pScreen) 51805b261ecSmrg{ 51905b261ecSmrg} 52005b261ecSmrg 52105b261ecSmrg/** 52205b261ecSmrg * exaDDXDriverInit is required by the top-level EXA module, and is used by 52305b261ecSmrg * the xorg DDX to hook in its EnableDisableFB wrapper. We don't need it, since 52405b261ecSmrg * we won't be enabling/disabling the FB. 52505b261ecSmrg */ 52605b261ecSmrgvoid 52705b261ecSmrgexaDDXDriverInit(ScreenPtr pScreen) 52805b261ecSmrg{ 52905b261ecSmrg ExaScreenPriv(pScreen); 53005b261ecSmrg 53105b261ecSmrg pExaScr->migration = ExaMigrationSmart; 53205b261ecSmrg pExaScr->checkDirtyCorrectness = TRUE; 53305b261ecSmrg} 534