g80_exa.c revision fc5a983d
1fc5a983dSmrg/*
2fc5a983dSmrg * Copyright (c) 2007 NVIDIA, Corporation
3fc5a983dSmrg *
4fc5a983dSmrg * Permission is hereby granted, free of charge, to any person obtaining a
5fc5a983dSmrg * copy of this software and associated documentation files (the
6fc5a983dSmrg * "Software"), to deal in the Software without restriction, including
7fc5a983dSmrg * without limitation the rights to use, copy, modify, merge, publish,
8fc5a983dSmrg * distribute, sublicense, and/or sell copies of the Software, and to
9fc5a983dSmrg * permit persons to whom the Software is furnished to do so, subject to
10fc5a983dSmrg * the following conditions:
11fc5a983dSmrg *
12fc5a983dSmrg * The above copyright notice and this permission notice shall be included
13fc5a983dSmrg * in all copies or substantial portions of the Software.
14fc5a983dSmrg *
15fc5a983dSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16fc5a983dSmrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17fc5a983dSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18fc5a983dSmrg * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19fc5a983dSmrg * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20fc5a983dSmrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21fc5a983dSmrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22fc5a983dSmrg */
23fc5a983dSmrg
24fc5a983dSmrg
25fc5a983dSmrg#ifdef HAVE_CONFIG_H
26fc5a983dSmrg#include "config.h"
27fc5a983dSmrg#endif
28fc5a983dSmrg
29fc5a983dSmrg#include "g80_type.h"
30fc5a983dSmrg#include "g80_dma.h"
31fc5a983dSmrg#include "g80_xaa.h"
32fc5a983dSmrg
33fc5a983dSmrgstatic void
34fc5a983dSmrgwaitMarker(ScreenPtr pScreen, int marker)
35fc5a983dSmrg{
36fc5a983dSmrg    G80Sync(xf86Screens[pScreen->myNum]);
37fc5a983dSmrg}
38fc5a983dSmrg
39fc5a983dSmrgstatic Bool
40fc5a983dSmrgsetSrc(G80Ptr pNv, PixmapPtr pSrc)
41fc5a983dSmrg{
42fc5a983dSmrg    CARD32 depth;
43fc5a983dSmrg
44fc5a983dSmrg    switch(pSrc->drawable.depth) {
45fc5a983dSmrg        case  8: depth = 0x000000f3; break;
46fc5a983dSmrg        case 15: depth = 0x000000f8; break;
47fc5a983dSmrg        case 16: depth = 0x000000e8; break;
48fc5a983dSmrg        case 24: depth = 0x000000e6; break;
49fc5a983dSmrg        case 32: depth = 0x000000cf; break;
50fc5a983dSmrg        default: return FALSE;
51fc5a983dSmrg    }
52fc5a983dSmrg
53fc5a983dSmrg    G80DmaStart(pNv, 0x230, 2);
54fc5a983dSmrg    G80DmaNext (pNv, depth);
55fc5a983dSmrg    G80DmaNext (pNv, 0x00000001);
56fc5a983dSmrg    G80DmaStart(pNv, 0x244, 5);
57fc5a983dSmrg    G80DmaNext (pNv, exaGetPixmapPitch(pSrc));
58fc5a983dSmrg    G80DmaNext (pNv, pSrc->drawable.width);
59fc5a983dSmrg    G80DmaNext (pNv, pSrc->drawable.height);
60fc5a983dSmrg    G80DmaNext (pNv, 0x00000000);
61fc5a983dSmrg    G80DmaNext (pNv, exaGetPixmapOffset(pSrc));
62fc5a983dSmrg
63fc5a983dSmrg    return TRUE;
64fc5a983dSmrg}
65fc5a983dSmrg
66fc5a983dSmrgstatic Bool
67fc5a983dSmrgsetDst(G80Ptr pNv, PixmapPtr pDst)
68fc5a983dSmrg{
69fc5a983dSmrg    CARD32 depth, depth2;
70fc5a983dSmrg
71fc5a983dSmrg    switch(pDst->drawable.depth) {
72fc5a983dSmrg        case  8: depth = 0x000000f3; depth2 = 3; break;
73fc5a983dSmrg        case 15: depth = 0x000000f8; depth2 = 1; break;
74fc5a983dSmrg        case 16: depth = 0x000000e8; depth2 = 0; break;
75fc5a983dSmrg        case 24: depth = 0x000000e6; depth2 = 2; break;
76fc5a983dSmrg        case 32: depth = 0x000000cf; depth2 = 2; break;
77fc5a983dSmrg        default: return FALSE;
78fc5a983dSmrg    }
79fc5a983dSmrg
80fc5a983dSmrg    G80DmaStart(pNv, 0x200, 2);
81fc5a983dSmrg    G80DmaNext (pNv, depth);
82fc5a983dSmrg    G80DmaNext (pNv, 0x00000001);
83fc5a983dSmrg    G80DmaStart(pNv, 0x214, 5);
84fc5a983dSmrg    G80DmaNext (pNv, exaGetPixmapPitch(pDst));
85fc5a983dSmrg    G80DmaNext (pNv, pDst->drawable.width);
86fc5a983dSmrg    G80DmaNext (pNv, pDst->drawable.height);
87fc5a983dSmrg    G80DmaNext (pNv, 0x00000000);
88fc5a983dSmrg    G80DmaNext (pNv, exaGetPixmapOffset(pDst));
89fc5a983dSmrg    G80DmaStart(pNv, 0x2e8, 1);
90fc5a983dSmrg    G80DmaNext (pNv, depth2);
91fc5a983dSmrg    G80DmaStart(pNv, 0x584, 1);
92fc5a983dSmrg    G80DmaNext (pNv, depth);
93fc5a983dSmrg    G80SetClip(pNv, 0, 0, pDst->drawable.width, pDst->drawable.height);
94fc5a983dSmrg
95fc5a983dSmrg    return TRUE;
96fc5a983dSmrg}
97fc5a983dSmrg
98fc5a983dSmrg/* solid fills */
99fc5a983dSmrg
100fc5a983dSmrgstatic Bool
101fc5a983dSmrgprepareSolid(PixmapPtr      pPixmap,
102fc5a983dSmrg             int            alu,
103fc5a983dSmrg             Pixel          planemask,
104fc5a983dSmrg             Pixel          fg)
105fc5a983dSmrg{
106fc5a983dSmrg    ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
107fc5a983dSmrg    G80Ptr pNv = G80PTR(pScrn);
108fc5a983dSmrg
109fc5a983dSmrg    if(pPixmap->drawable.depth > 24) return FALSE;
110fc5a983dSmrg    if(!setDst(pNv, pPixmap)) return FALSE;
111fc5a983dSmrg    G80DmaStart(pNv, 0x2ac, 1);
112fc5a983dSmrg    G80DmaNext (pNv, 1);
113fc5a983dSmrg    G80SetRopSolid(pNv, alu, planemask);
114fc5a983dSmrg    G80DmaStart(pNv, 0x580, 1);
115fc5a983dSmrg    G80DmaNext (pNv, 4);
116fc5a983dSmrg    G80DmaStart(pNv, 0x588, 1);
117fc5a983dSmrg    G80DmaNext (pNv, fg);
118fc5a983dSmrg
119fc5a983dSmrg    pNv->DMAKickoffCallback = G80DMAKickoffCallback;
120fc5a983dSmrg    return TRUE;
121fc5a983dSmrg}
122fc5a983dSmrg
123fc5a983dSmrgstatic void
124fc5a983dSmrgsolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2)
125fc5a983dSmrg{
126fc5a983dSmrg    ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
127fc5a983dSmrg    G80Ptr pNv = G80PTR(pScrn);
128fc5a983dSmrg
129fc5a983dSmrg    G80DmaStart(pNv, 0x600, 4);
130fc5a983dSmrg    G80DmaNext (pNv, x1);
131fc5a983dSmrg    G80DmaNext (pNv, y1);
132fc5a983dSmrg    G80DmaNext (pNv, x2);
133fc5a983dSmrg    G80DmaNext (pNv, y2);
134fc5a983dSmrg
135fc5a983dSmrg    if((x2 - x1) * (y2 - y1) >= 512)
136fc5a983dSmrg        G80DmaKickoff(pNv);
137fc5a983dSmrg}
138fc5a983dSmrg
139fc5a983dSmrgstatic void
140fc5a983dSmrgdoneSolid(PixmapPtr pPixmap)
141fc5a983dSmrg{
142fc5a983dSmrg}
143fc5a983dSmrg
144fc5a983dSmrg/* screen to screen copies */
145fc5a983dSmrg
146fc5a983dSmrgstatic Bool
147fc5a983dSmrgprepareCopy(PixmapPtr       pSrcPixmap,
148fc5a983dSmrg            PixmapPtr       pDstPixmap,
149fc5a983dSmrg            int             dx,
150fc5a983dSmrg            int             dy,
151fc5a983dSmrg            int             alu,
152fc5a983dSmrg            Pixel           planemask)
153fc5a983dSmrg{
154fc5a983dSmrg    ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
155fc5a983dSmrg    G80Ptr pNv = G80PTR(pScrn);
156fc5a983dSmrg
157fc5a983dSmrg    if(!setSrc(pNv, pSrcPixmap)) return FALSE;
158fc5a983dSmrg    if(!setDst(pNv, pDstPixmap)) return FALSE;
159fc5a983dSmrg    G80DmaStart(pNv, 0x2ac, 1);
160fc5a983dSmrg    if(alu == GXcopy && planemask == ~0) {
161fc5a983dSmrg        G80DmaNext (pNv, 3);
162fc5a983dSmrg    } else {
163fc5a983dSmrg        G80DmaNext (pNv, 1);
164fc5a983dSmrg        G80SetRopSolid(pNv, alu, planemask);
165fc5a983dSmrg    }
166fc5a983dSmrg    pNv->DMAKickoffCallback = G80DMAKickoffCallback;
167fc5a983dSmrg    return TRUE;
168fc5a983dSmrg}
169fc5a983dSmrg
170fc5a983dSmrgstatic void
171fc5a983dSmrgcopy(PixmapPtr pDstPixmap,
172fc5a983dSmrg     int       srcX,
173fc5a983dSmrg     int       srcY,
174fc5a983dSmrg     int       dstX,
175fc5a983dSmrg     int       dstY,
176fc5a983dSmrg     int       width,
177fc5a983dSmrg     int       height)
178fc5a983dSmrg{
179fc5a983dSmrg    ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
180fc5a983dSmrg    G80Ptr pNv = G80PTR(pScrn);
181fc5a983dSmrg
182fc5a983dSmrg    G80DmaStart(pNv, 0x110, 1);
183fc5a983dSmrg    G80DmaNext (pNv, 0);
184fc5a983dSmrg    G80DmaStart(pNv, 0x8b0, 12);
185fc5a983dSmrg    G80DmaNext (pNv, dstX);
186fc5a983dSmrg    G80DmaNext (pNv, dstY);
187fc5a983dSmrg    G80DmaNext (pNv, width);
188fc5a983dSmrg    G80DmaNext (pNv, height);
189fc5a983dSmrg    G80DmaNext (pNv, 0);
190fc5a983dSmrg    G80DmaNext (pNv, 1);
191fc5a983dSmrg    G80DmaNext (pNv, 0);
192fc5a983dSmrg    G80DmaNext (pNv, 1);
193fc5a983dSmrg    G80DmaNext (pNv, 0);
194fc5a983dSmrg    G80DmaNext (pNv, srcX);
195fc5a983dSmrg    G80DmaNext (pNv, 0);
196fc5a983dSmrg    G80DmaNext (pNv, srcY);
197fc5a983dSmrg
198fc5a983dSmrg    if(width * height >= 512)
199fc5a983dSmrg        G80DmaKickoff(pNv);
200fc5a983dSmrg}
201fc5a983dSmrg
202fc5a983dSmrgstatic void
203fc5a983dSmrgdoneCopy(PixmapPtr pDstPixmap)
204fc5a983dSmrg{
205fc5a983dSmrg}
206fc5a983dSmrg
207fc5a983dSmrg/* composite */
208fc5a983dSmrg
209fc5a983dSmrgstatic Bool
210fc5a983dSmrgcheckComposite(int          op,
211fc5a983dSmrg               PicturePtr   pSrc,
212fc5a983dSmrg               PicturePtr   pMask,
213fc5a983dSmrg               PicturePtr   pDst)
214fc5a983dSmrg{
215fc5a983dSmrg    return FALSE;
216fc5a983dSmrg}
217fc5a983dSmrg
218fc5a983dSmrg/* upload to screen */
219fc5a983dSmrg
220fc5a983dSmrgstatic Bool
221fc5a983dSmrgupload(PixmapPtr pDst,
222fc5a983dSmrg       int       x,
223fc5a983dSmrg       int       y,
224fc5a983dSmrg       int       w,
225fc5a983dSmrg       int       h,
226fc5a983dSmrg       char      *src,
227fc5a983dSmrg       int       src_pitch)
228fc5a983dSmrg{
229fc5a983dSmrg    ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
230fc5a983dSmrg    G80Ptr pNv = G80PTR(pScrn);
231fc5a983dSmrg    const int Bpp = pDst->drawable.bitsPerPixel >> 3;
232fc5a983dSmrg    int line_dwords = (w * Bpp + 3) / 4;
233fc5a983dSmrg    const Bool kickoff = w * h >= 512;
234fc5a983dSmrg    CARD32 depth;
235fc5a983dSmrg
236fc5a983dSmrg    if(!setDst(pNv, pDst)) return FALSE;
237fc5a983dSmrg    switch(pDst->drawable.depth) {
238fc5a983dSmrg        case  8: depth = 0x000000f3; break;
239fc5a983dSmrg        case 15: depth = 0x000000f8; break;
240fc5a983dSmrg        case 16: depth = 0x000000e8; break;
241fc5a983dSmrg        case 24: depth = 0x000000e6; break;
242fc5a983dSmrg        case 32: depth = 0x000000cf; break;
243fc5a983dSmrg        default: return FALSE;
244fc5a983dSmrg    }
245fc5a983dSmrg
246fc5a983dSmrg    G80SetClip(pNv, x, y, w, h);
247fc5a983dSmrg    G80DmaStart(pNv, 0x2ac, 1);
248fc5a983dSmrg    G80DmaNext (pNv, 3);
249fc5a983dSmrg    G80DmaStart(pNv, 0x800, 2);
250fc5a983dSmrg    G80DmaNext (pNv, 0);
251fc5a983dSmrg    G80DmaNext (pNv, depth);
252fc5a983dSmrg    G80DmaStart(pNv, 0x838, 10);
253fc5a983dSmrg    G80DmaNext (pNv, (line_dwords * 4) / Bpp);
254fc5a983dSmrg    G80DmaNext (pNv, h);
255fc5a983dSmrg    G80DmaNext (pNv, 0);
256fc5a983dSmrg    G80DmaNext (pNv, 1);
257fc5a983dSmrg    G80DmaNext (pNv, 0);
258fc5a983dSmrg    G80DmaNext (pNv, 1);
259fc5a983dSmrg    G80DmaNext (pNv, 0);
260fc5a983dSmrg    G80DmaNext (pNv, x);
261fc5a983dSmrg    G80DmaNext (pNv, 0);
262fc5a983dSmrg    G80DmaNext (pNv, y);
263fc5a983dSmrg
264fc5a983dSmrg    while(h-- > 0) {
265fc5a983dSmrg        int count = line_dwords;
266fc5a983dSmrg        char *p = src;
267fc5a983dSmrg
268fc5a983dSmrg        while(count) {
269fc5a983dSmrg            int size = count > 1792 ? 1792 : count;
270fc5a983dSmrg
271fc5a983dSmrg            G80DmaStart(pNv, 0x40000860, size);
272fc5a983dSmrg            memcpy(&pNv->dmaBase[pNv->dmaCurrent], p, size * 4);
273fc5a983dSmrg
274fc5a983dSmrg            p += size * Bpp;
275fc5a983dSmrg            pNv->dmaCurrent += size;
276fc5a983dSmrg
277fc5a983dSmrg            count -= size;
278fc5a983dSmrg        }
279fc5a983dSmrg
280fc5a983dSmrg        src += src_pitch;
281fc5a983dSmrg    }
282fc5a983dSmrg
283fc5a983dSmrg    if(kickoff)
284fc5a983dSmrg        G80DmaKickoff(pNv);
285fc5a983dSmrg    else
286fc5a983dSmrg        pNv->DMAKickoffCallback = G80DMAKickoffCallback;
287fc5a983dSmrg
288fc5a983dSmrg    return TRUE;
289fc5a983dSmrg}
290fc5a983dSmrg
291fc5a983dSmrg/******************************************************************************/
292fc5a983dSmrg
293fc5a983dSmrgBool G80ExaInit(ScreenPtr pScreen, ScrnInfoPtr pScrn)
294fc5a983dSmrg{
295fc5a983dSmrg    G80Ptr pNv = G80PTR(pScrn);
296fc5a983dSmrg    ExaDriverPtr exa;
297fc5a983dSmrg    const int pitch = pScrn->displayWidth * (pScrn->bitsPerPixel / 8);
298fc5a983dSmrg
299fc5a983dSmrg    exa = pNv->exa = exaDriverAlloc();
300fc5a983dSmrg    if(!exa) return FALSE;
301fc5a983dSmrg
302fc5a983dSmrg    exa->exa_major         = EXA_VERSION_MAJOR;
303fc5a983dSmrg    exa->exa_minor         = EXA_VERSION_MINOR;
304fc5a983dSmrg    exa->memoryBase        = pNv->mem;
305fc5a983dSmrg    exa->offScreenBase     = 0;
306fc5a983dSmrg    exa->memorySize        = pitch * pNv->offscreenHeight;
307fc5a983dSmrg    exa->pixmapOffsetAlign = 256;
308fc5a983dSmrg    exa->pixmapPitchAlign  = 256;
309fc5a983dSmrg    exa->flags             = EXA_OFFSCREEN_PIXMAPS;
310fc5a983dSmrg    exa->maxX              = 8192;
311fc5a983dSmrg    exa->maxY              = 8192;
312fc5a983dSmrg
313fc5a983dSmrg    /**** Rendering ops ****/
314fc5a983dSmrg    exa->PrepareSolid     = prepareSolid;
315fc5a983dSmrg    exa->Solid            = solid;
316fc5a983dSmrg    exa->DoneSolid        = doneSolid;
317fc5a983dSmrg    exa->PrepareCopy      = prepareCopy;
318fc5a983dSmrg    exa->Copy             = copy;
319fc5a983dSmrg    exa->DoneCopy         = doneCopy;
320fc5a983dSmrg    exa->CheckComposite   = checkComposite;
321fc5a983dSmrg    //exa->PrepareComposite = prepareComposite;
322fc5a983dSmrg    //exa->Composite        = composite;
323fc5a983dSmrg    //exa->DoneComposite    = doneComposite;
324fc5a983dSmrg    exa->UploadToScreen   = upload;
325fc5a983dSmrg
326fc5a983dSmrg    exa->WaitMarker       = waitMarker;
327fc5a983dSmrg
328fc5a983dSmrg    return exaDriverInit(pScreen, exa);
329fc5a983dSmrg}
330