2 * Copyright © 2003 Eric Anholt
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
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of Eric Anholt not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission. Eric Anholt makes no
11 * representations about the suitability of this software for any purpose. It
12 * is provided "as is" without express or implied warranty.
14 * ERIC ANHOLT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL ERIC ANHOLT 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.
24 #include <kdrive-config.h>
32 CARD8 ATISolidRop
[16] = {
33 /* GXclear */ 0x00, /* 0 */
34 /* GXand */ 0xa0, /* src AND dst */
35 /* GXandReverse */ 0x50, /* src AND NOT dst */
36 /* GXcopy */ 0xf0, /* src */
37 /* GXandInverted*/ 0x0a, /* NOT src AND dst */
38 /* GXnoop */ 0xaa, /* dst */
39 /* GXxor */ 0x5a, /* src XOR dst */
40 /* GXor */ 0xfa, /* src OR dst */
41 /* GXnor */ 0x05, /* NOT src AND NOT dst */
42 /* GXequiv */ 0xa5, /* NOT src XOR dst */
43 /* GXinvert */ 0x55, /* NOT dst */
44 /* GXorReverse */ 0xf5, /* src OR NOT dst */
45 /* GXcopyInverted*/ 0x0f, /* NOT src */
46 /* GXorInverted */ 0xaf, /* NOT src OR dst */
47 /* GXnand */ 0x5f, /* NOT src OR NOT dst */
48 /* GXset */ 0xff, /* 1 */
51 CARD8 ATIBltRop
[16] = {
52 /* GXclear */ 0x00, /* 0 */
53 /* GXand */ 0x88, /* src AND dst */
54 /* GXandReverse */ 0x44, /* src AND NOT dst */
55 /* GXcopy */ 0xcc, /* src */
56 /* GXandInverted*/ 0x22, /* NOT src AND dst */
57 /* GXnoop */ 0xaa, /* dst */
58 /* GXxor */ 0x66, /* src XOR dst */
59 /* GXor */ 0xee, /* src OR dst */
60 /* GXnor */ 0x11, /* NOT src AND NOT dst */
61 /* GXequiv */ 0x99, /* NOT src XOR dst */
62 /* GXinvert */ 0x55, /* NOT dst */
63 /* GXorReverse */ 0xdd, /* src OR NOT dst */
64 /* GXcopyInverted*/ 0x33, /* NOT src */
65 /* GXorInverted */ 0xbb, /* NOT src OR dst */
66 /* GXnand */ 0x77, /* NOT src OR NOT dst */
67 /* GXset */ 0xff, /* 1 */
71 ATIScreenInfo
*accel_atis
;
72 /* If is_24bpp is set, then we are using the accelerator in 8-bit mode due
73 * to it being broken for 24bpp, so coordinates have to be multiplied by 3.
76 CARD32 settings
, color
, src_pitch_offset
, dst_pitch_offset
;
79 float sample_offsets_x
[255];
80 float sample_offsets_y
[255];
82 #define DRAW_USING_PACKET3 0
85 ATIDrawSetup(ScreenPtr pScreen
)
87 KdScreenPriv(pScreen
);
88 ATIScreenInfo(pScreenPriv
);
89 ATICardInfo(pScreenPriv
);
92 /* XXX: this shouldn't be necessary, but fixes some R128 composite
95 /*if (!atic->is_radeon) {
96 char *mmio = atic->reg_base;
98 MMIO_OUT32(mmio, R128_REG_PC_GUI_MODE,
103 OUT_REG(ATI_REG_DEFAULT_SC_BOTTOM_RIGHT
,
104 ATI_DEFAULT_SC_RIGHT_MAX
| ATI_DEFAULT_SC_BOTTOM_MAX
);
107 if (!atic
->is_radeon
) {
108 /* Setup for R128 Composite */
110 OUT_REG(R128_REG_SCALE_3D_CNTL
,
111 R128_SCALE_3D_TEXMAP_SHADE
|
112 R128_SCALE_PIX_REPLICATE
|
113 R128_TEX_CACHE_SPLIT
|
114 R128_TEX_MAP_ALPHA_IN_TEXTURE
|
115 R128_TEX_CACHE_LINE_SIZE_4QW
);
116 OUT_REG(R128_REG_SETUP_CNTL
,
117 R128_COLOR_SOLID_COLOR
|
119 R128_TEXTURE_ST_MULT_W
|
120 R128_STARTING_VERTEX_1
|
121 R128_ENDING_VERTEX_3
|
123 OUT_REG(R128_REG_PM4_VC_FPU_SETUP
,
126 R128_FRONTFACE_SOLID
|
127 R128_FPU_COLOR_SOLID
|
128 R128_FPU_SUB_PIX_4BITS
|
130 R128_TRAP_BITS_DISABLE
|
133 R128_FLAT_SHADE_VERTEX_OGL
|
134 R128_FPU_ROUND_TRUNCATE
|
136 OUT_REG(R128_REG_PLANE_3D_MASK_C
, 0xffffffff);
137 OUT_REG(R128_REG_CONSTANT_COLOR_C
, 0xff000000);
138 OUT_REG(R128_REG_WINDOW_XY_OFFSET
, 0x00000000);
140 } else if (!atic
->is_r300
) {
141 /* Setup for R100/R200 Composite */
143 OUT_REG(RADEON_REG_RE_TOP_LEFT
, 0);
144 OUT_REG(RADEON_REG_RE_WIDTH_HEIGHT
, 0xffffffff);
145 OUT_REG(RADEON_REG_RB3D_PLANEMASK
, 0xffffffff);
146 OUT_REG(RADEON_REG_SE_CNTL
,
147 RADEON_FFACE_CULL_CCW
|
149 RADEON_VTX_PIX_CENTER_OGL
);
154 OUT_REG(RADEON_REG_SE_CNTL_STATUS
, RADEON_TCL_BYPASS
);
155 OUT_REG(RADEON_REG_SE_COORD_FMT
,
156 RADEON_VTX_XY_PRE_MULT_1_OVER_W0
|
157 RADEON_VTX_ST0_NONPARAMETRIC
|
158 RADEON_VTX_ST1_NONPARAMETRIC
|
159 RADEON_TEX1_W_ROUTING_USE_W0
);
160 OUT_REG(RADEON_REG_RB3D_DSTCACHE_MODE
,
161 RADEON_RB3D_DC_2D_CACHE_AUTOFLUSH
|
162 RADEON_RB3D_DC_3D_CACHE_AUTOFLUSH
);
166 /* XXX: The 0 below should be RADEON_TCL_BYPASS on
169 OUT_REG(R200_REG_SE_VAP_CNTL_STATUS
, 0);
170 OUT_REG(R200_REG_PP_CNTL_X
, 0);
171 OUT_REG(R200_REG_PP_TXMULTI_CTL_0
, 0);
172 OUT_REG(R200_REG_SE_VTX_STATE_CNTL
, 0);
173 OUT_REG(R200_REG_RE_CNTL
, 0);
174 /* XXX: VTX_ST_DENORMALIZED is illegal for the case of
175 * repeating textures.
177 OUT_REG(R200_REG_SE_VTE_CNTL
, R200_VTX_ST_DENORMALIZED
);
178 OUT_REG(R200_REG_SE_VAP_CNTL
,
179 R200_VAP_FORCE_W_TO_ONE
|
180 R200_VAP_VF_MAX_VTX_NUM
);
181 OUT_REG(R200_REG_RE_AUX_SCISSOR_CNTL
, 0);
182 OUT_REG(RADEON_REG_RB3D_DSTCACHE_MODE
,
183 RADEON_RB3D_DC_2D_CACHE_AUTOFLUSH
|
184 RADEON_RB3D_DC_3D_CACHE_AUTOFLUSH
|
185 R200_RB3D_DC_2D_CACHE_AUTOFREE
|
186 R200_RB3D_DC_3D_CACHE_AUTOFREE
);
193 ATIWaitMarker(ScreenPtr pScreen
, int marker
)
195 KdScreenPriv(pScreen
);
196 ATIScreenInfo(pScreenPriv
);
204 RadeonSwitchTo2D(ATIScreenInfo
*atis
)
210 OUT_REG(RADEON_REG_RB3D_DSTCACHE_CTLSTAT
, RADEON_RB3D_DC_FLUSH
);
211 OUT_REG(ATI_REG_WAIT_UNTIL
,
212 RADEON_WAIT_HOST_IDLECLEAN
| RADEON_WAIT_3D_IDLECLEAN
);
218 RadeonSwitchTo3D(ATIScreenInfo
*atis
)
224 OUT_REG(RADEON_REG_RB3D_DSTCACHE_CTLSTAT
, RADEON_RB3D_DC_FLUSH
);
225 /* We must wait for 3d to idle, in case source was just written as a dest. */
226 OUT_REG(ATI_REG_WAIT_UNTIL
,
227 RADEON_WAIT_HOST_IDLECLEAN
| RADEON_WAIT_2D_IDLECLEAN
| RADEON_WAIT_3D_IDLECLEAN
);
234 ATIEnterDraw (PixmapPtr pPix
, char *function
)
237 KdScreenPriv(pPix
->drawable
.pScreen
);
240 offset
= ((CARD8
*)pPix
->devPrivate
.ptr
-
241 pScreenPriv
->screen
->memory_base
);
243 ErrorF ("Enter %s 0x%x (%dx%dx%d/%d)\n", function
, offset
,
244 pPix
->drawable
.width
, pPix
->drawable
.height
, pPix
->drawable
.depth
,
245 pPix
->drawable
.bitsPerPixel
);
247 ErrorF ("Enter %s\n", function
);
251 ATILeaveDraw (PixmapPtr pPix
, char *function
)
254 KdScreenPriv(pPix
->drawable
.pScreen
);
257 offset
= ((CARD8
*)pPix
->devPrivate
.ptr
-
258 pScreenPriv
->screen
->memory_base
);
260 ErrorF ("Leave %s 0x%x\n", function
, offset
);
262 ErrorF ("Leave %s\n", function
);
266 /* Assumes that depth 15 and 16 can be used as depth 16, which is okay since we
267 * require src and dest datatypes to be equal.
270 ATIGetDatatypeBpp(int bpp
, CARD32
*type
)
274 *type
= R128_DATATYPE_CI8
;
277 *type
= R128_DATATYPE_RGB565
;
280 *type
= R128_DATATYPE_CI8
;
283 *type
= R128_DATATYPE_ARGB8888
;
286 ATI_FALLBACK(("Unsupported bpp: %d\n", bpp
));
292 ATIGetOffsetPitch(ATIScreenInfo
*atis
, int bpp
, CARD32
*pitch_offset
,
293 int offset
, int pitch
)
295 ATICardInfo
*atic
= atis
->atic
;
297 /* On the R128, depending on the bpp the screen can be set up so that it
298 * doesn't meet the pitchAlign requirement but can still be
299 * accelerated, so we check the specific pitch requirement of alignment
302 if (atic
->is_radeon
) {
303 if (pitch
% atis
->kaa
.pitchAlign
!= 0)
304 ATI_FALLBACK(("Bad pitch 0x%08x\n", pitch
));
305 *pitch_offset
= ((pitch
>> 6) << 22) | (offset
>> 10);
308 if (pitch
% bpp
!= 0)
309 ATI_FALLBACK(("Bad pitch 0x%08x\n", pitch
));
310 *pitch_offset
= ((pitch
/ bpp
) << 21) | (offset
>> 5);
313 if (offset
% atis
->kaa
.offsetAlign
!= 0)
314 ATI_FALLBACK(("Bad offset 0x%08x\n", offset
));
320 ATIGetPixmapOffsetPitch(PixmapPtr pPix
, CARD32
*pitch_offset
)
322 KdScreenPriv(pPix
->drawable
.pScreen
);
323 ATIScreenInfo(pScreenPriv
);
324 CARD32 pitch
, offset
;
327 bpp
= pPix
->drawable
.bitsPerPixel
;
331 offset
= ((CARD8
*)pPix
->devPrivate
.ptr
-
332 pScreenPriv
->screen
->memory_base
);
333 pitch
= pPix
->devKind
;
335 return ATIGetOffsetPitch(atis
, bpp
, pitch_offset
, offset
, pitch
);
339 ATIPrepareSolid(PixmapPtr pPix
, int alu
, Pixel pm
, Pixel fg
)
341 KdScreenPriv(pPix
->drawable
.pScreen
);
342 ATIScreenInfo(pScreenPriv
);
343 ATICardInfo(pScreenPriv
);
347 is_24bpp
= (pPix
->drawable
.bitsPerPixel
== 24);
351 /* Solid fills in fake-24bpp mode only work if the pixel color
352 * and planemask are all the same byte.
354 if ((fg
& 0xffffff) != (((fg
& 0xff) << 16) | ((fg
>> 8) &
356 ATI_FALLBACK(("Can't do solid color 0x%08x in 24bpp\n",
358 if ((pm
& 0xffffff) != (((pm
& 0xff) << 16) | ((pm
>> 8) &
360 ATI_FALLBACK(("Can't do planemask 0x%08x in 24bpp\n",
364 if (!ATIGetDatatypeBpp(pPix
->drawable
.bitsPerPixel
, &datatype
))
366 if (!ATIGetPixmapOffsetPitch(pPix
, &dst_pitch_offset
))
372 RadeonSwitchTo2D(atis
);
375 ATI_GMC_DST_PITCH_OFFSET_CNTL
|
376 ATI_GMC_BRUSH_SOLID_COLOR
|
378 ATI_GMC_SRC_DATATYPE_COLOR
|
379 (ATISolidRop
[alu
] << 16) |
380 ATI_GMC_CLR_CMP_CNTL_DIS
|
381 R128_GMC_AUX_CLIP_DIS
;
384 #if DRAW_USING_PACKET3
386 OUT_REG(ATI_REG_DEFAULT_SC_BOTTOM_RIGHT
,
387 ATI_DEFAULT_SC_RIGHT_MAX
| ATI_DEFAULT_SC_BOTTOM_MAX
);
388 OUT_REG(ATI_REG_DP_WRITE_MASK
, pm
);
389 OUT_REG(ATI_REG_DP_CNTL
, ATI_DST_X_LEFT_TO_RIGHT
|
390 ATI_DST_Y_TOP_TO_BOTTOM
);
394 OUT_REG(ATI_REG_DEFAULT_SC_BOTTOM_RIGHT
,
395 ATI_DEFAULT_SC_RIGHT_MAX
| ATI_DEFAULT_SC_BOTTOM_MAX
);
396 OUT_REG(ATI_REG_DST_PITCH_OFFSET
, dst_pitch_offset
);
397 OUT_REG(ATI_REG_DP_GUI_MASTER_CNTL
, settings
);
398 OUT_REG(ATI_REG_DP_BRUSH_FRGD_CLR
, fg
);
399 OUT_REG(ATI_REG_DP_WRITE_MASK
, pm
);
400 OUT_REG(ATI_REG_DP_CNTL
, ATI_DST_X_LEFT_TO_RIGHT
|
401 ATI_DST_Y_TOP_TO_BOTTOM
);
410 ATISolid(int x1
, int y1
, int x2
, int y2
)
413 ATIScreenInfo
*atis
= accel_atis
;
420 #if DRAW_USING_PACKET3
422 OUT_RING(DMA_PACKET3(ATI_CCE_PACKET3_PAINT_MULTI
, 5));
424 OUT_RING(dst_pitch_offset
);
426 OUT_RING((x1
<< 16) | y1
);
427 OUT_RING(((x2
- x1
) << 16) | (y2
- y1
));
431 OUT_RING(DMA_PACKET0(ATI_REG_DST_Y_X
, 2));
432 OUT_RING_REG(ATI_REG_DST_Y_X
, (y1
<< 16) | x1
);
433 OUT_RING_REG(ATI_REG_DST_HEIGHT_WIDTH
, ((y2
- y1
) << 16) | (x2
- x1
));
447 ATIPrepareCopy(PixmapPtr pSrc
, PixmapPtr pDst
, int dx
, int dy
, int alu
, Pixel pm
)
449 KdScreenPriv(pDst
->drawable
.pScreen
);
450 ATIScreenInfo(pScreenPriv
);
451 ATICardInfo(pScreenPriv
);
457 is_24bpp
= pDst
->drawable
.bitsPerPixel
== 24;
460 if (is_24bpp
&& ((pm
& 0xffffff) != (((pm
& 0xff) << 16) | ((pm
>> 8) &
462 ATI_FALLBACK(("Can't do planemask 0x%08x in 24bpp\n", pm
));
464 if (!ATIGetDatatypeBpp(pDst
->drawable
.bitsPerPixel
, &datatype
))
466 if (!ATIGetPixmapOffsetPitch(pSrc
, &src_pitch_offset
))
468 if (!ATIGetPixmapOffsetPitch(pDst
, &dst_pitch_offset
))
473 RadeonSwitchTo2D(atis
);
476 ATI_GMC_SRC_PITCH_OFFSET_CNTL
|
477 ATI_GMC_DST_PITCH_OFFSET_CNTL
|
480 ATI_GMC_SRC_DATATYPE_COLOR
|
481 (ATIBltRop
[alu
] << 16) |
482 ATI_DP_SRC_SOURCE_MEMORY
|
483 ATI_GMC_CLR_CMP_CNTL_DIS
|
484 R128_GMC_AUX_CLIP_DIS
;
486 #if DRAW_USING_PACKET3
488 OUT_REG(ATI_REG_DEFAULT_SC_BOTTOM_RIGHT
,
489 ATI_DEFAULT_SC_RIGHT_MAX
| ATI_DEFAULT_SC_BOTTOM_MAX
);
490 OUT_REG(ATI_REG_DP_WRITE_MASK
, pm
);
491 OUT_REG(ATI_REG_DP_CNTL
,
492 (dx
>= 0 ? ATI_DST_X_LEFT_TO_RIGHT
: 0) |
493 (dy
>= 0 ? ATI_DST_Y_TOP_TO_BOTTOM
: 0));
498 OUT_REG(ATI_REG_DEFAULT_SC_BOTTOM_RIGHT
,
499 ATI_DEFAULT_SC_RIGHT_MAX
| ATI_DEFAULT_SC_BOTTOM_MAX
);
500 OUT_REG(ATI_REG_SRC_PITCH_OFFSET
, src_pitch_offset
);
501 OUT_REG(ATI_REG_DST_PITCH_OFFSET
, dst_pitch_offset
);
502 OUT_REG(ATI_REG_DP_GUI_MASTER_CNTL
, settings
);
503 OUT_REG(ATI_REG_DP_WRITE_MASK
, pm
);
504 OUT_REG(ATI_REG_DP_CNTL
,
505 (dx
>= 0 ? ATI_DST_X_LEFT_TO_RIGHT
: 0) |
506 (dy
>= 0 ? ATI_DST_Y_TOP_TO_BOTTOM
: 0));
515 ATICopy(int srcX
, int srcY
, int dstX
, int dstY
, int w
, int h
)
517 ATIScreenInfo
*atis
= accel_atis
;
526 #if !DRAW_USING_PACKET3
538 #if DRAW_USING_PACKET3
540 OUT_RING(DMA_PACKET3(ATI_CCE_PACKET3_BITBLT_MULTI
, 6));
542 OUT_RING(src_pitch_offset
);
543 OUT_RING(dst_pitch_offset
);
544 OUT_RING((srcX
<< 16) | srcY
);
545 OUT_RING((dstX
<< 16) | dstY
);
546 OUT_RING((w
<< 16) | h
);
550 OUT_RING(DMA_PACKET0(ATI_REG_SRC_Y_X
, 3));
551 OUT_RING_REG(ATI_REG_SRC_Y_X
, (srcY
<< 16) | srcX
);
552 OUT_RING_REG(ATI_REG_DST_Y_X
, (dstY
<< 16) | dstX
);
553 OUT_RING_REG(ATI_REG_DST_HEIGHT_WIDTH
, (h
<< 16) | w
);
564 ATIUploadToScreen(PixmapPtr pDst
, char *src
, int src_pitch
)
566 ScreenPtr pScreen
= pDst
->drawable
.pScreen
;
567 KdScreenPriv(pScreen
);
568 ATIScreenInfo(pScreenPriv
);
569 ATICardInfo(pScreenPriv
);
570 int width
, height
, bpp
, i
, dwords
;
571 int dst_pitch
, dst_offset
;
572 CARD32 dst_pitch_offset
, datatype
;
579 /* XXX: Hostdata uploads aren't working yet. */
582 dst_offset
= ((CARD8
*)pDst
->devPrivate
.ptr
-
583 pScreenPriv
->screen
->memory_base
);
584 dst_pitch
= pDst
->devKind
;
585 width
= pDst
->drawable
.width
;
586 height
= pDst
->drawable
.height
;
587 bpp
= pDst
->drawable
.bitsPerPixel
;
589 success
= ATIGetDatatypeBpp(bpp
, &datatype
);
597 if (!ATIGetOffsetPitch(atis
, bpp
, &dst_pitch_offset
, dst_offset
,
601 if (src_pitch
!= (width
* bpp
/ 8))
604 /* No PACKET3 packets when in PIO mode. */
608 dwords
= (width
* height
* (bpp
/ 8) + 3) / 4;
610 /* Flush pixel cache so nothing being written to the destination
611 * previously gets mixed up with the hostdata blit.
613 if (atic
->is_radeon
) {
615 OUT_REG(RADEON_REG_RB3D_DSTCACHE_CTLSTAT
, RADEON_RB3D_DC_FLUSH
);
616 OUT_REG(ATI_REG_WAIT_UNTIL
,
617 RADEON_WAIT_2D_IDLECLEAN
|
618 RADEON_WAIT_3D_IDLECLEAN
|
619 RADEON_WAIT_HOST_IDLECLEAN
);
623 OUT_REG(R128_REG_PC_GUI_CTLSTAT
,
624 R128_PC_FLUSH_GUI
| R128_PC_RI_GUI
);
629 OUT_RING(DMA_PACKET3(ATI_CCE_PACKET3_HOSTDATA_BLT
, 7 + dwords
));
630 OUT_RING(ATI_GMC_DST_PITCH_OFFSET_CNTL
|
633 ATI_GMC_SRC_DATATYPE_COLOR
|
634 (ATISolidRop
[GXcopy
] << 16) |
635 ATI_DP_SRC_SOURCE_HOST_DATA
|
636 ATI_GMC_CLR_CMP_CNTL_DIS
|
637 R128_GMC_AUX_CLIP_DIS
|
639 OUT_RING(dst_pitch_offset
);
640 OUT_RING(0xffffffff);
641 OUT_RING(0xffffffff);
642 OUT_RING((0 << 16) | 0);
643 OUT_RING((height
<< 16) | width
);
647 for (i
= 0; i
< dwords
; i
++) {
649 OUT_RING(((CARD32
*)src
)[i
]);
653 if (atic
->is_radeon
) {
655 OUT_REG(RADEON_REG_RB3D_DSTCACHE_CTLSTAT
,
656 RADEON_RB3D_DC_FLUSH_ALL
);
657 OUT_REG(ATI_REG_WAIT_UNTIL
,
658 RADEON_WAIT_2D_IDLECLEAN
|
659 RADEON_WAIT_HOST_IDLECLEAN
);
663 OUT_REG(R128_REG_PC_GUI_CTLSTAT
, R128_PC_FLUSH_GUI
);
667 kaaMarkSync(pScreen
);
669 ErrorF("hostdata upload %d,%d %dbpp\n", width
, height
, bpp
);
676 ATIUploadToScratch(PixmapPtr pSrc
, PixmapPtr pDst
)
678 KdScreenPriv(pSrc
->drawable
.pScreen
);
679 ATICardInfo(pScreenPriv
);
680 ATIScreenInfo(pScreenPriv
);
681 int dst_pitch
, src_pitch
, w
, i
, size
, bytes
;
682 unsigned char *dst
, *src
;
686 /* Align width to log 2, useful for R128 composite. This should be a
687 * KAA flag we check for (and supported in kaa.c in general) since many
688 * older bits of hardware are going to want POT pitches.
690 w
= pSrc
->drawable
.width
;
691 if (atis
->kaa
.flags
& KAA_OFFSCREEN_ALIGN_POT
)
692 w
= 1 << (ATILog2(w
- 1) + 1);
693 dst_pitch
= (w
* pSrc
->drawable
.bitsPerPixel
/ 8 +
694 atis
->kaa
.pitchAlign
- 1) & ~(atis
->kaa
.pitchAlign
- 1);
696 size
= dst_pitch
* pSrc
->drawable
.height
;
697 if (size
> atis
->scratch_area
->size
)
698 ATI_FALLBACK(("Pixmap too large for scratch (%d,%d)\n",
699 pSrc
->drawable
.width
, pSrc
->drawable
.height
));
701 atis
->scratch_next
= (atis
->scratch_next
+ atis
->kaa
.offsetAlign
- 1) &
702 ~(atis
->kaa
.offsetAlign
- 1);
703 if (atis
->scratch_next
+ size
> atis
->scratch_area
->offset
+
704 atis
->scratch_area
->size
) {
705 /* Only sync when we've used all of the scratch area. */
706 kaaWaitSync(pSrc
->drawable
.pScreen
);
707 atis
->scratch_next
= atis
->scratch_area
->offset
;
709 memcpy(pDst
, pSrc
, sizeof(*pDst
));
710 pDst
->devKind
= dst_pitch
;
711 pDst
->devPrivate
.ptr
= pScreenPriv
->screen
->memory_base
+
713 atis
->scratch_next
+= size
;
715 src
= pSrc
->devPrivate
.ptr
;
716 src_pitch
= pSrc
->devKind
;
717 dst
= pDst
->devPrivate
.ptr
;
718 bytes
= src_pitch
< dst_pitch
? src_pitch
: dst_pitch
;
720 i
= pSrc
->drawable
.height
;
722 memcpy(dst
, src
, bytes
);
727 /* Flush the pixel cache */
728 if (atic
->is_radeon
) {
730 OUT_REG(RADEON_REG_RB3D_DSTCACHE_CTLSTAT
,
731 RADEON_RB3D_DC_FLUSH_ALL
);
732 OUT_REG(ATI_REG_WAIT_UNTIL
, RADEON_WAIT_HOST_IDLECLEAN
);
736 OUT_REG(R128_REG_PC_GUI_CTLSTAT
, R128_PC_FLUSH_ALL
);
745 ATIBlockHandler(pointer blockData
, OSTimePtr timeout
, pointer readmask
)
747 ScreenPtr pScreen
= (ScreenPtr
) blockData
;
748 KdScreenPriv(pScreen
);
749 ATIScreenInfo(pScreenPriv
);
751 /* When the server is going to sleep, make sure that all DMA data has
754 if (atis
->indirectBuffer
)
755 ATIFlushIndirect(atis
, 1);
759 ATIWakeupHandler(pointer blockData
, int result
, pointer readmask
)
764 ATIDrawInit(ScreenPtr pScreen
)
766 KdScreenPriv(pScreen
);
767 ATIScreenInfo(pScreenPriv
);
768 ATICardInfo(pScreenPriv
);
770 ErrorF("Screen: %d/%d depth/bpp\n", pScreenPriv
->screen
->fb
[0].depth
,
771 pScreenPriv
->screen
->fb
[0].bitsPerPixel
);
773 RegisterBlockAndWakeupHandlers(ATIBlockHandler
, ATIWakeupHandler
,
777 atis
->using_dri
= ATIDRIScreenInit(pScreen
);
780 memset(&atis
->kaa
, 0, sizeof(KaaScreenInfoRec
));
781 atis
->kaa
.waitMarker
= ATIWaitMarker
;
782 atis
->kaa
.PrepareSolid
= ATIPrepareSolid
;
783 atis
->kaa
.Solid
= ATISolid
;
784 atis
->kaa
.DoneSolid
= ATIDoneSolid
;
785 atis
->kaa
.PrepareCopy
= ATIPrepareCopy
;
786 atis
->kaa
.Copy
= ATICopy
;
787 atis
->kaa
.DoneCopy
= ATIDoneCopy
;
788 /* Other acceleration will be hooked in in DrawEnable depending on
789 * what type of DMA gets initialized.
792 atis
->kaa
.flags
= KAA_OFFSCREEN_PIXMAPS
;
793 if (atic
->is_radeon
) {
794 atis
->kaa
.offsetAlign
= 1024;
795 atis
->kaa
.pitchAlign
= 64;
797 /* Rage 128 compositing wants power-of-two pitches. */
798 atis
->kaa
.flags
|= KAA_OFFSCREEN_ALIGN_POT
;
799 atis
->kaa
.offsetAlign
= 32;
800 /* Pitch alignment is in sets of 8 pixels, and we need to cover
801 * 32bpp, so 32 bytes.
803 atis
->kaa
.pitchAlign
= 32;
806 kaaInitTrapOffsets(8, sample_offsets_x
, sample_offsets_y
, 0.0, 0.0);
807 sample_count
= (1 << 8) - 1;
809 if (!kaaDrawInit(pScreen
, &atis
->kaa
))
816 ATIScratchSave(ScreenPtr pScreen
, KdOffscreenArea
*area
)
818 KdScreenPriv(pScreen
);
819 ATIScreenInfo(pScreenPriv
);
821 atis
->scratch_area
= NULL
;
825 ATIDrawEnable(ScreenPtr pScreen
)
827 KdScreenPriv(pScreen
);
828 ATIScreenInfo(pScreenPriv
);
829 ATICardInfo(pScreenPriv
);
831 ATIDMASetup(pScreen
);
832 ATIDrawSetup(pScreen
);
834 atis
->scratch_area
= NULL
;
835 atis
->kaa
.PrepareBlend
= NULL
;
836 atis
->kaa
.Blend
= NULL
;
837 atis
->kaa
.DoneBlend
= NULL
;
838 atis
->kaa
.CheckComposite
= NULL
;
839 atis
->kaa
.PrepareComposite
= NULL
;
840 atis
->kaa
.Composite
= NULL
;
841 atis
->kaa
.DoneComposite
= NULL
;
842 atis
->kaa
.UploadToScreen
= NULL
;
843 atis
->kaa
.UploadToScratch
= NULL
;
845 /* We can't dispatch 3d commands in PIO mode. */
846 if (!atis
->using_pio
) {
847 if (!atic
->is_radeon
) {
848 atis
->kaa
.CheckComposite
= R128CheckComposite
;
849 atis
->kaa
.PrepareComposite
= R128PrepareComposite
;
850 atis
->kaa
.Composite
= R128Composite
;
851 atis
->kaa
.DoneComposite
= R128DoneComposite
;
852 } else if (atic
->is_r100
) {
853 atis
->kaa
.CheckComposite
= R100CheckComposite
;
854 atis
->kaa
.PrepareComposite
= R100PrepareComposite
;
855 atis
->kaa
.Composite
= RadeonComposite
;
856 atis
->kaa
.DoneComposite
= RadeonDoneComposite
;
857 } else if (atic
->is_r200
) {
858 atis
->kaa
.CheckComposite
= R200CheckComposite
;
859 atis
->kaa
.PrepareComposite
= R200PrepareComposite
;
860 atis
->kaa
.Composite
= RadeonComposite
;
861 atis
->kaa
.DoneComposite
= RadeonDoneComposite
;
865 if (atis
->using_dri
) {
866 if (!atic
->is_radeon
) {
867 /*atis->kaa.PrepareTrapezoids = R128PrepareTrapezoids;
868 atis->kaa.Trapezoids = R128Trapezoids;
869 atis->kaa.DoneTrapezoids = R128DoneTrapezoids;*/
870 } else if (atic
->is_r100
|| atic
->is_r200
) {
871 atis
->kaa
.PrepareTrapezoids
= RadeonPrepareTrapezoids
;
872 atis
->kaa
.Trapezoids
= RadeonTrapezoids
;
873 atis
->kaa
.DoneTrapezoids
= RadeonDoneTrapezoids
;
878 atis
->kaa
.UploadToScreen
= ATIUploadToScreen
;
880 /* Reserve a scratch area. It'll be used for storing glyph data during
881 * Composite operations, because glyphs aren't in real pixmaps and thus
884 atis
->scratch_area
= KdOffscreenAlloc(pScreen
, 131072,
885 atis
->kaa
.offsetAlign
, TRUE
, ATIScratchSave
, atis
);
886 if (atis
->scratch_area
!= NULL
) {
887 atis
->scratch_next
= atis
->scratch_area
->offset
;
888 atis
->kaa
.UploadToScratch
= ATIUploadToScratch
;
891 kaaMarkSync(pScreen
);
895 ATIDrawDisable(ScreenPtr pScreen
)
897 kaaWaitSync(pScreen
);
898 ATIDMATeardown(pScreen
);
902 ATIDrawFini(ScreenPtr pScreen
)
905 KdScreenPriv(pScreen
);
906 ATIScreenInfo(pScreenPriv
);
907 if (atis
->using_dri
) {
908 ATIDRICloseScreen(pScreen
);
909 atis
->using_dri
= FALSE
;
913 RemoveBlockAndWakeupHandlers(ATIBlockHandler
, ATIWakeupHandler
,
916 kaaDrawFini(pScreen
);