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"
3172320d7bSmrg#include "g80_exa.h"
32fc5a983dSmrg#include "g80_xaa.h"
33fc5a983dSmrg
34fc5a983dSmrgstatic void
35fc5a983dSmrgwaitMarker(ScreenPtr pScreen, int marker)
36fc5a983dSmrg{
37bd304fc0Smrg    G80Sync(xf86ScreenToScrn(pScreen));
38fc5a983dSmrg}
39fc5a983dSmrg
40fc5a983dSmrgstatic Bool
41fc5a983dSmrgsetSrc(G80Ptr pNv, PixmapPtr pSrc)
42fc5a983dSmrg{
43fc5a983dSmrg    CARD32 depth;
44fc5a983dSmrg
45fc5a983dSmrg    switch(pSrc->drawable.depth) {
46fc5a983dSmrg        case  8: depth = 0x000000f3; break;
47fc5a983dSmrg        case 15: depth = 0x000000f8; break;
48fc5a983dSmrg        case 16: depth = 0x000000e8; break;
49fc5a983dSmrg        case 24: depth = 0x000000e6; break;
50fc5a983dSmrg        case 32: depth = 0x000000cf; break;
51fc5a983dSmrg        default: return FALSE;
52fc5a983dSmrg    }
53fc5a983dSmrg
54fc5a983dSmrg    G80DmaStart(pNv, 0x230, 2);
55fc5a983dSmrg    G80DmaNext (pNv, depth);
56fc5a983dSmrg    G80DmaNext (pNv, 0x00000001);
57fc5a983dSmrg    G80DmaStart(pNv, 0x244, 5);
58fc5a983dSmrg    G80DmaNext (pNv, exaGetPixmapPitch(pSrc));
59fc5a983dSmrg    G80DmaNext (pNv, pSrc->drawable.width);
60fc5a983dSmrg    G80DmaNext (pNv, pSrc->drawable.height);
61fc5a983dSmrg    G80DmaNext (pNv, 0x00000000);
62fc5a983dSmrg    G80DmaNext (pNv, exaGetPixmapOffset(pSrc));
63fc5a983dSmrg
64fc5a983dSmrg    return TRUE;
65fc5a983dSmrg}
66fc5a983dSmrg
67fc5a983dSmrgstatic Bool
68fc5a983dSmrgsetDst(G80Ptr pNv, PixmapPtr pDst)
69fc5a983dSmrg{
70fc5a983dSmrg    CARD32 depth, depth2;
71fc5a983dSmrg
72fc5a983dSmrg    switch(pDst->drawable.depth) {
73fc5a983dSmrg        case  8: depth = 0x000000f3; depth2 = 3; break;
74fc5a983dSmrg        case 15: depth = 0x000000f8; depth2 = 1; break;
75fc5a983dSmrg        case 16: depth = 0x000000e8; depth2 = 0; break;
76fc5a983dSmrg        case 24: depth = 0x000000e6; depth2 = 2; break;
77fc5a983dSmrg        case 32: depth = 0x000000cf; depth2 = 2; break;
78fc5a983dSmrg        default: return FALSE;
79fc5a983dSmrg    }
80fc5a983dSmrg
81fc5a983dSmrg    G80DmaStart(pNv, 0x200, 2);
82fc5a983dSmrg    G80DmaNext (pNv, depth);
83fc5a983dSmrg    G80DmaNext (pNv, 0x00000001);
84fc5a983dSmrg    G80DmaStart(pNv, 0x214, 5);
85fc5a983dSmrg    G80DmaNext (pNv, exaGetPixmapPitch(pDst));
86fc5a983dSmrg    G80DmaNext (pNv, pDst->drawable.width);
87fc5a983dSmrg    G80DmaNext (pNv, pDst->drawable.height);
88fc5a983dSmrg    G80DmaNext (pNv, 0x00000000);
89fc5a983dSmrg    G80DmaNext (pNv, exaGetPixmapOffset(pDst));
90fc5a983dSmrg    G80DmaStart(pNv, 0x2e8, 1);
91fc5a983dSmrg    G80DmaNext (pNv, depth2);
92fc5a983dSmrg    G80DmaStart(pNv, 0x584, 1);
93fc5a983dSmrg    G80DmaNext (pNv, depth);
94fc5a983dSmrg    G80SetClip(pNv, 0, 0, pDst->drawable.width, pDst->drawable.height);
95fc5a983dSmrg
96fc5a983dSmrg    return TRUE;
97fc5a983dSmrg}
98fc5a983dSmrg
99fc5a983dSmrg/* solid fills */
100fc5a983dSmrg
101fc5a983dSmrgstatic Bool
102fc5a983dSmrgprepareSolid(PixmapPtr      pPixmap,
103fc5a983dSmrg             int            alu,
104fc5a983dSmrg             Pixel          planemask,
105fc5a983dSmrg             Pixel          fg)
106fc5a983dSmrg{
107bd304fc0Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pPixmap->drawable.pScreen);
108fc5a983dSmrg    G80Ptr pNv = G80PTR(pScrn);
109fc5a983dSmrg
110fc5a983dSmrg    if(pPixmap->drawable.depth > 24) return FALSE;
111fc5a983dSmrg    if(!setDst(pNv, pPixmap)) return FALSE;
112fc5a983dSmrg    G80DmaStart(pNv, 0x2ac, 1);
113f3561b8bSmrg    G80DmaNext (pNv, 4);
114fc5a983dSmrg    G80SetRopSolid(pNv, alu, planemask);
115fc5a983dSmrg    G80DmaStart(pNv, 0x580, 1);
116fc5a983dSmrg    G80DmaNext (pNv, 4);
117fc5a983dSmrg    G80DmaStart(pNv, 0x588, 1);
118fc5a983dSmrg    G80DmaNext (pNv, fg);
119fc5a983dSmrg
12063a93945Smrg    pNv->DMAKickoffCallback = G80DMAKickoffCallback;
121fc5a983dSmrg    return TRUE;
122fc5a983dSmrg}
123fc5a983dSmrg
124fc5a983dSmrgstatic void
125fc5a983dSmrgsolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2)
126fc5a983dSmrg{
127bd304fc0Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pPixmap->drawable.pScreen);
128fc5a983dSmrg    G80Ptr pNv = G80PTR(pScrn);
129fc5a983dSmrg
130fc5a983dSmrg    G80DmaStart(pNv, 0x600, 4);
131fc5a983dSmrg    G80DmaNext (pNv, x1);
132fc5a983dSmrg    G80DmaNext (pNv, y1);
133fc5a983dSmrg    G80DmaNext (pNv, x2);
134fc5a983dSmrg    G80DmaNext (pNv, y2);
135fc5a983dSmrg
136fc5a983dSmrg    if((x2 - x1) * (y2 - y1) >= 512)
137fc5a983dSmrg        G80DmaKickoff(pNv);
138fc5a983dSmrg}
139fc5a983dSmrg
140fc5a983dSmrgstatic void
141fc5a983dSmrgdoneSolid(PixmapPtr pPixmap)
142fc5a983dSmrg{
143fc5a983dSmrg}
144fc5a983dSmrg
145fc5a983dSmrg/* screen to screen copies */
146fc5a983dSmrg
147fc5a983dSmrgstatic Bool
148fc5a983dSmrgprepareCopy(PixmapPtr       pSrcPixmap,
149fc5a983dSmrg            PixmapPtr       pDstPixmap,
150fc5a983dSmrg            int             dx,
151fc5a983dSmrg            int             dy,
152fc5a983dSmrg            int             alu,
153fc5a983dSmrg            Pixel           planemask)
154fc5a983dSmrg{
155bd304fc0Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pDstPixmap->drawable.pScreen);
156fc5a983dSmrg    G80Ptr pNv = G80PTR(pScrn);
157fc5a983dSmrg
158fc5a983dSmrg    if(!setSrc(pNv, pSrcPixmap)) return FALSE;
159fc5a983dSmrg    if(!setDst(pNv, pDstPixmap)) return FALSE;
160fc5a983dSmrg    G80DmaStart(pNv, 0x2ac, 1);
161fc5a983dSmrg    if(alu == GXcopy && planemask == ~0) {
162fc5a983dSmrg        G80DmaNext (pNv, 3);
163fc5a983dSmrg    } else {
164f3561b8bSmrg        G80DmaNext (pNv, 4);
165fc5a983dSmrg        G80SetRopSolid(pNv, alu, planemask);
166fc5a983dSmrg    }
16763a93945Smrg    pNv->DMAKickoffCallback = G80DMAKickoffCallback;
168fc5a983dSmrg    return TRUE;
169fc5a983dSmrg}
170fc5a983dSmrg
171fc5a983dSmrgstatic void
172fc5a983dSmrgcopy(PixmapPtr pDstPixmap,
173fc5a983dSmrg     int       srcX,
174fc5a983dSmrg     int       srcY,
175fc5a983dSmrg     int       dstX,
176fc5a983dSmrg     int       dstY,
177fc5a983dSmrg     int       width,
178fc5a983dSmrg     int       height)
179fc5a983dSmrg{
180bd304fc0Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pDstPixmap->drawable.pScreen);
181fc5a983dSmrg    G80Ptr pNv = G80PTR(pScrn);
182fc5a983dSmrg
183fc5a983dSmrg    G80DmaStart(pNv, 0x110, 1);
184fc5a983dSmrg    G80DmaNext (pNv, 0);
185fc5a983dSmrg    G80DmaStart(pNv, 0x8b0, 12);
186fc5a983dSmrg    G80DmaNext (pNv, dstX);
187fc5a983dSmrg    G80DmaNext (pNv, dstY);
188fc5a983dSmrg    G80DmaNext (pNv, width);
189fc5a983dSmrg    G80DmaNext (pNv, height);
190fc5a983dSmrg    G80DmaNext (pNv, 0);
191fc5a983dSmrg    G80DmaNext (pNv, 1);
192fc5a983dSmrg    G80DmaNext (pNv, 0);
193fc5a983dSmrg    G80DmaNext (pNv, 1);
194fc5a983dSmrg    G80DmaNext (pNv, 0);
195fc5a983dSmrg    G80DmaNext (pNv, srcX);
196fc5a983dSmrg    G80DmaNext (pNv, 0);
197fc5a983dSmrg    G80DmaNext (pNv, srcY);
198fc5a983dSmrg
199fc5a983dSmrg    if(width * height >= 512)
200fc5a983dSmrg        G80DmaKickoff(pNv);
201fc5a983dSmrg}
202fc5a983dSmrg
203fc5a983dSmrgstatic void
204fc5a983dSmrgdoneCopy(PixmapPtr pDstPixmap)
205fc5a983dSmrg{
206fc5a983dSmrg}
207fc5a983dSmrg
208fc5a983dSmrg/* composite */
209fc5a983dSmrg
210fc5a983dSmrgstatic Bool
211fc5a983dSmrgcheckComposite(int          op,
212fc5a983dSmrg               PicturePtr   pSrc,
213fc5a983dSmrg               PicturePtr   pMask,
214fc5a983dSmrg               PicturePtr   pDst)
215fc5a983dSmrg{
216fc5a983dSmrg    return FALSE;
217fc5a983dSmrg}
218fc5a983dSmrg
219fc5a983dSmrg/* upload to screen */
220fc5a983dSmrg
221fc5a983dSmrgstatic Bool
222fc5a983dSmrgupload(PixmapPtr pDst,
223fc5a983dSmrg       int       x,
224fc5a983dSmrg       int       y,
225fc5a983dSmrg       int       w,
226fc5a983dSmrg       int       h,
227fc5a983dSmrg       char      *src,
228fc5a983dSmrg       int       src_pitch)
229fc5a983dSmrg{
230bd304fc0Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pDst->drawable.pScreen);
231fc5a983dSmrg    G80Ptr pNv = G80PTR(pScrn);
232fc5a983dSmrg    const int Bpp = pDst->drawable.bitsPerPixel >> 3;
233fc5a983dSmrg    int line_dwords = (w * Bpp + 3) / 4;
234fc5a983dSmrg    const Bool kickoff = w * h >= 512;
235fc5a983dSmrg    CARD32 depth;
236fc5a983dSmrg
237fc5a983dSmrg    if(!setDst(pNv, pDst)) return FALSE;
238fc5a983dSmrg    switch(pDst->drawable.depth) {
239fc5a983dSmrg        case  8: depth = 0x000000f3; break;
240fc5a983dSmrg        case 15: depth = 0x000000f8; break;
241fc5a983dSmrg        case 16: depth = 0x000000e8; break;
242fc5a983dSmrg        case 24: depth = 0x000000e6; break;
243fc5a983dSmrg        case 32: depth = 0x000000cf; break;
244fc5a983dSmrg        default: return FALSE;
245fc5a983dSmrg    }
246fc5a983dSmrg
247fc5a983dSmrg    G80SetClip(pNv, x, y, w, h);
248fc5a983dSmrg    G80DmaStart(pNv, 0x2ac, 1);
249fc5a983dSmrg    G80DmaNext (pNv, 3);
250fc5a983dSmrg    G80DmaStart(pNv, 0x800, 2);
251fc5a983dSmrg    G80DmaNext (pNv, 0);
252fc5a983dSmrg    G80DmaNext (pNv, depth);
253fc5a983dSmrg    G80DmaStart(pNv, 0x838, 10);
254fc5a983dSmrg    G80DmaNext (pNv, (line_dwords * 4) / Bpp);
255fc5a983dSmrg    G80DmaNext (pNv, h);
256fc5a983dSmrg    G80DmaNext (pNv, 0);
257fc5a983dSmrg    G80DmaNext (pNv, 1);
258fc5a983dSmrg    G80DmaNext (pNv, 0);
259fc5a983dSmrg    G80DmaNext (pNv, 1);
260fc5a983dSmrg    G80DmaNext (pNv, 0);
261fc5a983dSmrg    G80DmaNext (pNv, x);
262fc5a983dSmrg    G80DmaNext (pNv, 0);
263fc5a983dSmrg    G80DmaNext (pNv, y);
264fc5a983dSmrg
265fc5a983dSmrg    while(h-- > 0) {
266fc5a983dSmrg        int count = line_dwords;
267fc5a983dSmrg        char *p = src;
268fc5a983dSmrg
269fc5a983dSmrg        while(count) {
270fc5a983dSmrg            int size = count > 1792 ? 1792 : count;
271fc5a983dSmrg
272fc5a983dSmrg            G80DmaStart(pNv, 0x40000860, size);
273fc5a983dSmrg            memcpy(&pNv->dmaBase[pNv->dmaCurrent], p, size * 4);
274fc5a983dSmrg
275fc5a983dSmrg            p += size * Bpp;
276fc5a983dSmrg            pNv->dmaCurrent += size;
277fc5a983dSmrg
278fc5a983dSmrg            count -= size;
279fc5a983dSmrg        }
280fc5a983dSmrg
281fc5a983dSmrg        src += src_pitch;
282fc5a983dSmrg    }
283fc5a983dSmrg
284fc5a983dSmrg    if(kickoff)
285fc5a983dSmrg        G80DmaKickoff(pNv);
286fc5a983dSmrg    else
28763a93945Smrg        pNv->DMAKickoffCallback = G80DMAKickoffCallback;
288fc5a983dSmrg
289fc5a983dSmrg    return TRUE;
290fc5a983dSmrg}
291fc5a983dSmrg
292fc5a983dSmrg/******************************************************************************/
293fc5a983dSmrg
294fc5a983dSmrgBool G80ExaInit(ScreenPtr pScreen, ScrnInfoPtr pScrn)
295fc5a983dSmrg{
296fc5a983dSmrg    G80Ptr pNv = G80PTR(pScrn);
297fc5a983dSmrg    ExaDriverPtr exa;
298fc5a983dSmrg    const int pitch = pScrn->displayWidth * (pScrn->bitsPerPixel / 8);
299fc5a983dSmrg
300fc5a983dSmrg    exa = pNv->exa = exaDriverAlloc();
301fc5a983dSmrg    if(!exa) return FALSE;
302fc5a983dSmrg
303fc5a983dSmrg    exa->exa_major         = EXA_VERSION_MAJOR;
304fc5a983dSmrg    exa->exa_minor         = EXA_VERSION_MINOR;
305fc5a983dSmrg    exa->memoryBase        = pNv->mem;
306fc5a983dSmrg    exa->offScreenBase     = 0;
307fc5a983dSmrg    exa->memorySize        = pitch * pNv->offscreenHeight;
308fc5a983dSmrg    exa->pixmapOffsetAlign = 256;
309fc5a983dSmrg    exa->pixmapPitchAlign  = 256;
310fc5a983dSmrg    exa->flags             = EXA_OFFSCREEN_PIXMAPS;
311fc5a983dSmrg    exa->maxX              = 8192;
312fc5a983dSmrg    exa->maxY              = 8192;
313fc5a983dSmrg
314fc5a983dSmrg    /**** Rendering ops ****/
315fc5a983dSmrg    exa->PrepareSolid     = prepareSolid;
316fc5a983dSmrg    exa->Solid            = solid;
317fc5a983dSmrg    exa->DoneSolid        = doneSolid;
318fc5a983dSmrg    exa->PrepareCopy      = prepareCopy;
319fc5a983dSmrg    exa->Copy             = copy;
320fc5a983dSmrg    exa->DoneCopy         = doneCopy;
321fc5a983dSmrg    exa->CheckComposite   = checkComposite;
322fc5a983dSmrg    //exa->PrepareComposite = prepareComposite;
323fc5a983dSmrg    //exa->Composite        = composite;
324fc5a983dSmrg    //exa->DoneComposite    = doneComposite;
325fc5a983dSmrg    exa->UploadToScreen   = upload;
326fc5a983dSmrg
327fc5a983dSmrg    exa->WaitMarker       = waitMarker;
328fc5a983dSmrg
329fc5a983dSmrg    return exaDriverInit(pScreen, exa);
330fc5a983dSmrg}
331