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>
31 extern ATIScreenInfo
*accel_atis
;
32 extern int sample_count
;
33 extern float sample_offsets_x
[255];
34 extern float sample_offsets_y
[255];
35 static Bool is_transform
[2];
36 static PictTransform
*transform
[2];
44 static struct blendinfo RadeonBlendOp
[] = {
46 {0, 0, RADEON_SBLEND_GL_ZERO
| RADEON_DBLEND_GL_ZERO
},
48 {0, 0, RADEON_SBLEND_GL_ONE
| RADEON_DBLEND_GL_ZERO
},
50 {0, 0, RADEON_SBLEND_GL_ZERO
| RADEON_DBLEND_GL_ONE
},
52 {0, 1, RADEON_SBLEND_GL_ONE
| RADEON_DBLEND_GL_INV_SRC_ALPHA
},
54 {1, 0, RADEON_SBLEND_GL_INV_DST_ALPHA
| RADEON_DBLEND_GL_ONE
},
56 {1, 0, RADEON_SBLEND_GL_DST_ALPHA
| RADEON_DBLEND_GL_ZERO
},
58 {0, 1, RADEON_SBLEND_GL_ZERO
| RADEON_DBLEND_GL_SRC_ALPHA
},
60 {1, 0, RADEON_SBLEND_GL_INV_DST_ALPHA
| RADEON_DBLEND_GL_ZERO
},
62 {0, 1, RADEON_SBLEND_GL_ZERO
| RADEON_DBLEND_GL_INV_SRC_ALPHA
},
64 {1, 1, RADEON_SBLEND_GL_DST_ALPHA
| RADEON_DBLEND_GL_INV_SRC_ALPHA
},
66 {1, 1, RADEON_SBLEND_GL_INV_DST_ALPHA
| RADEON_DBLEND_GL_SRC_ALPHA
},
68 {1, 1, RADEON_SBLEND_GL_INV_DST_ALPHA
| RADEON_DBLEND_GL_INV_SRC_ALPHA
},
70 {0, 0, RADEON_SBLEND_GL_ONE
| RADEON_DBLEND_GL_ONE
},
79 /* Note on texture formats:
80 * TXFORMAT_Y8 expands to (Y,Y,Y,1). TXFORMAT_I8 expands to (I,I,I,I)
82 static struct formatinfo R100TexFormats
[] = {
83 {PICT_a8r8g8b8
, 0, RADEON_TXFORMAT_ARGB8888
| RADEON_TXFORMAT_ALPHA_IN_MAP
},
84 {PICT_x8r8g8b8
, 0, RADEON_TXFORMAT_ARGB8888
},
85 {PICT_a8b8g8r8
, 1, RADEON_TXFORMAT_RGBA8888
| RADEON_TXFORMAT_ALPHA_IN_MAP
},
86 {PICT_x8b8g8r8
, 1, RADEON_TXFORMAT_RGBA8888
},
87 {PICT_r5g6b5
, 0, RADEON_TXFORMAT_RGB565
},
88 {PICT_a1r5g5b5
, 0, RADEON_TXFORMAT_ARGB1555
| RADEON_TXFORMAT_ALPHA_IN_MAP
},
89 {PICT_x1r5g5b5
, 0, RADEON_TXFORMAT_ARGB1555
},
90 {PICT_a8
, 0, RADEON_TXFORMAT_I8
| RADEON_TXFORMAT_ALPHA_IN_MAP
},
93 static struct formatinfo R200TexFormats
[] = {
94 {PICT_a8r8g8b8
, 0, R200_TXFORMAT_ARGB8888
| R200_TXFORMAT_ALPHA_IN_MAP
},
95 {PICT_x8r8g8b8
, 0, R200_TXFORMAT_ARGB8888
},
96 {PICT_a8r8g8b8
, 1, R200_TXFORMAT_RGBA8888
| R200_TXFORMAT_ALPHA_IN_MAP
},
97 {PICT_x8r8g8b8
, 1, R200_TXFORMAT_RGBA8888
},
98 {PICT_r5g6b5
, 0, R200_TXFORMAT_RGB565
},
99 {PICT_a1r5g5b5
, 0, R200_TXFORMAT_ARGB1555
| R200_TXFORMAT_ALPHA_IN_MAP
},
100 {PICT_x1r5g5b5
, 0, R200_TXFORMAT_ARGB1555
},
101 {PICT_a8
, 0, R200_TXFORMAT_I8
| R200_TXFORMAT_ALPHA_IN_MAP
},
104 /* Common Radeon setup code */
107 RadeonGetDestFormat(PicturePtr pDstPicture
, CARD32
*dst_format
)
109 switch (pDstPicture
->format
) {
112 *dst_format
= RADEON_COLOR_FORMAT_ARGB8888
;
115 *dst_format
= RADEON_COLOR_FORMAT_RGB565
;
119 *dst_format
= RADEON_COLOR_FORMAT_ARGB1555
;
122 *dst_format
= RADEON_COLOR_FORMAT_RGB8
;
125 ATI_FALLBACK(("Unsupported dest format 0x%x\n",
126 pDstPicture
->format
));
132 /* R100-specific code */
135 R100CheckCompositeTexture(PicturePtr pPict
, int unit
)
137 int w
= pPict
->pDrawable
->width
;
138 int h
= pPict
->pDrawable
->height
;
141 if ((w
> 0x7ff) || (h
> 0x7ff))
142 ATI_FALLBACK(("Picture w/h too large (%dx%d)\n", w
, h
));
144 for (i
= 0; i
< sizeof(R100TexFormats
) / sizeof(R100TexFormats
[0]); i
++)
146 if (R100TexFormats
[i
].fmt
== pPict
->format
)
149 if (i
== sizeof(R100TexFormats
) / sizeof(R100TexFormats
[0]))
150 ATI_FALLBACK(("Unsupported picture format 0x%x\n",
153 if (pPict
->repeat
&& ((w
& (w
- 1)) != 0 || (h
& (h
- 1)) != 0))
154 ATI_FALLBACK(("NPOT repeat unsupported (%dx%d)\n", w
, h
));
156 if (pPict
->filter
!= PictFilterNearest
&&
157 pPict
->filter
!= PictFilterBilinear
)
158 ATI_FALLBACK(("Unsupported filter 0x%x\n", pPict
->filter
));
164 R100TextureSetup(PicturePtr pPict
, PixmapPtr pPix
, int unit
)
166 ATIScreenInfo
*atis
= accel_atis
;
167 KdScreenPriv(pPix
->drawable
.pScreen
);
168 CARD32 txfilter
, txformat
, txoffset
, txpitch
;
169 int w
= pPict
->pDrawable
->width
;
170 int h
= pPict
->pDrawable
->height
;
174 txpitch
= pPix
->devKind
;
175 txoffset
= ((CARD8
*)pPix
->devPrivate
.ptr
-
176 pScreenPriv
->screen
->memory_base
);
178 for (i
= 0; i
< sizeof(R100TexFormats
) / sizeof(R100TexFormats
[0]); i
++)
180 if (R100TexFormats
[i
].fmt
== pPict
->format
)
183 txformat
= R100TexFormats
[i
].card_fmt
;
184 if (R100TexFormats
[i
].byte_swap
)
185 txoffset
|= RADEON_TXO_ENDIAN_BYTE_SWAP
;
188 txformat
|= ATILog2(w
) << RADEON_TXFORMAT_WIDTH_SHIFT
;
189 txformat
|= ATILog2(h
) << RADEON_TXFORMAT_HEIGHT_SHIFT
;
191 txformat
|= RADEON_TXFORMAT_NON_POWER2
;
192 txformat
|= unit
<< 24; /* RADEON_TXFORMAT_ST_ROUTE_STQX */
195 if ((txoffset
& 0x1f) != 0)
196 ATI_FALLBACK(("Bad texture offset 0x%x\n", txoffset
));
197 if ((txpitch
& 0x1f) != 0)
198 ATI_FALLBACK(("Bad texture pitch 0x%x\n", txpitch
));
200 switch (pPict
->filter
) {
201 case PictFilterNearest
:
202 txfilter
= (RADEON_MAG_FILTER_NEAREST
|
203 RADEON_MIN_FILTER_NEAREST
);
205 case PictFilterBilinear
:
206 txfilter
= (RADEON_MAG_FILTER_LINEAR
|
207 RADEON_MIN_FILTER_LINEAR
);
210 ATI_FALLBACK(("Bad filter 0x%x\n", pPict
->filter
));
215 OUT_RING(DMA_PACKET0(RADEON_REG_PP_TXFILTER_0
, 3));
216 OUT_RING_REG(RADEON_REG_PP_TXFILTER_0
, txfilter
);
217 OUT_RING_REG(RADEON_REG_PP_TXFORMAT_0
, txformat
);
218 OUT_RING_REG(RADEON_REG_PP_TXOFFSET_0
, txoffset
);
219 OUT_RING(DMA_PACKET0(RADEON_REG_PP_TEX_SIZE_0
, 2));
220 OUT_RING_REG(RADEON_REG_PP_TEX_SIZE_0
,
221 (pPix
->drawable
.width
- 1) |
222 ((pPix
->drawable
.height
- 1) << RADEON_TEX_VSIZE_SHIFT
));
223 OUT_RING_REG(RADEON_REG_PP_TEX_PITCH_0
, txpitch
- 32);
225 OUT_RING(DMA_PACKET0(RADEON_REG_PP_TXFILTER_1
, 3));
226 OUT_RING_REG(RADEON_REG_PP_TXFILTER_1
, txfilter
);
227 OUT_RING_REG(RADEON_REG_PP_TXFORMAT_1
, txformat
);
228 OUT_RING_REG(RADEON_REG_PP_TXOFFSET_1
, txoffset
);
229 OUT_RING(DMA_PACKET0(RADEON_REG_PP_TEX_SIZE_1
, 2));
230 OUT_RING_REG(RADEON_REG_PP_TEX_SIZE_1
,
231 (pPix
->drawable
.width
- 1) |
232 ((pPix
->drawable
.height
- 1) << RADEON_TEX_VSIZE_SHIFT
));
233 OUT_RING_REG(RADEON_REG_PP_TEX_PITCH_1
, txpitch
- 32);
237 if (pPict
->transform
!= 0) {
238 is_transform
[unit
] = TRUE
;
239 transform
[unit
] = pPict
->transform
;
241 is_transform
[unit
] = FALSE
;
248 R100CheckComposite(int op
, PicturePtr pSrcPicture
, PicturePtr pMaskPicture
,
249 PicturePtr pDstPicture
)
253 /* Check for unsupported compositing operations. */
254 if (op
>= sizeof(RadeonBlendOp
) / sizeof(RadeonBlendOp
[0]))
255 ATI_FALLBACK(("Unsupported Composite op 0x%x\n", op
));
256 if (pMaskPicture
!= NULL
&& pMaskPicture
->componentAlpha
&&
257 RadeonBlendOp
[op
].src_alpha
)
258 ATI_FALLBACK(("Component alpha not supported with source "
259 "alpha blending.\n"));
260 if (pDstPicture
->pDrawable
->width
>= (1 << 11) ||
261 pDstPicture
->pDrawable
->height
>= (1 << 11))
262 ATI_FALLBACK(("Dest w/h too large (%d,%d).\n",
263 pDstPicture
->pDrawable
->width
,
264 pDstPicture
->pDrawable
->height
));
266 if (!R100CheckCompositeTexture(pSrcPicture
, 0))
268 if (pMaskPicture
!= NULL
&& !R100CheckCompositeTexture(pMaskPicture
, 1))
271 if (pDstPicture
->componentAlpha
)
274 if (!RadeonGetDestFormat(pDstPicture
, &tmp1
))
281 R100PrepareComposite(int op
, PicturePtr pSrcPicture
, PicturePtr pMaskPicture
,
282 PicturePtr pDstPicture
, PixmapPtr pSrc
, PixmapPtr pMask
, PixmapPtr pDst
)
284 KdScreenPriv(pDst
->drawable
.pScreen
);
285 ATIScreenInfo(pScreenPriv
);
286 CARD32 dst_format
, dst_offset
, dst_pitch
;
287 CARD32 pp_cntl
, blendcntl
, cblend
, ablend
;
293 RadeonGetDestFormat(pDstPicture
, &dst_format
);
294 pixel_shift
= pDst
->drawable
.bitsPerPixel
>> 4;
296 dst_offset
= ((CARD8
*)pDst
->devPrivate
.ptr
-
297 pScreenPriv
->screen
->memory_base
);
298 dst_pitch
= pDst
->devKind
;
299 if ((dst_offset
& 0x0f) != 0)
300 ATI_FALLBACK(("Bad destination offset 0x%x\n", dst_offset
));
301 if (((dst_pitch
>> pixel_shift
) & 0x7) != 0)
302 ATI_FALLBACK(("Bad destination pitch 0x%x\n", dst_pitch
));
304 if (!R100TextureSetup(pSrcPicture
, pSrc
, 0))
306 pp_cntl
= RADEON_TEX_0_ENABLE
| RADEON_TEX_BLEND_0_ENABLE
;
309 if (!R100TextureSetup(pMaskPicture
, pMask
, 1))
311 pp_cntl
|= RADEON_TEX_1_ENABLE
;
313 is_transform
[1] = FALSE
;
318 RadeonSwitchTo3D(atis
);
322 OUT_RING(DMA_PACKET0(RADEON_REG_PP_CNTL
, 3));
323 OUT_RING_REG(RADEON_REG_PP_CNTL
, pp_cntl
);
324 OUT_RING_REG(RADEON_REG_RB3D_CNTL
,
325 dst_format
| RADEON_ALPHA_BLEND_ENABLE
);
326 OUT_RING_REG(RADEON_REG_RB3D_COLOROFFSET
, dst_offset
);
328 OUT_REG(RADEON_REG_RB3D_COLORPITCH
, dst_pitch
>> pixel_shift
);
330 /* IN operator: Multiply src by mask components or mask alpha.
331 * BLEND_CTL_ADD is A * B + C.
332 * If a picture is a8, we have to explicitly zero its color values.
333 * If the destination is a8, we have to route the alpha to red, I think.
335 cblend
= RADEON_BLEND_CTL_ADD
| RADEON_CLAMP_TX
|
336 RADEON_COLOR_ARG_C_ZERO
;
337 ablend
= RADEON_BLEND_CTL_ADD
| RADEON_CLAMP_TX
|
338 RADEON_ALPHA_ARG_C_ZERO
;
340 if (pDstPicture
->format
== PICT_a8
)
341 cblend
|= RADEON_COLOR_ARG_A_T0_ALPHA
;
342 else if (pSrcPicture
->format
== PICT_a8
)
343 cblend
|= RADEON_COLOR_ARG_A_ZERO
;
345 cblend
|= RADEON_COLOR_ARG_A_T0_COLOR
;
346 ablend
|= RADEON_ALPHA_ARG_A_T0_ALPHA
;
349 if (pMaskPicture
->componentAlpha
&&
350 pDstPicture
->format
!= PICT_a8
)
351 cblend
|= RADEON_COLOR_ARG_B_T1_COLOR
;
353 cblend
|= RADEON_COLOR_ARG_B_T1_ALPHA
;
354 ablend
|= RADEON_ALPHA_ARG_B_T1_ALPHA
;
356 cblend
|= RADEON_COLOR_ARG_B_ZERO
| RADEON_COMP_ARG_B
;
357 ablend
|= RADEON_ALPHA_ARG_B_ZERO
| RADEON_COMP_ARG_B
;
360 OUT_REG(RADEON_REG_PP_TXCBLEND_0
, cblend
);
361 OUT_REG(RADEON_REG_PP_TXABLEND_0
, ablend
);
364 blendcntl
= RadeonBlendOp
[op
].blend_cntl
;
365 if (PICT_FORMAT_A(pDstPicture
->format
) == 0 &&
366 RadeonBlendOp
[op
].dst_alpha
) {
367 if ((blendcntl
& RADEON_SBLEND_MASK
) ==
368 RADEON_SBLEND_GL_DST_ALPHA
)
369 blendcntl
= (blendcntl
& ~RADEON_SBLEND_MASK
) |
370 RADEON_SBLEND_GL_ONE
;
371 else if ((blendcntl
& RADEON_SBLEND_MASK
) ==
372 RADEON_SBLEND_GL_INV_DST_ALPHA
)
373 blendcntl
= (blendcntl
& ~RADEON_SBLEND_MASK
) |
374 RADEON_SBLEND_GL_ZERO
;
376 OUT_REG(RADEON_REG_RB3D_BLENDCNTL
, blendcntl
);
385 R200CheckCompositeTexture(PicturePtr pPict
, int unit
)
387 int w
= pPict
->pDrawable
->width
;
388 int h
= pPict
->pDrawable
->height
;
391 if ((w
> 0x7ff) || (h
> 0x7ff))
392 ATI_FALLBACK(("Picture w/h too large (%dx%d)\n", w
, h
));
394 for (i
= 0; i
< sizeof(R200TexFormats
) / sizeof(R200TexFormats
[0]); i
++)
396 if (R200TexFormats
[i
].fmt
== pPict
->format
)
399 if (i
== sizeof(R200TexFormats
) / sizeof(R200TexFormats
[0]))
400 ATI_FALLBACK(("Unsupported picture format 0x%x\n",
403 if (pPict
->repeat
&& ((w
& (w
- 1)) != 0 || (h
& (h
- 1)) != 0))
404 ATI_FALLBACK(("NPOT repeat unsupported (%dx%d)\n", w
, h
));
406 if (pPict
->filter
!= PictFilterNearest
&&
407 pPict
->filter
!= PictFilterBilinear
)
408 ATI_FALLBACK(("Unsupported filter 0x%x\n", pPict
->filter
));
414 R200TextureSetup(PicturePtr pPict
, PixmapPtr pPix
, int unit
)
416 ATIScreenInfo
*atis
= accel_atis
;
417 KdScreenPriv(pPix
->drawable
.pScreen
);
418 CARD32 txfilter
, txformat
, txoffset
, txpitch
;
419 int w
= pPict
->pDrawable
->width
;
420 int h
= pPict
->pDrawable
->height
;
424 txpitch
= pPix
->devKind
;
425 txoffset
= ((CARD8
*)pPix
->devPrivate
.ptr
-
426 pScreenPriv
->screen
->memory_base
);
428 for (i
= 0; i
< sizeof(R200TexFormats
) / sizeof(R200TexFormats
[0]); i
++)
430 if (R200TexFormats
[i
].fmt
== pPict
->format
)
433 txformat
= R200TexFormats
[i
].card_fmt
;
434 if (R200TexFormats
[i
].byte_swap
)
435 txoffset
|= R200_TXO_ENDIAN_BYTE_SWAP
;
438 txformat
|= ATILog2(w
) << R200_TXFORMAT_WIDTH_SHIFT
;
439 txformat
|= ATILog2(h
) << R200_TXFORMAT_HEIGHT_SHIFT
;
441 txformat
|= R200_TXFORMAT_NON_POWER2
;
442 txformat
|= unit
<< R200_TXFORMAT_ST_ROUTE_SHIFT
;
444 if ((txoffset
& 0x1f) != 0)
445 ATI_FALLBACK(("Bad texture offset 0x%x\n", txoffset
));
446 if ((txpitch
& 0x1f) != 0)
447 ATI_FALLBACK(("Bad texture pitch 0x%x\n", txpitch
));
449 switch (pPict
->filter
) {
450 case PictFilterNearest
:
451 txfilter
= (R200_MAG_FILTER_NEAREST
|
452 R200_MIN_FILTER_NEAREST
);
454 case PictFilterBilinear
:
455 txfilter
= (R200_MAG_FILTER_LINEAR
|
456 R200_MIN_FILTER_LINEAR
);
459 ATI_FALLBACK(("Bad filter 0x%x\n", pPict
->filter
));
464 OUT_RING(DMA_PACKET0(R200_REG_PP_TXFILTER_0
+ 0x20 * unit
, 5));
465 OUT_RING_REG(R200_REG_PP_TXFILTER_0
, txfilter
);
466 OUT_RING_REG(R200_REG_PP_TXFORMAT_0
, txformat
);
467 OUT_RING_REG(R200_REG_PP_TXFORMAT_X_0
, 0);
468 OUT_RING_REG(R200_REG_PP_TXSIZE_0
,
469 (pPix
->drawable
.width
- 1) |
470 ((pPix
->drawable
.height
- 1) << RADEON_TEX_VSIZE_SHIFT
));
471 OUT_RING_REG(R200_REG_PP_TXPITCH_0
, txpitch
- 32);
475 OUT_RING(DMA_PACKET0(R200_REG_PP_TXFILTER_1
, 5));
476 OUT_RING_REG(R200_REG_PP_TXFILTER_1
, txfilter
);
477 OUT_RING_REG(R200_REG_PP_TXFORMAT_1
, txformat
);
478 OUT_RING_REG(R200_REG_PP_TXFORMAT_X_1
, 0);
479 OUT_RING_REG(R200_REG_PP_TXSIZE_1
,
480 (pPix
->drawable
.width
- 1) |
481 ((pPix
->drawable
.height
- 1) << RADEON_TEX_VSIZE_SHIFT
));
482 OUT_RING_REG(R200_REG_PP_TXPITCH_1
, txpitch
- 32);
487 OUT_REG(R200_PP_TXOFFSET_0
+ 0x18 * unit
, txoffset
);
490 if (pPict
->transform
!= 0) {
491 is_transform
[unit
] = TRUE
;
492 transform
[unit
] = pPict
->transform
;
494 is_transform
[unit
] = FALSE
;
501 R200CheckComposite(int op
, PicturePtr pSrcPicture
, PicturePtr pMaskPicture
,
502 PicturePtr pDstPicture
)
506 /* Check for unsupported compositing operations. */
507 if (op
>= sizeof(RadeonBlendOp
) / sizeof(RadeonBlendOp
[0]))
508 ATI_FALLBACK(("Unsupported Composite op 0x%x\n", op
));
509 if (pMaskPicture
!= NULL
&& pMaskPicture
->componentAlpha
&&
510 RadeonBlendOp
[op
].src_alpha
)
511 ATI_FALLBACK(("Component alpha not supported with source "
512 "alpha blending.\n"));
514 if (!R200CheckCompositeTexture(pSrcPicture
, 0))
516 if (pMaskPicture
!= NULL
&& !R200CheckCompositeTexture(pMaskPicture
, 1))
519 if (!RadeonGetDestFormat(pDstPicture
, &tmp1
))
526 R200PrepareComposite(int op
, PicturePtr pSrcPicture
, PicturePtr pMaskPicture
,
527 PicturePtr pDstPicture
, PixmapPtr pSrc
, PixmapPtr pMask
, PixmapPtr pDst
)
529 KdScreenPriv(pDst
->drawable
.pScreen
);
530 ATIScreenInfo(pScreenPriv
);
531 CARD32 dst_format
, dst_offset
, dst_pitch
;
532 CARD32 pp_cntl
, blendcntl
, cblend
, ablend
;
536 RadeonGetDestFormat(pDstPicture
, &dst_format
);
537 pixel_shift
= pDst
->drawable
.bitsPerPixel
>> 4;
541 dst_offset
= ((CARD8
*)pDst
->devPrivate
.ptr
-
542 pScreenPriv
->screen
->memory_base
);
543 dst_pitch
= pDst
->devKind
;
544 if ((dst_offset
& 0x0f) != 0)
545 ATI_FALLBACK(("Bad destination offset 0x%x\n", dst_offset
));
546 if (((dst_pitch
>> pixel_shift
) & 0x7) != 0)
547 ATI_FALLBACK(("Bad destination pitch 0x%x\n", dst_pitch
));
549 if (!R200TextureSetup(pSrcPicture
, pSrc
, 0))
551 pp_cntl
= RADEON_TEX_0_ENABLE
| RADEON_TEX_BLEND_0_ENABLE
;
554 if (!R200TextureSetup(pMaskPicture
, pMask
, 1))
556 pp_cntl
|= RADEON_TEX_1_ENABLE
;
558 is_transform
[1] = FALSE
;
561 RadeonSwitchTo3D(atis
);
565 OUT_RING(DMA_PACKET0(RADEON_REG_PP_CNTL
, 3));
566 OUT_RING_REG(RADEON_REG_PP_CNTL
, pp_cntl
);
567 OUT_RING_REG(RADEON_REG_RB3D_CNTL
, dst_format
| RADEON_ALPHA_BLEND_ENABLE
);
568 OUT_RING_REG(RADEON_REG_RB3D_COLOROFFSET
, dst_offset
);
570 OUT_REG(R200_REG_SE_VTX_FMT_0
, R200_VTX_XY
);
571 OUT_REG(R200_REG_SE_VTX_FMT_1
,
572 (2 << R200_VTX_TEX0_COMP_CNT_SHIFT
) |
573 (2 << R200_VTX_TEX1_COMP_CNT_SHIFT
));
575 OUT_REG(RADEON_REG_RB3D_COLORPITCH
, dst_pitch
>> pixel_shift
);
577 /* IN operator: Multiply src by mask components or mask alpha.
578 * BLEND_CTL_ADD is A * B + C.
579 * If a picture is a8, we have to explicitly zero its color values.
580 * If the destination is a8, we have to route the alpha to red, I think.
582 cblend
= R200_TXC_OP_MADD
| R200_TXC_ARG_C_ZERO
;
583 ablend
= R200_TXA_OP_MADD
| R200_TXA_ARG_C_ZERO
;
585 if (pDstPicture
->format
== PICT_a8
)
586 cblend
|= R200_TXC_ARG_A_R0_ALPHA
;
587 else if (pSrcPicture
->format
== PICT_a8
)
588 cblend
|= R200_TXC_ARG_A_ZERO
;
590 cblend
|= R200_TXC_ARG_A_R0_COLOR
;
591 ablend
|= R200_TXA_ARG_A_R0_ALPHA
;
594 if (pMaskPicture
->componentAlpha
&&
595 pDstPicture
->format
!= PICT_a8
)
596 cblend
|= R200_TXC_ARG_B_R1_COLOR
;
598 cblend
|= R200_TXC_ARG_B_R1_ALPHA
;
599 ablend
|= R200_TXA_ARG_B_R1_ALPHA
;
601 cblend
|= R200_TXC_ARG_B_ZERO
| R200_TXC_COMP_ARG_B
;
602 ablend
|= R200_TXA_ARG_B_ZERO
| R200_TXA_COMP_ARG_B
;
605 OUT_RING(DMA_PACKET0(R200_REG_PP_TXCBLEND_0
, 4));
606 OUT_RING_REG(R200_REG_PP_TXCBLEND_0
, cblend
);
607 OUT_RING_REG(R200_REG_PP_TXCBLEND2_0
,
608 R200_TXC_CLAMP_0_1
| R200_TXC_OUTPUT_REG_R0
);
609 OUT_RING_REG(R200_REG_PP_TXABLEND_0
, ablend
);
610 OUT_RING_REG(R200_REG_PP_TXABLEND2_0
,
611 R200_TXA_CLAMP_0_1
| R200_TXA_OUTPUT_REG_R0
);
614 blendcntl
= RadeonBlendOp
[op
].blend_cntl
;
615 if (PICT_FORMAT_A(pDstPicture
->format
) == 0 &&
616 RadeonBlendOp
[op
].dst_alpha
) {
617 if ((blendcntl
& RADEON_SBLEND_MASK
) ==
618 RADEON_SBLEND_GL_DST_ALPHA
)
619 blendcntl
= (blendcntl
& ~RADEON_SBLEND_MASK
) |
620 RADEON_SBLEND_GL_ONE
;
621 else if ((blendcntl
& RADEON_SBLEND_MASK
) ==
622 RADEON_SBLEND_GL_INV_DST_ALPHA
)
623 blendcntl
= (blendcntl
& ~RADEON_SBLEND_MASK
) |
624 RADEON_SBLEND_GL_ZERO
;
626 OUT_REG(RADEON_REG_RB3D_BLENDCNTL
, blendcntl
);
637 struct blend_vertex
{
639 union intfloat s0
, t0
;
640 union intfloat s1
, t1
;
643 #define VTX_DWORD_COUNT 6
645 #define VTX_OUT(_dstX, _dstY, _srcX, _srcY, _maskX, _maskY) \
651 OUT_RING_F(_maskX); \
652 OUT_RING_F(_maskY); \
656 RadeonComposite(int srcX
, int srcY
, int maskX
, int maskY
, int dstX
, int dstY
,
659 ATIScreenInfo
*atis
= accel_atis
;
660 ATICardInfo
*atic
= atis
->atic
;
661 int srcXend
, srcYend
, maskXend
, maskYend
;
667 /*ErrorF("RadeonComposite (%d,%d) (%d,%d) (%d,%d) (%d,%d)\n",
668 srcX, srcY, maskX, maskY,dstX, dstY, w, h);*/
672 maskXend
= maskX
+ w
;
673 maskYend
= maskY
+ h
;
674 if (is_transform
[0]) {
675 v
.vector
[0] = IntToxFixed(srcX
);
676 v
.vector
[1] = IntToxFixed(srcY
);
677 v
.vector
[2] = xFixed1
;
678 PictureTransformPoint(transform
[0], &v
);
679 srcX
= xFixedToInt(v
.vector
[0]);
680 srcY
= xFixedToInt(v
.vector
[1]);
681 v
.vector
[0] = IntToxFixed(srcXend
);
682 v
.vector
[1] = IntToxFixed(srcYend
);
683 v
.vector
[2] = xFixed1
;
684 PictureTransformPoint(transform
[0], &v
);
685 srcXend
= xFixedToInt(v
.vector
[0]);
686 srcYend
= xFixedToInt(v
.vector
[1]);
688 if (is_transform
[1]) {
689 v
.vector
[0] = IntToxFixed(maskX
);
690 v
.vector
[1] = IntToxFixed(maskY
);
691 v
.vector
[2] = xFixed1
;
692 PictureTransformPoint(transform
[1], &v
);
693 maskX
= xFixedToInt(v
.vector
[0]);
694 maskY
= xFixedToInt(v
.vector
[1]);
695 v
.vector
[0] = IntToxFixed(maskXend
);
696 v
.vector
[1] = IntToxFixed(maskYend
);
697 v
.vector
[2] = xFixed1
;
698 PictureTransformPoint(transform
[1], &v
);
699 maskXend
= xFixedToInt(v
.vector
[0]);
700 maskYend
= xFixedToInt(v
.vector
[1]);
704 BEGIN_DMA(4 * VTX_DWORD_COUNT
+ 3);
705 OUT_RING(DMA_PACKET3(RADEON_CP_PACKET3_3D_DRAW_IMMD
,
706 4 * VTX_DWORD_COUNT
+ 2));
707 OUT_RING(RADEON_CP_VC_FRMT_XY
|
708 RADEON_CP_VC_FRMT_ST0
|
709 RADEON_CP_VC_FRMT_ST1
);
710 OUT_RING(RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN
|
711 RADEON_CP_VC_CNTL_PRIM_WALK_RING
|
712 RADEON_CP_VC_CNTL_MAOS_ENABLE
|
713 RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE
|
714 (4 << RADEON_CP_VC_CNTL_NUM_SHIFT
));
716 BEGIN_DMA(4 * VTX_DWORD_COUNT
+ 2);
717 OUT_RING(DMA_PACKET3(R200_CP_PACKET3_3D_DRAW_IMMD_2
,
718 4 * VTX_DWORD_COUNT
+ 1));
719 OUT_RING(RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN
|
720 RADEON_CP_VC_CNTL_PRIM_WALK_RING
|
721 (4 << RADEON_CP_VC_CNTL_NUM_SHIFT
));
724 VTX_OUT(dstX
, dstY
, srcX
, srcY
, maskX
, maskY
);
725 VTX_OUT(dstX
, dstY
+ h
, srcX
, srcYend
, maskX
, maskYend
);
726 VTX_OUT(dstX
+ w
, dstY
+ h
, srcXend
, srcYend
, maskXend
, maskYend
);
727 VTX_OUT(dstX
+ w
, dstY
, srcXend
, srcY
, maskXend
, maskY
);
735 RadeonDoneComposite(void)
742 RadeonPrepareTrapezoids(PicturePtr pDstPicture
, PixmapPtr pDst
)
744 KdScreenPriv(pDst
->drawable
.pScreen
);
745 ATIScreenInfo(pScreenPriv
);
746 ATICardInfo(pScreenPriv
);
747 CARD32 dst_offset
, dst_pitch
;
751 pixel_shift
= pDst
->drawable
.bitsPerPixel
>> 4;
755 dst_offset
= ((CARD8
*)pDst
->devPrivate
.ptr
-
756 pScreenPriv
->screen
->memory_base
);
757 dst_pitch
= pDst
->devKind
;
758 if ((dst_offset
& 0x0f) != 0)
759 ATI_FALLBACK(("Bad destination offset 0x%x\n", dst_offset
));
760 if (((dst_pitch
>> pixel_shift
) & 0x7) != 0)
761 ATI_FALLBACK(("Bad destination pitch 0x%x\n", dst_pitch
));
763 RadeonSwitchTo3D(atis
);
767 OUT_RING(DMA_PACKET0(RADEON_REG_PP_CNTL
, 5));
768 OUT_RING_REG(RADEON_REG_PP_CNTL
, RADEON_TEX_BLEND_0_ENABLE
);
769 OUT_RING_REG(RADEON_REG_RB3D_CNTL
,
770 RADEON_COLOR_FORMAT_RGB8
| RADEON_ALPHA_BLEND_ENABLE
);
771 OUT_RING_REG(RADEON_REG_RB3D_COLOROFFSET
, dst_offset
);
772 OUT_RING_REG(RADEON_REG_RE_WIDTH_HEIGHT
,
773 ((pDst
->drawable
.height
- 1) << 16) |
774 (pDst
->drawable
.width
- 1));
775 OUT_RING_REG(RADEON_REG_RB3D_COLORPITCH
, dst_pitch
>> pixel_shift
);
776 OUT_REG(RADEON_REG_RB3D_BLENDCNTL
, RadeonBlendOp
[PictOpAdd
].blend_cntl
);
781 OUT_RING(DMA_PACKET0(RADEON_REG_PP_TXCBLEND_0
, 3));
782 OUT_RING_REG(RADEON_REG_PP_TXCBLEND_0
,
783 RADEON_BLEND_CTL_ADD
| RADEON_CLAMP_TX
|
784 RADEON_COLOR_ARG_C_TFACTOR_ALPHA
);
785 OUT_RING_REG(RADEON_REG_PP_TXABLEND_0
,
786 RADEON_BLEND_CTL_ADD
| RADEON_CLAMP_TX
|
787 RADEON_ALPHA_ARG_C_TFACTOR_ALPHA
);
788 OUT_RING_REG(RADEON_REG_PP_TFACTOR_0
, 0x01000000);
790 } else if (atic
->is_r200
) {
792 OUT_REG(R200_REG_SE_VTX_FMT_0
, R200_VTX_XY
);
793 OUT_REG(R200_REG_SE_VTX_FMT_1
, 0);
794 OUT_REG(R200_REG_PP_TXCBLEND_0
,
795 R200_TXC_ARG_C_TFACTOR_COLOR
);
796 OUT_REG(R200_REG_PP_TXABLEND_0
,
797 R200_TXA_ARG_C_TFACTOR_ALPHA
);
798 OUT_REG(R200_REG_PP_TXCBLEND2_0
, R200_TXC_OUTPUT_REG_R0
);
799 OUT_REG(R200_REG_PP_TXABLEND2_0
, R200_TXA_OUTPUT_REG_R0
);
800 OUT_REG(RADEON_REG_PP_TFACTOR_0
, 0x01000000);
807 #define TRAP_VERT_RING_COUNT 2
809 #define TRAP_VERT(_x, _y) \
811 OUT_RING_F((_x) + sample_x); \
812 OUT_RING_F((_y) + sample_y); \
816 RadeonTrapezoids(KaaTrapezoid
*traps
, int ntraps
)
818 ATIScreenInfo
*atis
= accel_atis
;
819 ATICardInfo
*atic
= atis
->atic
;
823 int i
, sample
, count
, vertcount
;
825 count
= 0xffff / 4 / sample_count
;
828 vertcount
= count
* sample_count
* 4;
831 BEGIN_DMA(3 + vertcount
* TRAP_VERT_RING_COUNT
);
832 OUT_RING(DMA_PACKET3(RADEON_CP_PACKET3_3D_DRAW_IMMD
,
833 2 + vertcount
* TRAP_VERT_RING_COUNT
));
834 OUT_RING(RADEON_CP_VC_FRMT_XY
);
835 OUT_RING(RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN
|
836 RADEON_CP_VC_CNTL_PRIM_WALK_RING
|
837 RADEON_CP_VC_CNTL_MAOS_ENABLE
|
838 RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE
|
839 (vertcount
<< RADEON_CP_VC_CNTL_NUM_SHIFT
));
841 BEGIN_DMA(2 + vertcount
* TRAP_VERT_RING_COUNT
);
842 OUT_RING(DMA_PACKET3(R200_CP_PACKET3_3D_DRAW_IMMD_2
,
843 1 + vertcount
* TRAP_VERT_RING_COUNT
));
844 OUT_RING(RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN
|
845 RADEON_CP_VC_CNTL_PRIM_WALK_RING
|
846 (vertcount
<< RADEON_CP_VC_CNTL_NUM_SHIFT
));
849 for (i
= 0; i
< count
; i
++) {
850 for (sample
= 0; sample
< sample_count
; sample
++) {
851 float sample_x
= sample_offsets_x
[sample
];
852 float sample_y
= sample_offsets_y
[sample
];
853 TRAP_VERT(traps
[i
].tl
, traps
[i
].ty
);
854 TRAP_VERT(traps
[i
].bl
, traps
[i
].by
);
855 TRAP_VERT(traps
[i
].br
, traps
[i
].by
);
856 TRAP_VERT(traps
[i
].tr
, traps
[i
].ty
);
867 RadeonDoneTrapezoids(void)
869 ATIScreenInfo
*atis
= accel_atis
;
873 OUT_REG(RADEON_REG_RE_WIDTH_HEIGHT
, 0xffffffff);