1 /*
2 * Copyright 2003 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that copyright
7 * notice and this permission notice appear in supporting documentation, and
8 * that the name of Marc Aurele La France not be used in advertising or
9 * publicity pertaining to distribution of the software without specific,
10 * written prior permission. Marc Aurele La France makes no representations
11 * about the suitability of this software for any purpose. It is provided
12 * "as-is" without express or implied warranty.
13 *
14 * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
16 * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
21 */
22 /*
23 * Copyright 1999-2000 Precision Insight, Inc., Cedar Park, Texas.
24 * All Rights Reserved.
25 *
26 * Permission is hereby granted, free of charge, to any person obtaining a copy
27 * of this software and associated documentation files (the "Software"), to
28 * deal in the Software without restriction, including without limitation the
29 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
30 * sell copies of the Software, and to permit persons to whom the Software is
31 * furnished to do so, subject to the following conditions:
32 *
33 * The above copyright notice and this permission notice (including the next
34 * paragraph) shall be included in all copies or substantial portions of the
35 * Software.
36 *
37 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
38 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
39 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
40 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
41 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
42 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
43 * DEALINGS IN THE SOFTWARE.
44 */
45 /*
46 * DRI support by:
47 * Manuel Teira
48 * Leif Delgass <ldelgass@retinalburn.net>
49 *
50 * EXA support by:
51 * Jakub Stachowski <qbast@go2.pl>
52 * George Sapountzis <gsap7@yahoo.gr>
53 */
54
55 #ifdef HAVE_CONFIG_H
56 #include "config.h"
57 #endif
58
59 #include <string.h>
60
61 #include "ati.h"
62 #include "atichip.h"
63 #include "atidri.h"
64 #include "atimach64accel.h"
65 #include "atimach64io.h"
66 #include "atipriv.h"
67 #include "atiregs.h"
68
69 #ifdef XF86DRI_DEVEL
70 #include "mach64_dri.h"
71 #include "mach64_sarea.h"
72 #endif
73
74 #ifdef USE_EXA
75 extern CARD8 ATIMach64ALU[];
76
77 extern void
78 ATIMach64ValidateClip
79 (
80 ATIPtr pATI,
81 int sc_left,
82 int sc_right,
83 int sc_top,
84 int sc_bottom
85 );
86
87 #if 0
88 #define MACH64_TRACE(x) \
89 do { \
90 ErrorF("Mach64(%s): ", __FUNCTION__); \
91 ErrorF x; \
92 } while(0)
93 #else
94 #define MACH64_TRACE(x) do { } while(0)
95 #endif
96
97 #if 0
98 #define MACH64_FALLBACK(x) \
99 do { \
100 ErrorF("Fallback(%s): ", __FUNCTION__); \
101 ErrorF x; \
102 return FALSE; \
103 } while (0)
104 #else
105 #define MACH64_FALLBACK(x) return FALSE
106 #endif
107
108 static void
Mach64WaitMarker(ScreenPtr pScreenInfo,int Marker)109 Mach64WaitMarker(ScreenPtr pScreenInfo, int Marker)
110 {
111 ATIMach64Sync(xf86ScreenToScrn(pScreenInfo));
112 }
113
114 static Bool
Mach64GetDatatypeBpp(PixmapPtr pPix,CARD32 * pix_width)115 Mach64GetDatatypeBpp(PixmapPtr pPix, CARD32 *pix_width)
116 {
117 int bpp = pPix->drawable.bitsPerPixel;
118
119 switch (bpp) {
120 case 8:
121 *pix_width =
122 SetBits(PIX_WIDTH_8BPP, DP_DST_PIX_WIDTH) |
123 SetBits(PIX_WIDTH_8BPP, DP_SRC_PIX_WIDTH) |
124 SetBits(PIX_WIDTH_1BPP, DP_HOST_PIX_WIDTH);
125 break;
126 case 16:
127 *pix_width =
128 SetBits(PIX_WIDTH_16BPP, DP_DST_PIX_WIDTH) |
129 SetBits(PIX_WIDTH_16BPP, DP_SRC_PIX_WIDTH) |
130 SetBits(PIX_WIDTH_1BPP, DP_HOST_PIX_WIDTH);
131 break;
132 case 24:
133 *pix_width =
134 SetBits(PIX_WIDTH_8BPP, DP_DST_PIX_WIDTH) |
135 SetBits(PIX_WIDTH_8BPP, DP_SRC_PIX_WIDTH) |
136 SetBits(PIX_WIDTH_1BPP, DP_HOST_PIX_WIDTH);
137 break;
138 case 32:
139 *pix_width =
140 SetBits(PIX_WIDTH_32BPP, DP_DST_PIX_WIDTH) |
141 SetBits(PIX_WIDTH_32BPP, DP_SRC_PIX_WIDTH) |
142 SetBits(PIX_WIDTH_1BPP, DP_HOST_PIX_WIDTH);
143 break;
144 default:
145 MACH64_FALLBACK(("Unsupported bpp: %d\n", bpp));
146 }
147
148 #if X_BYTE_ORDER == X_LITTLE_ENDIAN
149
150 *pix_width |= DP_BYTE_PIX_ORDER;
151
152 #endif /* X_BYTE_ORDER */
153
154 return TRUE;
155 }
156
157 static Bool
Mach64GetOffsetPitch(PixmapPtr pPix,int bpp,CARD32 * pitch_offset,unsigned int offset,unsigned int pitch)158 Mach64GetOffsetPitch(PixmapPtr pPix, int bpp, CARD32 *pitch_offset,
159 unsigned int offset, unsigned int pitch)
160 {
161 #if 0
162 ScrnInfoPtr pScreenInfo = xf86ScreenToScrn(pPix->drawable.pScreen);
163 ATIPtr pATI = ATIPTR(pScreenInfo);
164
165 if (pitch % pATI->pExa->pixmapPitchAlign != 0)
166 MACH64_FALLBACK(("Bad pitch 0x%08x\n", pitch));
167
168 if (offset % pATI->pExa->pixmapOffsetAlign != 0)
169 MACH64_FALLBACK(("Bad offset 0x%08x\n", offset));
170 #endif
171
172 /* pixels / 8 = ((bytes * 8) / bpp) / 8 = bytes / bpp */
173 pitch = pitch / bpp;
174
175 /* bytes / 8 */
176 offset = offset >> 3;
177
178 *pitch_offset = ((pitch << 22) | (offset << 0));
179
180 return TRUE;
181 }
182
183 static Bool
Mach64GetPixmapOffsetPitch(PixmapPtr pPix,CARD32 * pitch_offset)184 Mach64GetPixmapOffsetPitch(PixmapPtr pPix, CARD32 *pitch_offset)
185 {
186 CARD32 pitch, offset;
187 int bpp;
188
189 bpp = pPix->drawable.bitsPerPixel;
190 if (bpp == 24)
191 bpp = 8;
192
193 pitch = exaGetPixmapPitch(pPix);
194 offset = exaGetPixmapOffset(pPix);
195
196 return Mach64GetOffsetPitch(pPix, bpp, pitch_offset, offset, pitch);
197 }
198
199 static Bool
Mach64PrepareCopy(PixmapPtr pSrcPixmap,PixmapPtr pDstPixmap,int xdir,int ydir,int alu,Pixel planemask)200 Mach64PrepareCopy
201 (
202 PixmapPtr pSrcPixmap,
203 PixmapPtr pDstPixmap,
204 int xdir,
205 int ydir,
206 int alu,
207 Pixel planemask
208 )
209 {
210 ScrnInfoPtr pScreenInfo = xf86ScreenToScrn(pDstPixmap->drawable.pScreen);
211 ATIPtr pATI = ATIPTR(pScreenInfo);
212 CARD32 src_pitch_offset, dst_pitch_offset, dp_pix_width;
213
214 ATIDRISync(pScreenInfo);
215
216 if (!Mach64GetDatatypeBpp(pDstPixmap, &dp_pix_width))
217 return FALSE;
218 if (!Mach64GetPixmapOffsetPitch(pSrcPixmap, &src_pitch_offset))
219 return FALSE;
220 if (!Mach64GetPixmapOffsetPitch(pDstPixmap, &dst_pitch_offset))
221 return FALSE;
222
223 ATIMach64WaitForFIFO(pATI, 7);
224 outf(DP_WRITE_MASK, planemask);
225 outf(DP_PIX_WIDTH, dp_pix_width);
226 outf(SRC_OFF_PITCH, src_pitch_offset);
227 outf(DST_OFF_PITCH, dst_pitch_offset);
228
229 outf(DP_SRC, DP_MONO_SRC_ALLONES |
230 SetBits(SRC_BLIT, DP_FRGD_SRC) | SetBits(SRC_BKGD, DP_BKGD_SRC));
231 outf(DP_MIX, SetBits(ATIMach64ALU[alu], DP_FRGD_MIX));
232
233 outf(CLR_CMP_CNTL, CLR_CMP_FN_FALSE);
234
235 pATI->dst_cntl = 0;
236
237 if (ydir > 0)
238 pATI->dst_cntl |= DST_Y_DIR;
239 if (xdir > 0)
240 pATI->dst_cntl |= DST_X_DIR;
241
242 if (pATI->XModifier == 1)
243 outf(DST_CNTL, pATI->dst_cntl);
244 else
245 pATI->dst_cntl |= DST_24_ROT_EN;
246
247 return TRUE;
248 }
249
250 static void
Mach64Copy(PixmapPtr pDstPixmap,int srcX,int srcY,int dstX,int dstY,int w,int h)251 Mach64Copy
252 (
253 PixmapPtr pDstPixmap,
254 int srcX,
255 int srcY,
256 int dstX,
257 int dstY,
258 int w,
259 int h
260 )
261 {
262 ScrnInfoPtr pScreenInfo = xf86ScreenToScrn(pDstPixmap->drawable.pScreen);
263 ATIPtr pATI = ATIPTR(pScreenInfo);
264
265 srcX *= pATI->XModifier;
266 dstY *= pATI->XModifier;
267 w *= pATI->XModifier;
268
269 ATIDRISync(pScreenInfo);
270
271 /* Disable clipping if it gets in the way */
272 ATIMach64ValidateClip(pATI, dstX, dstX + w - 1, dstY, dstY + h - 1);
273
274 if (!(pATI->dst_cntl & DST_X_DIR))
275 {
276 srcX += w - 1;
277 dstX += w - 1;
278 }
279
280 if (!(pATI->dst_cntl & DST_Y_DIR))
281 {
282 srcY += h - 1;
283 dstY += h - 1;
284 }
285
286 if (pATI->XModifier != 1)
287 outf(DST_CNTL, pATI->dst_cntl | SetBits((dstX / 4) % 6, DST_24_ROT));
288
289 ATIMach64WaitForFIFO(pATI, 4);
290 outf(SRC_Y_X, SetWord(srcX, 1) | SetWord(srcY, 0));
291 outf(SRC_WIDTH1, w);
292 outf(DST_Y_X, SetWord(dstX, 1) | SetWord(dstY, 0));
293 outf(DST_HEIGHT_WIDTH, SetWord(w, 1) | SetWord(h, 0));
294
295 /*
296 * On VTB's and later, the engine will randomly not wait for a copy
297 * operation to commit its results to video memory before starting the next
298 * one. The probability of such occurrences increases with GUI_WB_FLUSH
299 * (or GUI_WB_FLUSH_P) setting, bitsPerPixel and/or CRTC clock. This
300 * would point to some kind of video memory bandwidth problem were it noti
301 * for the fact that the problem occurs less often (but still occurs) when
302 * copying larger rectangles.
303 */
304 if ((pATI->Chip >= ATI_CHIP_264VTB) && !pATI->OptionDevel)
305 {
306 exaMarkSync(pScreenInfo->pScreen); /* Force sync. */
307 exaWaitSync(pScreenInfo->pScreen); /* Sync and notify EXA. */
308 }
309 }
310
Mach64DoneCopy(PixmapPtr pDstPixmap)311 static void Mach64DoneCopy(PixmapPtr pDstPixmap) { }
312
313 static Bool
Mach64PrepareSolid(PixmapPtr pPixmap,int alu,Pixel planemask,Pixel fg)314 Mach64PrepareSolid
315 (
316 PixmapPtr pPixmap,
317 int alu,
318 Pixel planemask,
319 Pixel fg
320 )
321 {
322 ScrnInfoPtr pScreenInfo = xf86ScreenToScrn(pPixmap->drawable.pScreen);
323 ATIPtr pATI = ATIPTR(pScreenInfo);
324 CARD32 dst_pitch_offset, dp_pix_width;
325
326 ATIDRISync(pScreenInfo);
327
328 if (!Mach64GetDatatypeBpp(pPixmap, &dp_pix_width))
329 return FALSE;
330 if (!Mach64GetPixmapOffsetPitch(pPixmap, &dst_pitch_offset))
331 return FALSE;
332
333 ATIMach64WaitForFIFO(pATI, 7);
334 outf(DP_WRITE_MASK, planemask);
335 outf(DP_PIX_WIDTH, dp_pix_width);
336 outf(DST_OFF_PITCH, dst_pitch_offset);
337
338 outf(DP_SRC, DP_MONO_SRC_ALLONES |
339 SetBits(SRC_FRGD, DP_FRGD_SRC) | SetBits(SRC_BKGD, DP_BKGD_SRC));
340 outf(DP_FRGD_CLR, fg);
341 outf(DP_MIX, SetBits(ATIMach64ALU[alu], DP_FRGD_MIX));
342
343 outf(CLR_CMP_CNTL, CLR_CMP_FN_FALSE);
344
345 if (pATI->XModifier == 1)
346 outf(DST_CNTL, DST_X_DIR | DST_Y_DIR);
347
348 return TRUE;
349 }
350
351 static void
Mach64Solid(PixmapPtr pPixmap,int x1,int y1,int x2,int y2)352 Mach64Solid
353 (
354 PixmapPtr pPixmap,
355 int x1,
356 int y1,
357 int x2,
358 int y2
359 )
360 {
361 ScrnInfoPtr pScreenInfo = xf86ScreenToScrn(pPixmap->drawable.pScreen);
362 ATIPtr pATI = ATIPTR(pScreenInfo);
363
364 int x = x1;
365 int y = y1;
366 int w = x2-x1;
367 int h = y2-y1;
368
369 ATIDRISync(pScreenInfo);
370
371 if (pATI->XModifier != 1)
372 {
373 x *= pATI->XModifier;
374 w *= pATI->XModifier;
375
376 outf(DST_CNTL, SetBits((x / 4) % 6, DST_24_ROT) |
377 (DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN));
378 }
379
380 /* Disable clipping if it gets in the way */
381 ATIMach64ValidateClip(pATI, x, x + w - 1, y, y + h - 1);
382
383 ATIMach64WaitForFIFO(pATI, 2);
384 outf(DST_Y_X, SetWord(x, 1) | SetWord(y, 0));
385 outf(DST_HEIGHT_WIDTH, SetWord(w, 1) | SetWord(h, 0));
386 }
387
Mach64DoneSolid(PixmapPtr pPixmap)388 static void Mach64DoneSolid(PixmapPtr pPixmap) { }
389
390 #include "atimach64render.c"
391
392 /* Compute log base 2 of val. */
Mach64Log2(int val)393 static __inline__ int Mach64Log2(int val)
394 {
395 int bits;
396
397 for (bits = 0; val != 0; val >>= 1, ++bits)
398 ;
399 return bits - 1;
400 }
401
402 /*
403 * Memory layour for EXA with DRI (no local_textures):
404 * | front | back | depth | textures | pixmaps, xv | c |
405 *
406 * 1024x768@16bpp with 8 MB:
407 * | 1.5 MB | 1.5 MB | 1.5 MB | 0 | ~3.5 MB | c |
408 *
409 * 1024x768@32bpp with 8 MB:
410 * | 3.0 MB | 3.0 MB | 1.5 MB | 0 | ~0.5 MB | c |
411 *
412 * "c" is the hw cursor which occupies 1KB
413 */
414 static void
Mach64SetupMemEXA(ScreenPtr pScreen)415 Mach64SetupMemEXA(ScreenPtr pScreen)
416 {
417 ScrnInfoPtr pScreenInfo = xf86ScreenToScrn(pScreen);
418 ATIPtr pATI = ATIPTR(pScreenInfo);
419
420 int cpp = (pScreenInfo->bitsPerPixel + 7) / 8;
421 /* front and back buffer */
422 int bufferSize = pScreenInfo->virtualY * pScreenInfo->displayWidth * cpp;
423 /* always 16-bit z-buffer */
424 int depthSize = pScreenInfo->virtualY * pScreenInfo->displayWidth * 2;
425
426 ExaDriverPtr pExa = pATI->pExa;
427
428 pExa->memoryBase = pATI->pMemory;
429 pExa->memorySize = pScreenInfo->videoRam * 1024;
430 pExa->offScreenBase = bufferSize;
431
432 #ifdef XF86DRI_DEVEL
433 if (pATI->directRenderingEnabled)
434 {
435 ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo;
436 Bool is_pci = pATIDRIServer->IsPCI;
437
438 int textureSize = 0;
439 int pixmapCache = 0;
440 int next = 0;
441
442 /* front buffer */
443 pATIDRIServer->frontOffset = 0;
444 pATIDRIServer->frontPitch = pScreenInfo->displayWidth;
445 next += bufferSize;
446
447 /* back buffer */
448 pATIDRIServer->backOffset = next;
449 pATIDRIServer->backPitch = pScreenInfo->displayWidth;
450 next += bufferSize;
451
452 /* depth buffer */
453 pATIDRIServer->depthOffset = next;
454 pATIDRIServer->depthPitch = pScreenInfo->displayWidth;
455 next += depthSize;
456
457 /* ATIScreenInit does check for the this condition. */
458 if (next > pExa->memorySize)
459 {
460 xf86DrvMsg(pScreen->myNum, X_WARNING,
461 "DRI static buffer allocation failed, disabling DRI --"
462 "need at least %d kB video memory\n", next / 1024 );
463 ATIDRICloseScreen(pScreen);
464 pATI->directRenderingEnabled = FALSE;
465 }
466
467 /* local textures */
468
469 /* Reserve approx. half of offscreen memory for local textures */
470 textureSize = (pExa->memorySize - next) / 2;
471
472 /* In case DRI requires more offscreen memory than available,
473 * should not happen as ATIScreenInit would have not enabled DRI */
474 if (textureSize < 0)
475 textureSize = 0;
476
477 /* Try for enough pixmap cache for a full viewport */
478 pixmapCache = (pExa->memorySize - next) - textureSize;
479 if (pixmapCache < bufferSize)
480 textureSize = 0;
481
482 /* Don't allocate a local texture heap for AGP unless requested */
483 if ( !is_pci && !pATI->OptionLocalTextures )
484 textureSize = 0;
485
486 if (textureSize > 0)
487 {
488 int l = Mach64Log2(textureSize / MACH64_NR_TEX_REGIONS);
489 if (l < MACH64_LOG_TEX_GRANULARITY)
490 l = MACH64_LOG_TEX_GRANULARITY;
491 pATIDRIServer->logTextureGranularity = l;
492
493 /* Round the texture size down to the nearest whole number of
494 * texture regions.
495 */
496 textureSize = (textureSize >> l) << l;
497 }
498
499 /* Set a minimum usable local texture heap size. This will fit
500 * two 256x256 textures. We check this after any rounding of
501 * the texture area.
502 */
503 if (textureSize < 256*256 * cpp * 2)
504 textureSize = 0;
505
506 /* Disable DRI for PCI if cannot allocate a local texture heap */
507 if ( is_pci && textureSize == 0 )
508 {
509 xf86DrvMsg(pScreen->myNum, X_WARNING,
510 "Not enough memory for local textures, disabling DRI\n");
511 ATIDRICloseScreen(pScreen);
512 pATI->directRenderingEnabled = FALSE;
513 }
514
515 pATIDRIServer->textureOffset = next;
516 pATIDRIServer->textureSize = textureSize;
517 next += textureSize;
518
519 /* pExa->offScreenBase is moved to `next' when DRI gets activated */
520 }
521 #endif /* XF86DRI_DEVEL */
522
523 xf86DrvMsg(pScreen->myNum, X_INFO,
524 "EXA memory management initialized\n"
525 "\t base : %10p\n"
526 "\t offscreen: +%10lx\n"
527 "\t size : +%10lx\n"
528 "\t cursor : %10p\n",
529 pExa->memoryBase,
530 pExa->offScreenBase,
531 pExa->memorySize,
532 pATI->pCursorImage);
533
534 if (TRUE || xf86GetVerbosity() > 1)
535 {
536 int offscreen = pExa->memorySize - pExa->offScreenBase;
537 int viewport = bufferSize;
538 int dvdframe = 720*480*cpp; /* enough for single-buffered DVD */
539
540 xf86DrvMsg(pScreen->myNum, X_INFO,
541 "Will use %d kB of offscreen memory for EXA\n"
542 "\t\t or %5.2f viewports (composite)\n"
543 "\t\t or %5.2f dvdframes (xvideo)\n",
544 offscreen / 1024,
545 1.0 * offscreen / viewport,
546 1.0 * offscreen / dvdframe);
547 }
548
549 #ifdef XF86DRI_DEVEL
550 if (pATI->directRenderingEnabled)
551 {
552 ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo;
553
554 xf86DrvMsg(pScreen->myNum, X_INFO,
555 "Will use back buffer at offset 0x%x\n",
556 pATIDRIServer->backOffset);
557
558 xf86DrvMsg(pScreen->myNum, X_INFO,
559 "Will use depth buffer at offset 0x%x\n",
560 pATIDRIServer->depthOffset);
561
562 if (pATIDRIServer->textureSize > 0)
563 {
564 xf86DrvMsg(pScreen->myNum, X_INFO,
565 "Will use %d kB for local textures at offset 0x%x\n",
566 pATIDRIServer->textureSize/1024,
567 pATIDRIServer->textureOffset);
568 }
569 }
570 #endif /* XF86DRI_DEVEL */
571
572 pExa->pixmapOffsetAlign = 64;
573 pExa->pixmapPitchAlign = 64;
574
575 pExa->flags = EXA_OFFSCREEN_PIXMAPS;
576
577 pExa->maxX = ATIMach64MaxX;
578 pExa->maxY = ATIMach64MaxY;
579 }
580
ATIMach64ExaInit(ScreenPtr pScreen)581 Bool ATIMach64ExaInit(ScreenPtr pScreen)
582 {
583 ScrnInfoPtr pScreenInfo = xf86ScreenToScrn(pScreen);
584 ATIPtr pATI = ATIPTR(pScreenInfo);
585 ExaDriverPtr pExa;
586
587 pExa = exaDriverAlloc();
588 if (!pExa)
589 return FALSE;
590
591 pATI->pExa = pExa;
592
593 pExa->exa_major = 2;
594 pExa->exa_minor = 0;
595
596 Mach64SetupMemEXA(pScreen);
597
598 pExa->WaitMarker = Mach64WaitMarker;
599
600 pExa->PrepareSolid = Mach64PrepareSolid;
601 pExa->Solid = Mach64Solid;
602 pExa->DoneSolid = Mach64DoneSolid;
603
604 pExa->PrepareCopy = Mach64PrepareCopy;
605 pExa->Copy = Mach64Copy;
606 pExa->DoneCopy = Mach64DoneCopy;
607
608 if (pATI->RenderAccelEnabled) {
609 if (pATI->Chip >= ATI_CHIP_264GTPRO) {
610 /* 3D Rage Pro does not support NPOT textures. */
611 pExa->flags |= EXA_OFFSCREEN_ALIGN_POT;
612
613 pExa->CheckComposite = Mach64CheckComposite;
614 pExa->PrepareComposite = Mach64PrepareComposite;
615 pExa->Composite = Mach64Composite;
616 pExa->DoneComposite = Mach64DoneComposite;
617 } else {
618 xf86DrvMsg(pScreen->myNum, X_INFO,
619 "Render acceleration is not supported for ATI chips "
620 "earlier than the ATI 3D Rage Pro.\n");
621 pATI->RenderAccelEnabled = FALSE;
622 }
623 }
624
625 xf86DrvMsg(pScreen->myNum, X_INFO, "Render acceleration %s\n",
626 pATI->RenderAccelEnabled ? "enabled" : "disabled");
627
628 if (!exaDriverInit(pScreen, pATI->pExa)) {
629 free(pATI->pExa);
630 pATI->pExa = NULL;
631 return FALSE;
632 }
633
634 return TRUE;
635 }
636 #endif
637