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