First import
[xorg_rtime.git] / xorg-server-1.4 / hw / kdrive / i810 / i810draw.c
blobb571efbe0e600003300f11228f9763d44bba50db
1 /* COPYRIGHT AND PERMISSION NOTICE
3 Copyright (c) 2000, 2001 Nokia Home Communications
5 All rights reserved.
7 Permission is hereby granted, free of charge, to any person obtaining
8 a copy of this software and associated documentation files (the
9 "Software"), to deal in the Software without restriction, including
10 without limitation the rights to use, copy, modify, merge, publish,
11 distribute, and/or sell copies of the Software, and to permit persons
12 to whom the Software is furnished to do so, provided that the above
13 copyright notice(s) and this permission notice appear in all copies of
14 the Software and that both the above copyright notice(s) and this
15 permission notice appear in supporting documentation.
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
20 OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
21 HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY
22 SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER
23 RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
24 CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
25 CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
27 Except as contained in this notice, the name of a copyright holder
28 shall not be used in advertising or otherwise to promote the sale, use
29 or other dealings in this Software without prior written authorization
30 of the copyright holder.
32 X Window System is a trademark of The Open Group */
34 /* Hardware accelerated drawing for KDrive i810 driver.
35 Author: Pontus Lidman <pontus.lidman@nokia.com>
38 #ifdef HAVE_CONFIG_H
39 #include <kdrive-config.h>
40 #endif
41 #include "kdrive.h"
42 #include "kaa.h"
43 #ifdef XV
44 #include "kxv.h"
45 #endif
46 #include "i810.h"
47 #include "i810_reg.h"
49 //#include "Xmd.h"
50 #include "gcstruct.h"
51 #include "scrnintstr.h"
52 #include "pixmapstr.h"
53 #include "regionstr.h"
54 #include "mistruct.h"
55 #include "dixfontstr.h"
56 #include "fb.h"
57 #include "migc.h"
58 #include "miline.h"
59 #include "picturestr.h"
61 #define NUM_STACK_RECTS 1024
63 i810ScreenInfo *accel_i810s;
65 static int
66 i810WaitLpRing(i810ScreenInfo *i810s, int n, int timeout_millis)
68 i810CardInfo *i810c = i810s->i810c;
69 I810RingBuffer *ring = &(i810c->LpRing);
70 int iters = 0;
71 int start = 0;
72 int now = 0;
73 int last_head = 0;
74 int first = 0;
76 /* If your system hasn't moved the head pointer in 2 seconds, I'm going to
77 * call it crashed.
79 if (timeout_millis == 0)
80 timeout_millis = 2000;
82 if (I810_DEBUG) {
83 fprintf(stderr, "i810WaitLpRing %d\n", n);
84 first = GetTimeInMillis();
87 while (ring->space < n)
89 int i;
91 ring->head = INREG(LP_RING + RING_HEAD) & HEAD_ADDR;
92 ring->space = ring->head - (ring->tail+8);
94 if (ring->space < 0)
95 ring->space += ring->mem.Size;
97 iters++;
98 now = GetTimeInMillis();
99 if ( start == 0 || now < start || ring->head != last_head) {
100 if (I810_DEBUG)
101 if (now > start)
102 fprintf(stderr, "space: %d wanted %d\n", ring->space, n );
103 start = now;
104 last_head = ring->head;
105 } else if ( now - start > timeout_millis ) {
107 i810PrintErrorState(i810c);
108 fprintf(stderr, "space: %d wanted %d\n", ring->space, n );
109 FatalError("lockup\n");
112 for (i = 0 ; i < 2000 ; i++)
116 if (I810_DEBUG)
118 now = GetTimeInMillis();
119 if (now - first) {
120 fprintf(stderr,"Elapsed %d ms\n", now - first);
121 fprintf(stderr, "space: %d wanted %d\n", ring->space, n );
125 return iters;
128 static void
129 i810Sync(i810ScreenInfo *i810s)
131 i810CardInfo *i810c = i810s->i810c;
132 LP_RING_LOCALS;
134 if (I810_DEBUG)
135 fprintf(stderr, "i810Sync\n");
137 /* Send a flush instruction and then wait till the ring is empty.
138 * This is stronger than waiting for the blitter to finish as it also
139 * flushes the internal graphics caches.
141 BEGIN_LP_RING(2);
142 OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE );
143 OUT_RING( 0 ); /* pad to quadword */
144 ADVANCE_LP_RING();
146 i810WaitLpRing(i810s, i810c->LpRing.mem.Size - 8, 0);
148 i810c->LpRing.space = i810c->LpRing.mem.Size - 8;
149 i810c->nextColorExpandBuf = 0;
152 static void
153 i810WaitMarker(ScreenPtr pScreen, int marker)
155 KdScreenPriv(pScreen);
156 i810ScreenInfo(pScreenPriv);
158 i810Sync(i810s);
161 #if 0
162 static void
163 i810EmitInvarientState(ScreenPtr pScreen)
165 KdScreenPriv(pScreen);
166 i810CardInfo(pScreenPriv);
167 i810ScreenInfo(pScreenPriv);
168 LP_RING_LOCALS;
170 BEGIN_LP_RING( 10 );
172 OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE );
173 OUT_RING( GFX_CMD_CONTEXT_SEL | CS_UPDATE_USE | CS_USE_CTX0 );
174 OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE);
175 OUT_RING( 0 );
178 OUT_RING( GFX_OP_COLOR_CHROMA_KEY );
179 OUT_RING( CC1_UPDATE_KILL_WRITE |
180 CC1_DISABLE_KILL_WRITE |
181 CC1_UPDATE_COLOR_IDX |
182 CC1_UPDATE_CHROMA_LOW |
183 CC1_UPDATE_CHROMA_HI |
185 OUT_RING( 0 );
186 OUT_RING( 0 );
188 /* No depth buffer in KDrive yet */
189 /* OUT_RING( CMD_OP_Z_BUFFER_INFO ); */
190 /* OUT_RING( pI810->DepthBuffer.Start | pI810->auxPitchBits); */
192 ADVANCE_LP_RING();
194 #endif
196 static unsigned int i810PatternRop[16] = {
197 0x00, /* GXclear */
198 0xA0, /* GXand */
199 0x50, /* GXandReverse */
200 0xF0, /* GXcopy */
201 0x0A, /* GXandInvert */
202 0xAA, /* GXnoop */
203 0x5A, /* GXxor */
204 0xFA, /* GXor */
205 0x05, /* GXnor */
206 0xA5, /* GXequiv */
207 0x55, /* GXinvert */
208 0xF5, /* GXorReverse */
209 0x0F, /* GXcopyInvert */
210 0xAF, /* GXorInverted */
211 0x5F, /* GXnand */
212 0xFF /* GXset */
215 static Bool
216 i810PrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg)
218 KdScreenPriv(pPix->drawable.pScreen);
219 i810ScreenInfo(pScreenPriv);
220 i810CardInfo(pScreenPriv);
222 if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
223 ErrorF( "i810PrepareSolid color: %x rop: %x mask: %x\n",
224 fg, alu, pm);
226 /* Color blit, p166 */
227 i810c->BR[13] = BR13_SOLID_PATTERN |
228 (i810PatternRop[alu] << 16) |
229 (pPix->drawable.pScreen->width * i810c->cpp);
230 i810c->BR[16] = fg;
232 accel_i810s = i810s;
234 return TRUE;
237 static void
238 i810Solid(int x1, int y1, int x2, int y2)
240 I810ScreenInfo *i810s = accel_i810s;
241 I810CardInfo *i810c = i810s->i810c;
242 LP_RING_LOCALS;
244 if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
245 ErrorF( "i810SubsequentFillRectSolid %d,%d %d,%d\n", x1, y1, x2, y2);
247 BEGIN_LP_RING(6);
249 OUT_RING( BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3 );
250 OUT_RING( i810c->BR[13] );
251 OUT_RING( ((y2 - y1) << 16) | ((x2 - x1) * i810c->cpp));
252 OUT_RING( i810c->bufferOffset + y1 * i810s->pitch + x1 * i810c->cpp );
254 OUT_RING( i810c->BR[16]);
255 OUT_RING( 0 ); /* pad to quadword */
257 ADVANCE_LP_RING();
260 static void
261 i810DoneSolid(void)
265 static Bool
266 i810PrepareCopy(PixmapPtr pSrc, PixmapPtr pDst, int dx, int dy, int alu, Pixel pm)
268 return FALSE;
271 static void
272 i810RefreshRing(i810CardInfo *i810c)
274 i810c->LpRing.head = INREG(LP_RING + RING_HEAD) & HEAD_ADDR;
275 i810c->LpRing.tail = INREG(LP_RING + RING_TAIL);
276 i810c->LpRing.space = i810c->LpRing.head - (i810c->LpRing.tail+8);
277 if (i810c->LpRing.space < 0)
278 i810c->LpRing.space += i810c->LpRing.mem.Size;
282 static void
283 i810SetRingRegs(i810CardInfo *i810c)
285 unsigned int itemp;
287 OUTREG(LP_RING + RING_TAIL, 0 );
288 OUTREG(LP_RING + RING_HEAD, 0 );
290 itemp = INREG(LP_RING + RING_START);
291 itemp &= ~(START_ADDR);
292 itemp |= i810c->LpRing.mem.Start;
293 OUTREG(LP_RING + RING_START, itemp );
295 itemp = INREG(LP_RING + RING_LEN);
296 itemp &= ~(RING_NR_PAGES | RING_REPORT_MASK | RING_VALID_MASK);
297 itemp |= ((i810c->LpRing.mem.Size-4096) | RING_NO_REPORT | RING_VALID);
298 OUTREG(LP_RING + RING_LEN, itemp );
301 Bool
302 i810InitAccel(ScreenPtr pScreen)
304 KdScreenPriv(pScreen);
305 i810ScreenInfo(pScreenPriv);
306 i810CardInfo(pScreenPriv);
308 memset(&i810s->kaa, 0, sizeof(KaaScreenInfoRec));
309 i810s->kaa.waitMarker = i810WaitMarker;
310 i810s->kaa.PrepareSolid = i810PrepareSolid;
311 i810s->kaa.Solid = i810Solid;
312 i810s->kaa.DoneSolid = i810DoneSolid;
313 i810s->kaa.PrepareCopy = i810PrepareCopy;
314 i810s->kaa.Copy = NULL;
315 i810s->kaa.DoneCopy = NULL;
317 i810s->pitch = pScreen->width * i810c->cpp;
319 return FALSE;
322 void
323 i810EnableAccel(ScreenPtr pScreen)
325 KdScreenPriv(pScreen);
326 i810CardInfo(pScreenPriv);
328 if (i810c->LpRing.mem.Size == 0) {
329 ErrorF("No memory for LpRing!! Acceleration not functional!!\n");
332 i810SetRingRegs(i810c);
334 kaaMarkSync (pScreen);
338 void
339 i810DisableAccel(ScreenPtr pScreen)
341 KdScreenPriv(pScreen);
342 i810CardInfo(pScreenPriv);
343 i810ScreenInfo(pScreenPriv);
345 i810RefreshRing(i810c);
346 i810Sync(i810s);
349 void
350 i810FiniAccel(ScreenPtr pScreen)