1706f2543Smrg/* 2706f2543Smrg * Copyright � 2006 Intel Corporation 3706f2543Smrg * 4706f2543Smrg * Permission is hereby granted, free of charge, to any person obtaining a 5706f2543Smrg * copy of this software and associated documentation files (the "Software"), 6706f2543Smrg * to deal in the Software without restriction, including without limitation 7706f2543Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8706f2543Smrg * and/or sell copies of the Software, and to permit persons to whom the 9706f2543Smrg * Software is furnished to do so, subject to the following conditions: 10706f2543Smrg * 11706f2543Smrg * The above copyright notice and this permission notice (including the next 12706f2543Smrg * paragraph) shall be included in all copies or substantial portions of the 13706f2543Smrg * Software. 14706f2543Smrg * 15706f2543Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16706f2543Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17706f2543Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18706f2543Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19706f2543Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20706f2543Smrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21706f2543Smrg * SOFTWARE. 22706f2543Smrg * 23706f2543Smrg * Authors: 24706f2543Smrg * Eric Anholt <eric@anholt.net> 25706f2543Smrg * 26706f2543Smrg */ 27706f2543Smrg 28706f2543Smrg#ifdef HAVE_CONFIG_H 29706f2543Smrg#include <kdrive-config.h> 30706f2543Smrg#endif 31706f2543Smrg 32706f2543Smrg#include "ephyr.h" 33706f2543Smrg#include "exa_priv.h" 34706f2543Smrg#include "fbpict.h" 35706f2543Smrg 36706f2543Smrg#define EPHYR_TRACE_DRAW 0 37706f2543Smrg 38706f2543Smrg#if EPHYR_TRACE_DRAW 39706f2543Smrg#define TRACE_DRAW() ErrorF("%s\n", __FUNCTION__); 40706f2543Smrg#else 41706f2543Smrg#define TRACE_DRAW() do { } while (0) 42706f2543Smrg#endif 43706f2543Smrg 44706f2543Smrg/* Use some oddball alignments, to expose issues in alignment handling in EXA. */ 45706f2543Smrg#define EPHYR_OFFSET_ALIGN 24 46706f2543Smrg#define EPHYR_PITCH_ALIGN 24 47706f2543Smrg 48706f2543Smrg#define EPHYR_OFFSCREEN_SIZE (16 * 1024 * 1024) 49706f2543Smrg#define EPHYR_OFFSCREEN_BASE (1 * 1024 * 1024) 50706f2543Smrg 51706f2543Smrg/** 52706f2543Smrg * Forces a real devPrivate.ptr for hidden pixmaps, so that we can call down to 53706f2543Smrg * fb functions. 54706f2543Smrg */ 55706f2543Smrgstatic void 56706f2543SmrgephyrPreparePipelinedAccess(PixmapPtr pPix, int index) 57706f2543Smrg{ 58706f2543Smrg KdScreenPriv(pPix->drawable.pScreen); 59706f2543Smrg KdScreenInfo *screen = pScreenPriv->screen; 60706f2543Smrg EphyrScrPriv *scrpriv = screen->driver; 61706f2543Smrg EphyrFakexaPriv *fakexa = scrpriv->fakexa; 62706f2543Smrg 63706f2543Smrg assert(fakexa->saved_ptrs[index] == NULL); 64706f2543Smrg fakexa->saved_ptrs[index] = pPix->devPrivate.ptr; 65706f2543Smrg 66706f2543Smrg if (pPix->devPrivate.ptr != NULL) 67706f2543Smrg return; 68706f2543Smrg 69706f2543Smrg pPix->devPrivate.ptr = fakexa->exa->memoryBase + exaGetPixmapOffset(pPix); 70706f2543Smrg} 71706f2543Smrg 72706f2543Smrg/** 73706f2543Smrg * Restores the original devPrivate.ptr of the pixmap from before we messed with 74706f2543Smrg * it. 75706f2543Smrg */ 76706f2543Smrgstatic void 77706f2543SmrgephyrFinishPipelinedAccess(PixmapPtr pPix, int index) 78706f2543Smrg{ 79706f2543Smrg KdScreenPriv(pPix->drawable.pScreen); 80706f2543Smrg KdScreenInfo *screen = pScreenPriv->screen; 81706f2543Smrg EphyrScrPriv *scrpriv = screen->driver; 82706f2543Smrg EphyrFakexaPriv *fakexa = scrpriv->fakexa; 83706f2543Smrg 84706f2543Smrg pPix->devPrivate.ptr = fakexa->saved_ptrs[index]; 85706f2543Smrg fakexa->saved_ptrs[index] = NULL; 86706f2543Smrg} 87706f2543Smrg 88706f2543Smrg/** 89706f2543Smrg * Sets up a scratch GC for fbFill, and saves other parameters for the 90706f2543Smrg * ephyrSolid implementation. 91706f2543Smrg */ 92706f2543Smrgstatic Bool 93706f2543SmrgephyrPrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg) 94706f2543Smrg{ 95706f2543Smrg ScreenPtr pScreen = pPix->drawable.pScreen; 96706f2543Smrg KdScreenPriv(pScreen); 97706f2543Smrg KdScreenInfo *screen = pScreenPriv->screen; 98706f2543Smrg EphyrScrPriv *scrpriv = screen->driver; 99706f2543Smrg EphyrFakexaPriv *fakexa = scrpriv->fakexa; 100706f2543Smrg ChangeGCVal tmpval[3]; 101706f2543Smrg 102706f2543Smrg ephyrPreparePipelinedAccess(pPix, EXA_PREPARE_DEST); 103706f2543Smrg 104706f2543Smrg fakexa->pDst = pPix; 105706f2543Smrg fakexa->pGC = GetScratchGC(pPix->drawable.depth, pScreen); 106706f2543Smrg 107706f2543Smrg tmpval[0].val = alu; 108706f2543Smrg tmpval[1].val = pm; 109706f2543Smrg tmpval[2].val = fg; 110706f2543Smrg ChangeGC(NullClient, fakexa->pGC, GCFunction | GCPlaneMask | GCForeground, tmpval); 111706f2543Smrg 112706f2543Smrg ValidateGC(&pPix->drawable, fakexa->pGC); 113706f2543Smrg 114706f2543Smrg TRACE_DRAW(); 115706f2543Smrg 116706f2543Smrg return TRUE; 117706f2543Smrg} 118706f2543Smrg 119706f2543Smrg/** 120706f2543Smrg * Does an fbFill of the rectangle to be drawn. 121706f2543Smrg */ 122706f2543Smrgstatic void 123706f2543SmrgephyrSolid(PixmapPtr pPix, int x1, int y1, int x2, int y2) 124706f2543Smrg{ 125706f2543Smrg ScreenPtr pScreen = pPix->drawable.pScreen; 126706f2543Smrg KdScreenPriv(pScreen); 127706f2543Smrg KdScreenInfo *screen = pScreenPriv->screen; 128706f2543Smrg EphyrScrPriv *scrpriv = screen->driver; 129706f2543Smrg EphyrFakexaPriv *fakexa = scrpriv->fakexa; 130706f2543Smrg 131706f2543Smrg fbFill(&fakexa->pDst->drawable, fakexa->pGC, x1, y1, x2 - x1, y2 - y1); 132706f2543Smrg} 133706f2543Smrg 134706f2543Smrg/** 135706f2543Smrg * Cleans up the scratch GC created in ephyrPrepareSolid. 136706f2543Smrg */ 137706f2543Smrgstatic void 138706f2543SmrgephyrDoneSolid(PixmapPtr pPix) 139706f2543Smrg{ 140706f2543Smrg ScreenPtr pScreen = pPix->drawable.pScreen; 141706f2543Smrg KdScreenPriv(pScreen); 142706f2543Smrg KdScreenInfo *screen = pScreenPriv->screen; 143706f2543Smrg EphyrScrPriv *scrpriv = screen->driver; 144706f2543Smrg EphyrFakexaPriv *fakexa = scrpriv->fakexa; 145706f2543Smrg 146706f2543Smrg FreeScratchGC(fakexa->pGC); 147706f2543Smrg 148706f2543Smrg ephyrFinishPipelinedAccess(pPix, EXA_PREPARE_DEST); 149706f2543Smrg} 150706f2543Smrg 151706f2543Smrg/** 152706f2543Smrg * Sets up a scratch GC for fbCopyArea, and saves other parameters for the 153706f2543Smrg * ephyrCopy implementation. 154706f2543Smrg */ 155706f2543Smrgstatic Bool 156706f2543SmrgephyrPrepareCopy(PixmapPtr pSrc, PixmapPtr pDst, int dx, int dy, int alu, 157706f2543Smrg Pixel pm) 158706f2543Smrg{ 159706f2543Smrg ScreenPtr pScreen = pDst->drawable.pScreen; 160706f2543Smrg KdScreenPriv(pScreen); 161706f2543Smrg KdScreenInfo *screen = pScreenPriv->screen; 162706f2543Smrg EphyrScrPriv *scrpriv = screen->driver; 163706f2543Smrg EphyrFakexaPriv *fakexa = scrpriv->fakexa; 164706f2543Smrg ChangeGCVal tmpval[2]; 165706f2543Smrg 166706f2543Smrg ephyrPreparePipelinedAccess(pDst, EXA_PREPARE_DEST); 167706f2543Smrg ephyrPreparePipelinedAccess(pSrc, EXA_PREPARE_SRC); 168706f2543Smrg 169706f2543Smrg fakexa->pSrc = pSrc; 170706f2543Smrg fakexa->pDst = pDst; 171706f2543Smrg fakexa->pGC = GetScratchGC(pDst->drawable.depth, pScreen); 172706f2543Smrg 173706f2543Smrg tmpval[0].val = alu; 174706f2543Smrg tmpval[1].val = pm; 175706f2543Smrg ChangeGC (NullClient, fakexa->pGC, GCFunction | GCPlaneMask, tmpval); 176706f2543Smrg 177706f2543Smrg ValidateGC(&pDst->drawable, fakexa->pGC); 178706f2543Smrg 179706f2543Smrg TRACE_DRAW(); 180706f2543Smrg 181706f2543Smrg return TRUE; 182706f2543Smrg} 183706f2543Smrg 184706f2543Smrg/** 185706f2543Smrg * Does an fbCopyArea to take care of the requested copy. 186706f2543Smrg */ 187706f2543Smrgstatic void 188706f2543SmrgephyrCopy(PixmapPtr pDst, int srcX, int srcY, int dstX, int dstY, int w, int h) 189706f2543Smrg{ 190706f2543Smrg ScreenPtr pScreen = pDst->drawable.pScreen; 191706f2543Smrg KdScreenPriv(pScreen); 192706f2543Smrg KdScreenInfo *screen = pScreenPriv->screen; 193706f2543Smrg EphyrScrPriv *scrpriv = screen->driver; 194706f2543Smrg EphyrFakexaPriv *fakexa = scrpriv->fakexa; 195706f2543Smrg 196706f2543Smrg fbCopyArea(&fakexa->pSrc->drawable, &fakexa->pDst->drawable, fakexa->pGC, 197706f2543Smrg srcX, srcY, w, h, dstX, dstY); 198706f2543Smrg} 199706f2543Smrg 200706f2543Smrg/** 201706f2543Smrg * Cleans up the scratch GC created in ephyrPrepareCopy. 202706f2543Smrg */ 203706f2543Smrgstatic void 204706f2543SmrgephyrDoneCopy(PixmapPtr pDst) 205706f2543Smrg{ 206706f2543Smrg ScreenPtr pScreen = pDst->drawable.pScreen; 207706f2543Smrg KdScreenPriv(pScreen); 208706f2543Smrg KdScreenInfo *screen = pScreenPriv->screen; 209706f2543Smrg EphyrScrPriv *scrpriv = screen->driver; 210706f2543Smrg EphyrFakexaPriv *fakexa = scrpriv->fakexa; 211706f2543Smrg 212706f2543Smrg FreeScratchGC (fakexa->pGC); 213706f2543Smrg 214706f2543Smrg ephyrFinishPipelinedAccess(fakexa->pSrc, EXA_PREPARE_SRC); 215706f2543Smrg ephyrFinishPipelinedAccess(fakexa->pDst, EXA_PREPARE_DEST); 216706f2543Smrg} 217706f2543Smrg 218706f2543Smrg/** 219706f2543Smrg * Reports that we can always accelerate the given operation. This may not be 220706f2543Smrg * desirable from an EXA testing standpoint -- testing the fallback paths would 221706f2543Smrg * be useful, too. 222706f2543Smrg */ 223706f2543Smrgstatic Bool 224706f2543SmrgephyrCheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, 225706f2543Smrg PicturePtr pDstPicture) 226706f2543Smrg{ 227706f2543Smrg /* Exercise the component alpha helper, so fail on this case like a normal 228706f2543Smrg * driver 229706f2543Smrg */ 230706f2543Smrg if (pMaskPicture && pMaskPicture->componentAlpha && op == PictOpOver) 231706f2543Smrg return FALSE; 232706f2543Smrg 233706f2543Smrg return TRUE; 234706f2543Smrg} 235706f2543Smrg 236706f2543Smrg/** 237706f2543Smrg * Saves off the parameters for ephyrComposite. 238706f2543Smrg */ 239706f2543Smrgstatic Bool 240706f2543SmrgephyrPrepareComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, 241706f2543Smrg PicturePtr pDstPicture, PixmapPtr pSrc, PixmapPtr pMask, 242706f2543Smrg PixmapPtr pDst) 243706f2543Smrg{ 244706f2543Smrg KdScreenPriv(pDst->drawable.pScreen); 245706f2543Smrg KdScreenInfo *screen = pScreenPriv->screen; 246706f2543Smrg EphyrScrPriv *scrpriv = screen->driver; 247706f2543Smrg EphyrFakexaPriv *fakexa = scrpriv->fakexa; 248706f2543Smrg 249706f2543Smrg ephyrPreparePipelinedAccess(pDst, EXA_PREPARE_DEST); 250706f2543Smrg ephyrPreparePipelinedAccess(pSrc, EXA_PREPARE_SRC); 251706f2543Smrg if (pMask != NULL) 252706f2543Smrg ephyrPreparePipelinedAccess(pMask, EXA_PREPARE_MASK); 253706f2543Smrg 254706f2543Smrg fakexa->op = op; 255706f2543Smrg fakexa->pSrcPicture = pSrcPicture; 256706f2543Smrg fakexa->pMaskPicture = pMaskPicture; 257706f2543Smrg fakexa->pDstPicture = pDstPicture; 258706f2543Smrg fakexa->pSrc = pSrc; 259706f2543Smrg fakexa->pMask = pMask; 260706f2543Smrg fakexa->pDst = pDst; 261706f2543Smrg 262706f2543Smrg TRACE_DRAW(); 263706f2543Smrg 264706f2543Smrg return TRUE; 265706f2543Smrg} 266706f2543Smrg 267706f2543Smrg/** 268706f2543Smrg * Does an fbComposite to complete the requested drawing operation. 269706f2543Smrg */ 270706f2543Smrgstatic void 271706f2543SmrgephyrComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, 272706f2543Smrg int dstX, int dstY, int w, int h) 273706f2543Smrg{ 274706f2543Smrg KdScreenPriv(pDst->drawable.pScreen); 275706f2543Smrg KdScreenInfo *screen = pScreenPriv->screen; 276706f2543Smrg EphyrScrPriv *scrpriv = screen->driver; 277706f2543Smrg EphyrFakexaPriv *fakexa = scrpriv->fakexa; 278706f2543Smrg 279706f2543Smrg fbComposite(fakexa->op, fakexa->pSrcPicture, fakexa->pMaskPicture, 280706f2543Smrg fakexa->pDstPicture, srcX, srcY, maskX, maskY, dstX, dstY, 281706f2543Smrg w, h); 282706f2543Smrg} 283706f2543Smrg 284706f2543Smrgstatic void 285706f2543SmrgephyrDoneComposite(PixmapPtr pDst) 286706f2543Smrg{ 287706f2543Smrg KdScreenPriv(pDst->drawable.pScreen); 288706f2543Smrg KdScreenInfo *screen = pScreenPriv->screen; 289706f2543Smrg EphyrScrPriv *scrpriv = screen->driver; 290706f2543Smrg EphyrFakexaPriv *fakexa = scrpriv->fakexa; 291706f2543Smrg 292706f2543Smrg if (fakexa->pMask != NULL) 293706f2543Smrg ephyrFinishPipelinedAccess(fakexa->pMask, EXA_PREPARE_MASK); 294706f2543Smrg ephyrFinishPipelinedAccess(fakexa->pSrc, EXA_PREPARE_SRC); 295706f2543Smrg ephyrFinishPipelinedAccess(fakexa->pDst, EXA_PREPARE_DEST); 296706f2543Smrg} 297706f2543Smrg 298706f2543Smrg/** 299706f2543Smrg * Does fake acceleration of DownloadFromScren using memcpy. 300706f2543Smrg */ 301706f2543Smrgstatic Bool 302706f2543SmrgephyrDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, char *dst, 303706f2543Smrg int dst_pitch) 304706f2543Smrg{ 305706f2543Smrg KdScreenPriv(pSrc->drawable.pScreen); 306706f2543Smrg KdScreenInfo *screen = pScreenPriv->screen; 307706f2543Smrg EphyrScrPriv *scrpriv = screen->driver; 308706f2543Smrg EphyrFakexaPriv *fakexa = scrpriv->fakexa; 309706f2543Smrg unsigned char *src; 310706f2543Smrg int src_pitch, cpp; 311706f2543Smrg 312706f2543Smrg if (pSrc->drawable.bitsPerPixel < 8) 313706f2543Smrg return FALSE; 314706f2543Smrg 315706f2543Smrg ephyrPreparePipelinedAccess(pSrc, EXA_PREPARE_SRC); 316706f2543Smrg 317706f2543Smrg cpp = pSrc->drawable.bitsPerPixel / 8; 318706f2543Smrg src_pitch = exaGetPixmapPitch(pSrc); 319706f2543Smrg src = fakexa->exa->memoryBase + exaGetPixmapOffset(pSrc); 320706f2543Smrg src += y * src_pitch + x * cpp; 321706f2543Smrg 322706f2543Smrg for (; h > 0; h--) { 323706f2543Smrg memcpy(dst, src, w * cpp); 324706f2543Smrg dst += dst_pitch; 325706f2543Smrg src += src_pitch; 326706f2543Smrg } 327706f2543Smrg 328706f2543Smrg exaMarkSync(pSrc->drawable.pScreen); 329706f2543Smrg 330706f2543Smrg ephyrFinishPipelinedAccess(pSrc, EXA_PREPARE_SRC); 331706f2543Smrg 332706f2543Smrg return TRUE; 333706f2543Smrg} 334706f2543Smrg 335706f2543Smrg/** 336706f2543Smrg * Does fake acceleration of UploadToScreen using memcpy. 337706f2543Smrg */ 338706f2543Smrgstatic Bool 339706f2543SmrgephyrUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src, 340706f2543Smrg int src_pitch) 341706f2543Smrg{ 342706f2543Smrg KdScreenPriv(pDst->drawable.pScreen); 343706f2543Smrg KdScreenInfo *screen = pScreenPriv->screen; 344706f2543Smrg EphyrScrPriv *scrpriv = screen->driver; 345706f2543Smrg EphyrFakexaPriv *fakexa = scrpriv->fakexa; 346706f2543Smrg unsigned char *dst; 347706f2543Smrg int dst_pitch, cpp; 348706f2543Smrg 349706f2543Smrg if (pDst->drawable.bitsPerPixel < 8) 350706f2543Smrg return FALSE; 351706f2543Smrg 352706f2543Smrg ephyrPreparePipelinedAccess(pDst, EXA_PREPARE_DEST); 353706f2543Smrg 354706f2543Smrg cpp = pDst->drawable.bitsPerPixel / 8; 355706f2543Smrg dst_pitch = exaGetPixmapPitch(pDst); 356706f2543Smrg dst = fakexa->exa->memoryBase + exaGetPixmapOffset(pDst); 357706f2543Smrg dst += y * dst_pitch + x * cpp; 358706f2543Smrg 359706f2543Smrg for (; h > 0; h--) { 360706f2543Smrg memcpy(dst, src, w * cpp); 361706f2543Smrg dst += dst_pitch; 362706f2543Smrg src += src_pitch; 363706f2543Smrg } 364706f2543Smrg 365706f2543Smrg exaMarkSync(pDst->drawable.pScreen); 366706f2543Smrg 367706f2543Smrg ephyrFinishPipelinedAccess(pDst, EXA_PREPARE_DEST); 368706f2543Smrg 369706f2543Smrg return TRUE; 370706f2543Smrg} 371706f2543Smrg 372706f2543Smrgstatic Bool 373706f2543SmrgephyrPrepareAccess(PixmapPtr pPix, int index) 374706f2543Smrg{ 375706f2543Smrg /* Make sure we don't somehow end up with a pointer that is in framebuffer 376706f2543Smrg * and hasn't been readied for us. 377706f2543Smrg */ 378706f2543Smrg assert(pPix->devPrivate.ptr != NULL); 379706f2543Smrg 380706f2543Smrg return TRUE; 381706f2543Smrg} 382706f2543Smrg 383706f2543Smrg/** 384706f2543Smrg * In fakexa, we currently only track whether we have synced to the latest 385706f2543Smrg * "accelerated" drawing that has happened or not. It's not used for anything 386706f2543Smrg * yet. 387706f2543Smrg */ 388706f2543Smrgstatic int 389706f2543SmrgephyrMarkSync(ScreenPtr pScreen) 390706f2543Smrg{ 391706f2543Smrg KdScreenPriv(pScreen); 392706f2543Smrg KdScreenInfo *screen = pScreenPriv->screen; 393706f2543Smrg EphyrScrPriv *scrpriv = screen->driver; 394706f2543Smrg EphyrFakexaPriv *fakexa = scrpriv->fakexa; 395706f2543Smrg 396706f2543Smrg fakexa->is_synced = FALSE; 397706f2543Smrg 398706f2543Smrg return 0; 399706f2543Smrg} 400706f2543Smrg 401706f2543Smrg/** 402706f2543Smrg * Assumes that we're waiting on the latest marker. When EXA gets smarter and 403706f2543Smrg * starts using markers in a fine-grained way (for example, waiting on drawing 404706f2543Smrg * to required pixmaps to complete, rather than waiting for all drawing to 405706f2543Smrg * complete), we'll want to make the ephyrMarkSync/ephyrWaitMarker 406706f2543Smrg * implementation fine-grained as well. 407706f2543Smrg */ 408706f2543Smrgstatic void 409706f2543SmrgephyrWaitMarker(ScreenPtr pScreen, int marker) 410706f2543Smrg{ 411706f2543Smrg KdScreenPriv(pScreen); 412706f2543Smrg KdScreenInfo *screen = pScreenPriv->screen; 413706f2543Smrg EphyrScrPriv *scrpriv = screen->driver; 414706f2543Smrg EphyrFakexaPriv *fakexa = scrpriv->fakexa; 415706f2543Smrg 416706f2543Smrg fakexa->is_synced = TRUE; 417706f2543Smrg} 418706f2543Smrg 419706f2543Smrg/** 420706f2543Smrg * This function initializes EXA to use the fake acceleration implementation 421706f2543Smrg * which just falls through to software. The purpose is to have a reliable, 422706f2543Smrg * correct driver with which to test changes to the EXA core. 423706f2543Smrg */ 424706f2543SmrgBool 425706f2543SmrgephyrDrawInit(ScreenPtr pScreen) 426706f2543Smrg{ 427706f2543Smrg KdScreenPriv(pScreen); 428706f2543Smrg KdScreenInfo *screen = pScreenPriv->screen; 429706f2543Smrg EphyrScrPriv *scrpriv = screen->driver; 430706f2543Smrg EphyrPriv *priv = screen->card->driver; 431706f2543Smrg EphyrFakexaPriv *fakexa; 432706f2543Smrg Bool success; 433706f2543Smrg 434706f2543Smrg fakexa = calloc(1, sizeof(*fakexa)); 435706f2543Smrg if (fakexa == NULL) 436706f2543Smrg return FALSE; 437706f2543Smrg 438706f2543Smrg fakexa->exa = exaDriverAlloc(); 439706f2543Smrg if (fakexa->exa == NULL) { 440706f2543Smrg free(fakexa); 441706f2543Smrg return FALSE; 442706f2543Smrg } 443706f2543Smrg 444706f2543Smrg fakexa->exa->memoryBase = (CARD8 *) (priv->base); 445706f2543Smrg fakexa->exa->memorySize = priv->bytes_per_line * ephyrBufferHeight(screen); 446706f2543Smrg fakexa->exa->offScreenBase = priv->bytes_per_line * screen->height; 447706f2543Smrg 448706f2543Smrg /* Since we statically link against EXA, we shouldn't have to be smart about 449706f2543Smrg * versioning. 450706f2543Smrg */ 451706f2543Smrg fakexa->exa->exa_major = 2; 452706f2543Smrg fakexa->exa->exa_minor = 0; 453706f2543Smrg 454706f2543Smrg fakexa->exa->PrepareSolid = ephyrPrepareSolid; 455706f2543Smrg fakexa->exa->Solid = ephyrSolid; 456706f2543Smrg fakexa->exa->DoneSolid = ephyrDoneSolid; 457706f2543Smrg 458706f2543Smrg fakexa->exa->PrepareCopy = ephyrPrepareCopy; 459706f2543Smrg fakexa->exa->Copy = ephyrCopy; 460706f2543Smrg fakexa->exa->DoneCopy = ephyrDoneCopy; 461706f2543Smrg 462706f2543Smrg fakexa->exa->CheckComposite = ephyrCheckComposite; 463706f2543Smrg fakexa->exa->PrepareComposite = ephyrPrepareComposite; 464706f2543Smrg fakexa->exa->Composite = ephyrComposite; 465706f2543Smrg fakexa->exa->DoneComposite = ephyrDoneComposite; 466706f2543Smrg 467706f2543Smrg fakexa->exa->DownloadFromScreen = ephyrDownloadFromScreen; 468706f2543Smrg fakexa->exa->UploadToScreen = ephyrUploadToScreen; 469706f2543Smrg 470706f2543Smrg fakexa->exa->MarkSync = ephyrMarkSync; 471706f2543Smrg fakexa->exa->WaitMarker = ephyrWaitMarker; 472706f2543Smrg 473706f2543Smrg fakexa->exa->PrepareAccess = ephyrPrepareAccess; 474706f2543Smrg 475706f2543Smrg fakexa->exa->pixmapOffsetAlign = EPHYR_OFFSET_ALIGN; 476706f2543Smrg fakexa->exa->pixmapPitchAlign = EPHYR_PITCH_ALIGN; 477706f2543Smrg 478706f2543Smrg fakexa->exa->maxX = 1023; 479706f2543Smrg fakexa->exa->maxY = 1023; 480706f2543Smrg 481706f2543Smrg fakexa->exa->flags = EXA_OFFSCREEN_PIXMAPS; 482706f2543Smrg 483706f2543Smrg success = exaDriverInit(pScreen, fakexa->exa); 484706f2543Smrg if (success) { 485706f2543Smrg ErrorF("Initialized fake EXA acceleration\n"); 486706f2543Smrg scrpriv->fakexa = fakexa; 487706f2543Smrg } else { 488706f2543Smrg ErrorF("Failed to initialize EXA\n"); 489706f2543Smrg free(fakexa->exa); 490706f2543Smrg free(fakexa); 491706f2543Smrg } 492706f2543Smrg 493706f2543Smrg return success; 494706f2543Smrg} 495706f2543Smrg 496706f2543Smrgvoid 497706f2543SmrgephyrDrawEnable(ScreenPtr pScreen) 498706f2543Smrg{ 499706f2543Smrg} 500706f2543Smrg 501706f2543Smrgvoid 502706f2543SmrgephyrDrawDisable(ScreenPtr pScreen) 503706f2543Smrg{ 504706f2543Smrg} 505706f2543Smrg 506706f2543Smrgvoid 507706f2543SmrgephyrDrawFini(ScreenPtr pScreen) 508706f2543Smrg{ 509706f2543Smrg} 510706f2543Smrg 511706f2543Smrg/** 512706f2543Smrg * exaDDXDriverInit is required by the top-level EXA module, and is used by 513706f2543Smrg * the xorg DDX to hook in its EnableDisableFB wrapper. We don't need it, since 514706f2543Smrg * we won't be enabling/disabling the FB. 515706f2543Smrg */ 516706f2543Smrgvoid 517706f2543SmrgexaDDXDriverInit(ScreenPtr pScreen) 518706f2543Smrg{ 519706f2543Smrg ExaScreenPriv(pScreen); 520706f2543Smrg 521706f2543Smrg pExaScr->migration = ExaMigrationSmart; 522706f2543Smrg pExaScr->checkDirtyCorrectness = TRUE; 523706f2543Smrg} 524