2 * Copyright © 2004 Keith Packard
3 * Copyright © 2005 Eric Anholt
5 * Permission to use, copy, modify, distribute, and sell this software and its
6 * documentation for any purpose is hereby granted without fee, provided that
7 * the above copyright notice appear in all copies and that both that
8 * copyright notice and this permission notice appear in supporting
9 * documentation, and that the name of Eric Anholt not be used in
10 * advertising or publicity pertaining to distribution of the software without
11 * specific, written prior permission. Eric Anholt makes no
12 * representations about the suitability of this software for any purpose. It
13 * is provided "as is" without express or implied warranty.
15 * ERIC ANHOLT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17 * EVENT SHALL ERIC ANHOLT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
21 * PERFORMANCE OF THIS SOFTWARE.
23 * Based on mach64video.c by Keith Packard.
27 #include <kdrive-config.h>
35 #include <X11/extensions/Xv.h>
38 #define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
40 static Atom xvBrightness
, xvSaturation
;
42 extern CARD8 ATIBltRop
[16];
44 #define IMAGE_MAX_WIDTH 2048
45 #define IMAGE_MAX_HEIGHT 2048
48 ATIStopVideo(KdScreenInfo
*screen
, pointer data
, Bool exit
)
50 ScreenPtr pScreen
= screen
->pScreen
;
51 ATIPortPrivPtr pPortPriv
= (ATIPortPrivPtr
)data
;
53 REGION_EMPTY(screen
->pScreen
, &pPortPriv
->clip
);
55 if (pPortPriv
->off_screen
) {
56 KdOffscreenFree (pScreen
, pPortPriv
->off_screen
);
57 pPortPriv
->off_screen
= 0;
62 ATISetPortAttribute(KdScreenInfo
*screen
, Atom attribute
, int value
,
69 ATIGetPortAttribute(KdScreenInfo
*screen
, Atom attribute
, int *value
,
76 ATIQueryBestSize(KdScreenInfo
*screen
, Bool motion
, short vid_w
, short vid_h
,
77 short drw_w
, short drw_h
, unsigned int *p_w
, unsigned int *p_h
,
86 Takes the dst box in standard X BoxRec form (top and left
87 edges inclusive, bottom and right exclusive). The new dst
88 box is returned. The source boundaries are given (x1, y1
89 inclusive, x2, y2 exclusive) and returned are the new source
90 boundaries in 16.16 fixed point.
94 ATIClipVideo(BoxPtr dst
, INT32
*x1
, INT32
*x2
, INT32
*y1
, INT32
*y2
,
95 BoxPtr extents
, INT32 width
, INT32 height
)
97 INT32 vscale
, hscale
, delta
;
100 hscale
= ((*x2
- *x1
) << 16) / (dst
->x2
- dst
->x1
);
101 vscale
= ((*y2
- *y1
) << 16) / (dst
->y2
- dst
->y1
);
103 *x1
<<= 16; *x2
<<= 16;
104 *y1
<<= 16; *y2
<<= 16;
106 diff
= extents
->x1
- dst
->x1
;
108 dst
->x1
= extents
->x1
;
109 *x1
+= diff
* hscale
;
111 diff
= dst
->x2
- extents
->x2
;
113 dst
->x2
= extents
->x2
;
114 *x2
-= diff
* hscale
;
116 diff
= extents
->y1
- dst
->y1
;
118 dst
->y1
= extents
->y1
;
119 *y1
+= diff
* vscale
;
121 diff
= dst
->y2
- extents
->y2
;
123 dst
->y2
= extents
->y2
;
124 *y2
-= diff
* vscale
;
128 diff
= (- *x1
+ hscale
- 1)/ hscale
;
130 *x1
+= diff
* hscale
;
132 delta
= *x2
- (width
<< 16);
134 diff
= (delta
+ hscale
- 1)/ hscale
;
136 *x2
-= diff
* hscale
;
139 diff
= (- *y1
+ vscale
- 1)/ vscale
;
141 *y1
+= diff
* vscale
;
143 delta
= *y2
- (height
<< 16);
145 diff
= (delta
+ vscale
- 1)/ vscale
;
147 *y2
-= diff
* vscale
;
152 R128DisplayVideo(KdScreenInfo
*screen
, ATIPortPrivPtr pPortPriv
)
154 ScreenPtr pScreen
= screen
->pScreen
;
155 KdScreenPriv(pScreen
);
156 ATIScreenInfo(pScreenPriv
);
157 CARD32 dstDatatype
, srcDatatype
;
158 CARD32 dst_offset
, dst_pitch
;
159 int dstxoff
, dstyoff
;
160 PixmapPtr pPixmap
= pPortPriv
->pPixmap
;
161 int bpp
= pPixmap
->drawable
.bitsPerPixel
;
164 BoxPtr pBox
= REGION_RECTS(&pPortPriv
->clip
);
165 int nBox
= REGION_NUM_RECTS(&pPortPriv
->clip
);
167 if (pPortPriv
->id
== FOURCC_UYVY
)
168 srcDatatype
= R128_DATATYPE_YVYU_422
;
170 srcDatatype
= R128_DATATYPE_VYUY_422
;
175 if (pPixmap
->drawable
.depth
== 15)
176 dstDatatype
= R128_DATATYPE_ARGB1555
;
178 dstDatatype
= R128_DATATYPE_RGB565
;
181 dstDatatype
= R128_DATATYPE_ARGB8888
;
187 dst_offset
= ((CARD8
*)pPixmap
->devPrivate
.ptr
-
188 pScreenPriv
->screen
->memory_base
);
189 dst_pitch
= pPixmap
->devKind
;
191 dstxoff
= -pPixmap
->screen_x
+ pPixmap
->drawable
.x
;
192 dstyoff
= -pPixmap
->screen_y
+ pPixmap
->drawable
.y
;
199 OUT_REG(ATI_REG_DST_PITCH_OFFSET
,
200 ((dst_pitch
/ bpp
) << 21) | (dst_offset
>> 5));
201 OUT_REG(ATI_REG_DP_GUI_MASTER_CNTL
,
202 ATI_GMC_DST_PITCH_OFFSET_CNTL
|
205 ATI_GMC_SRC_DATATYPE_COLOR
|
206 (ATIBltRop
[GXcopy
] << 16) |
208 ATI_GMC_CLR_CMP_CNTL_DIS
|
209 R128_GMC_AUX_CLIP_DIS
);
210 OUT_REG(ATI_REG_DP_CNTL
,
211 ATI_DST_X_LEFT_TO_RIGHT
| ATI_DST_Y_TOP_TO_BOTTOM
);
212 OUT_REG(R128_REG_SCALE_3D_CNTL
,
213 R128_SCALE_3D_SCALE
|
216 OUT_REG(R128_REG_TEX_CNTL_C
, R128_TEX_CACHE_FLUSH
);
217 OUT_REG(R128_REG_SCALE_3D_DATATYPE
, srcDatatype
);
219 OUT_RING(DMA_PACKET0(R128_REG_SCALE_PITCH
, 5));
220 OUT_RING_REG(R128_REG_SCALE_PITCH
, pPortPriv
->src_pitch
/ 16);
221 OUT_RING_REG(R128_REG_SCALE_X_INC
,
222 (pPortPriv
->src_w
<< 16) / pPortPriv
->dst_w
);
223 OUT_RING_REG(R128_REG_SCALE_Y_INC
,
224 (pPortPriv
->src_h
<< 16) / pPortPriv
->dst_h
);
225 OUT_RING_REG(R128_REG_SCALE_HACC
, 0x0);
226 OUT_RING_REG(R128_REG_SCALE_VACC
, 0x0);
231 int srcX
, srcY
, dstX
, dstY
, srcw
, srch
, dstw
, dsth
;
233 dstX
= pBox
->x1
+ dstxoff
;
234 dstY
= pBox
->y1
+ dstyoff
;
235 dstw
= pBox
->x2
- pBox
->x1
;
236 dsth
= pBox
->y2
- pBox
->y1
;
237 srcX
= (pBox
->x1
- pPortPriv
->dst_x1
) *
238 pPortPriv
->src_w
/ pPortPriv
->dst_w
;
239 srcY
= (pBox
->y1
- pPortPriv
->dst_y1
) *
240 pPortPriv
->src_h
/ pPortPriv
->dst_h
;
241 srcw
= pPortPriv
->src_w
- srcX
;
242 srch
= pPortPriv
->src_h
- srcY
;
245 OUT_RING(DMA_PACKET0(R128_REG_SCALE_SRC_HEIGHT_WIDTH
, 2));
246 OUT_RING_REG(R128_REG_SCALE_SRC_HEIGHT_WIDTH
,
247 (srch
<< 16) | srcw
);
248 OUT_RING_REG(R128_REG_SCALE_OFFSET_0
, pPortPriv
->src_offset
+
249 srcY
* pPortPriv
->src_pitch
+ srcX
* 2);
251 OUT_RING(DMA_PACKET0(R128_REG_SCALE_DST_X_Y
, 2));
252 OUT_RING_REG(R128_REG_SCALE_DST_X_Y
, (dstX
<< 16) | dstY
);
253 OUT_RING_REG(R128_REG_SCALE_DST_HEIGHT_WIDTH
,
254 (dsth
<< 16) | dstw
);
259 /* XXX: Shouldn't this be in kxv.c instead? */
260 DamageDamageRegion(pPortPriv
->pDraw
, &pPortPriv
->clip
);
262 kaaMarkSync(pScreen
);
270 struct blend_vertex
{
272 union intfloat s0
, t0
;
275 #define VTX_DWORD_COUNT 4
277 #define VTX_OUT(vtx) \
281 OUT_RING(vtx.s0.i); \
282 OUT_RING(vtx.t0.i); \
286 RadeonDisplayVideo(KdScreenInfo
*screen
, ATIPortPrivPtr pPortPriv
)
288 ScreenPtr pScreen
= screen
->pScreen
;
289 KdScreenPriv(pScreen
);
290 ATICardInfo(pScreenPriv
);
291 ATIScreenInfo(pScreenPriv
);
292 struct blend_vertex vtx
[4];
293 PixmapPtr pPixmap
= pPortPriv
->pPixmap
;
295 CARD32 dst_offset
, dst_pitch
, dst_format
;
296 int dstxoff
, dstyoff
, pixel_shift
;
299 BoxPtr pBox
= REGION_RECTS(&pPortPriv
->clip
);
300 int nBox
= REGION_NUM_RECTS(&pPortPriv
->clip
);
302 switch (pPixmap
->drawable
.bitsPerPixel
) {
304 if (pPixmap
->drawable
.depth
== 15)
305 dst_format
= RADEON_COLOR_FORMAT_ARGB1555
;
307 dst_format
= RADEON_COLOR_FORMAT_RGB565
;
311 dst_format
= RADEON_COLOR_FORMAT_ARGB8888
;
318 dst_offset
= ((CARD8
*)pPixmap
->devPrivate
.ptr
-
319 pScreenPriv
->screen
->memory_base
);
320 dst_pitch
= pPixmap
->devKind
;
323 dstxoff
= -pPixmap
->screen_x
+ pPixmap
->drawable
.x
;
324 dstyoff
= -pPixmap
->screen_y
+ pPixmap
->drawable
.y
;
330 /* Same for R100/R200 */
331 if (pPortPriv
->id
== FOURCC_UYVY
)
332 txformat
= RADEON_TXFORMAT_YVYU422
;
334 txformat
= RADEON_TXFORMAT_VYUY422
;
336 txformat
|= RADEON_TXFORMAT_NON_POWER2
;
338 RadeonSwitchTo3D(atis
);
342 OUT_RING(DMA_PACKET0(RADEON_REG_PP_CNTL
, 3));
343 OUT_RING_REG(RADEON_REG_PP_CNTL
,
344 RADEON_TEX_0_ENABLE
| RADEON_TEX_BLEND_0_ENABLE
);
345 OUT_RING_REG(RADEON_REG_RB3D_CNTL
,
346 dst_format
| RADEON_ALPHA_BLEND_ENABLE
);
347 OUT_RING_REG(RADEON_REG_RB3D_COLOROFFSET
, dst_offset
);
349 OUT_REG(RADEON_REG_RB3D_COLORPITCH
, dst_pitch
>> pixel_shift
);
351 OUT_REG(RADEON_REG_RB3D_BLENDCNTL
,
352 RADEON_SBLEND_GL_ONE
| RADEON_DBLEND_GL_ZERO
);
359 OUT_REG(R200_REG_SE_VTX_FMT_0
, R200_VTX_XY
);
360 OUT_REG(R200_REG_SE_VTX_FMT_1
,
361 (2 << R200_VTX_TEX0_COMP_CNT_SHIFT
));
363 OUT_RING(DMA_PACKET0(R200_REG_PP_TXFILTER_0
, 5));
364 OUT_RING_REG(R200_REG_PP_TXFILTER_0
,
365 R200_MAG_FILTER_LINEAR
|
366 R200_MIN_FILTER_LINEAR
|
368 OUT_RING_REG(R200_REG_PP_TXFORMAT_0
, txformat
);
369 OUT_RING_REG(R200_REG_PP_TXFORMAT_X_0
, 0);
370 OUT_RING_REG(R200_REG_PP_TXSIZE_0
,
371 (pPixmap
->drawable
.width
- 1) |
372 ((pPixmap
->drawable
.height
- 1) << RADEON_TEX_VSIZE_SHIFT
));
373 OUT_RING_REG(R200_REG_PP_TXPITCH_0
, pPortPriv
->src_pitch
- 32);
375 OUT_REG(R200_PP_TXOFFSET_0
, pPortPriv
->src_offset
);
377 OUT_RING(DMA_PACKET0(R200_REG_PP_TXCBLEND_0
, 4));
378 OUT_RING_REG(R200_REG_PP_TXCBLEND_0
,
379 R200_TXC_ARG_A_ZERO
|
380 R200_TXC_ARG_B_ZERO
|
381 R200_TXC_ARG_C_R0_COLOR
|
383 OUT_RING_REG(R200_REG_PP_TXCBLEND2_0
,
384 R200_TXC_CLAMP_0_1
| R200_TXC_OUTPUT_REG_R0
);
385 OUT_RING_REG(R200_REG_PP_TXABLEND_0
,
386 R200_TXA_ARG_A_ZERO
|
387 R200_TXA_ARG_B_ZERO
|
388 R200_TXA_ARG_C_R0_ALPHA
|
390 OUT_RING_REG(R200_REG_PP_TXABLEND2_0
,
391 R200_TXA_CLAMP_0_1
| R200_TXA_OUTPUT_REG_R0
);
398 OUT_RING(DMA_PACKET0(RADEON_REG_PP_TXFILTER_0
, 5));
399 OUT_RING_REG(RADEON_REG_PP_TXFILTER_0
, RADEON_MAG_FILTER_LINEAR
|
400 RADEON_MIN_FILTER_LINEAR
|
402 OUT_RING_REG(RADEON_REG_PP_TXFORMAT_0
, txformat
);
403 OUT_RING_REG(RADEON_REG_PP_TXOFFSET_0
, pPortPriv
->src_offset
);
404 OUT_RING_REG(RADEON_REG_PP_TXCBLEND_0
,
405 RADEON_COLOR_ARG_A_ZERO
|
406 RADEON_COLOR_ARG_B_ZERO
|
407 RADEON_COLOR_ARG_C_T0_COLOR
|
408 RADEON_BLEND_CTL_ADD
|
410 OUT_RING_REG(RADEON_REG_PP_TXABLEND_0
,
411 RADEON_ALPHA_ARG_A_ZERO
|
412 RADEON_ALPHA_ARG_B_ZERO
|
413 RADEON_ALPHA_ARG_C_T0_ALPHA
|
414 RADEON_BLEND_CTL_ADD
|
417 OUT_RING(DMA_PACKET0(RADEON_REG_PP_TEX_SIZE_0
, 2));
418 OUT_RING_REG(RADEON_REG_PP_TEX_SIZE_0
,
419 (pPixmap
->drawable
.width
- 1) |
420 ((pPixmap
->drawable
.height
- 1) << RADEON_TEX_VSIZE_SHIFT
));
421 OUT_RING_REG(RADEON_REG_PP_TEX_PITCH_0
,
422 pPortPriv
->src_pitch
- 32);
424 // OUT_RING_REG(ATI_REG_WAIT_UNTIL, ATI_WAIT_CRTC_VLINE);
430 float srcX
, srcY
, dstX
, dstY
, srcw
, srch
, dstw
, dsth
;
432 dstX
= pBox
->x1
+ dstxoff
;
433 dstY
= pBox
->y1
+ dstyoff
;
434 dstw
= pBox
->x2
- pBox
->x1
;
435 dsth
= pBox
->y2
- pBox
->y1
;
436 srcX
= (pBox
->x1
- pPortPriv
->dst_x1
) *
437 pPortPriv
->src_w
/ pPortPriv
->dst_w
;
438 srcY
= (pBox
->y1
- pPortPriv
->dst_y1
) *
439 pPortPriv
->src_h
/ pPortPriv
->dst_h
;
440 srcw
= pPortPriv
->src_w
* (dstw
/ pPortPriv
->dst_w
);
441 srch
= pPortPriv
->src_h
* (dsth
/ pPortPriv
->dst_h
);
453 vtx
[0].y
.f
= dstY
+ dsth
;
455 vtx
[0].t0
.f
= srcY
+ srch
;
457 vtx
[1].x
.f
= dstX
+ dstw
;
458 vtx
[1].y
.f
= dstY
+ dsth
;
459 vtx
[1].s0
.f
= srcX
+ srcw
;
460 vtx
[1].t0
.f
= srcY
+ srch
;
462 vtx
[2].x
.f
= dstX
+ dstw
;
464 vtx
[2].s0
.f
= srcX
+ srcw
;
468 BEGIN_DMA(3 * VTX_DWORD_COUNT
+ 3);
469 OUT_RING(DMA_PACKET3(RADEON_CP_PACKET3_3D_DRAW_IMMD
,
470 3 * VTX_DWORD_COUNT
+ 2));
471 OUT_RING(RADEON_CP_VC_FRMT_XY
|
472 RADEON_CP_VC_FRMT_ST0
);
473 OUT_RING(RADEON_CP_VC_CNTL_PRIM_TYPE_RECT_LIST
|
474 RADEON_CP_VC_CNTL_PRIM_WALK_RING
|
475 RADEON_CP_VC_CNTL_MAOS_ENABLE
|
476 RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE
|
477 (3 << RADEON_CP_VC_CNTL_NUM_SHIFT
));
479 BEGIN_DMA(3 * VTX_DWORD_COUNT
+ 2);
480 OUT_RING(DMA_PACKET3(R200_CP_PACKET3_3D_DRAW_IMMD_2
,
481 3 * VTX_DWORD_COUNT
+ 1));
482 OUT_RING(RADEON_CP_VC_CNTL_PRIM_TYPE_RECT_LIST
|
483 RADEON_CP_VC_CNTL_PRIM_WALK_RING
|
484 (3 << RADEON_CP_VC_CNTL_NUM_SHIFT
));
495 /* XXX: Shouldn't this be in kxv.c instead? */
496 DamageDamageRegion(pPortPriv
->pDraw
, &pPortPriv
->clip
);
498 kaaMarkSync(pScreen
);
502 ATIVideoSave(ScreenPtr pScreen
, KdOffscreenArea
*area
)
504 KdScreenPriv(pScreen
);
505 ATIScreenInfo(pScreenPriv
);
506 ATIPortPrivPtr pPortPriv
= atis
->pAdaptor
->pPortPrivates
[0].ptr
;
508 if (pPortPriv
->off_screen
== area
)
509 pPortPriv
->off_screen
= 0;
513 ATIPutImage(KdScreenInfo
*screen
, DrawablePtr pDraw
,
514 short src_x
, short src_y
,
515 short drw_x
, short drw_y
,
516 short src_w
, short src_h
,
517 short drw_w
, short drw_h
,
526 ScreenPtr pScreen
= screen
->pScreen
;
527 KdScreenPriv(pScreen
);
528 ATICardInfo(pScreenPriv
);
529 ATIScreenInfo(pScreenPriv
);
530 ATIPortPrivPtr pPortPriv
= (ATIPortPrivPtr
)data
;
531 char *mmio
= atic
->reg_base
;
532 INT32 x1
, x2
, y1
, y2
;
533 int randr
= RR_Rotate_0
/* XXX */;
534 int srcPitch
, srcPitch2
, dstPitch
;
535 int top
, left
, npixels
, nlines
, size
;
537 int dst_width
= width
, dst_height
= height
;
538 int rot_x1
, rot_y1
, rot_x2
, rot_y2
;
539 int dst_x1
, dst_y1
, dst_x2
, dst_y2
;
540 int rot_src_w
, rot_src_h
, rot_drw_w
, rot_drw_h
;
549 dstBox
.x2
= drw_x
+ drw_w
;
551 dstBox
.y2
= drw_y
+ drw_h
;
553 ATIClipVideo(&dstBox
, &x1
, &x2
, &y1
, &y2
,
554 REGION_EXTENTS(pScreen
, clipBoxes
), width
, height
);
556 src_w
= (x2
- x1
) >> 16;
557 src_h
= (y2
- y1
) >> 16;
558 drw_w
= dstBox
.x2
- dstBox
.x1
;
559 drw_h
= dstBox
.y2
- dstBox
.y1
;
561 if ((x1
>= x2
) || (y1
>= y2
))
567 if (randr
& (RR_Rotate_0
|RR_Rotate_180
)) {
583 switch (randr
& RR_Rotate_All
) {
597 dst_y1
= screen
->height
- dstBox
.x2
;
599 dst_y2
= screen
->height
- dstBox
.x1
;
601 rot_y1
= (src_w
<< 16) - x2
;
603 rot_y2
= (src_w
<< 16) - x1
;
606 dst_x1
= screen
->width
- dstBox
.x2
;
607 dst_y1
= screen
->height
- dstBox
.y2
;
608 dst_x2
= screen
->width
- dstBox
.x1
;
609 dst_y2
= screen
->height
- dstBox
.y1
;
610 rot_x1
= (src_w
<< 16) - x2
;
611 rot_y1
= (src_h
<< 16) - y2
;
612 rot_x2
= (src_w
<< 16) - x1
;
613 rot_y2
= (src_h
<< 16) - y1
;
616 dst_x1
= screen
->width
- dstBox
.y2
;
618 dst_x2
= screen
->width
- dstBox
.y1
;
620 rot_x1
= (src_h
<< 16) - y2
;
622 rot_x2
= (src_h
<< 16) - y1
;
630 dstPitch
= ((dst_width
<< 1) + 15) & ~15;
631 srcPitch
= (width
+ 3) & ~3;
632 srcPitch2
= ((width
>> 1) + 3) & ~3;
633 size
= dstPitch
* dst_height
;
638 dstPitch
= ((dst_width
<< 1) + 15) & ~15;
639 srcPitch
= (width
<< 1);
641 size
= dstPitch
* dst_height
;
645 if (pPortPriv
->off_screen
!= NULL
&& size
!= pPortPriv
->size
) {
646 KdOffscreenFree(screen
->pScreen
, pPortPriv
->off_screen
);
647 pPortPriv
->off_screen
= 0;
650 if (pPortPriv
->off_screen
== NULL
) {
651 pPortPriv
->off_screen
= KdOffscreenAlloc(screen
->pScreen
,
652 size
* 2, 64, TRUE
, ATIVideoSave
, pPortPriv
);
653 if (pPortPriv
->off_screen
== NULL
)
658 if (pDraw
->type
== DRAWABLE_WINDOW
)
660 (*pScreen
->GetWindowPixmap
)((WindowPtr
)pDraw
);
662 pPortPriv
->pPixmap
= (PixmapPtr
)pDraw
;
664 /* Migrate the pixmap to offscreen if necessary. */
665 if (!kaaPixmapIsOffscreen(pPortPriv
->pPixmap
))
666 kaaMoveInPixmap(pPortPriv
->pPixmap
);
668 if (!kaaPixmapIsOffscreen(pPortPriv
->pPixmap
)) {
672 pPortPriv
->src_offset
= pPortPriv
->off_screen
->offset
;
673 pPortPriv
->src_addr
= (CARD8
*)(pScreenPriv
->screen
->memory_base
+
674 pPortPriv
->src_offset
);
675 pPortPriv
->src_pitch
= dstPitch
;
676 pPortPriv
->size
= size
;
677 pPortPriv
->pDraw
= pDraw
;
681 left
= (rot_x1
>> 16) & ~1;
682 npixels
= ((((rot_x2
+ 0xffff) >> 16) + 1) & ~1) - left
;
684 /* Since we're probably overwriting the area that might still be used
685 * for the last PutImage request, wait for idle.
693 nlines
= ((((rot_y2
+ 0xffff) >> 16) + 1) & ~1) - top
;
694 KdXVCopyPlanarData(screen
, buf
, pPortPriv
->src_addr
, randr
,
695 srcPitch
, srcPitch2
, dstPitch
, rot_src_w
, rot_src_h
,
696 height
, top
, left
, nlines
, npixels
, id
);
701 nlines
= ((rot_y2
+ 0xffff) >> 16) - top
;
702 KdXVCopyPackedData(screen
, buf
, pPortPriv
->src_addr
, randr
,
703 srcPitch
, dstPitch
, rot_src_w
, rot_src_h
, top
, left
,
708 /* update cliplist */
709 if (!REGION_EQUAL(screen
->pScreen
, &pPortPriv
->clip
, clipBoxes
)) {
710 REGION_COPY(screen
->pScreen
, &pPortPriv
->clip
, clipBoxes
);
714 pPortPriv
->src_x1
= rot_x1
;
715 pPortPriv
->src_y1
= rot_y1
;
716 pPortPriv
->src_x2
= rot_x2
;
717 pPortPriv
->src_y2
= rot_y2
;
718 pPortPriv
->src_w
= rot_src_w
;
719 pPortPriv
->src_h
= rot_src_h
;
720 pPortPriv
->dst_x1
= dst_x1
;
721 pPortPriv
->dst_y1
= dst_y1
;
722 pPortPriv
->dst_x2
= dst_x2
;
723 pPortPriv
->dst_y2
= dst_y2
;
724 pPortPriv
->dst_w
= rot_drw_w
;
725 pPortPriv
->dst_h
= rot_drw_h
;
728 RadeonDisplayVideo(screen
, pPortPriv
);
730 R128DisplayVideo(screen
, pPortPriv
);
736 ATIReputImage(KdScreenInfo
*screen
, DrawablePtr pDraw
, short drw_x
, short drw_y
,
737 RegionPtr clipBoxes
, pointer data
)
739 ScreenPtr pScreen
= screen
->pScreen
;
740 KdScreenPriv(pScreen
);
741 ATICardInfo(pScreenPriv
);
742 ATIPortPrivPtr pPortPriv
= (ATIPortPrivPtr
)data
;
743 BoxPtr pOldExtents
= REGION_EXTENTS(screen
->pScreen
, &pPortPriv
->clip
);
744 BoxPtr pNewExtents
= REGION_EXTENTS(screen
->pScreen
, clipBoxes
);
746 if (pOldExtents
->x1
!= pNewExtents
->x1
||
747 pOldExtents
->x2
!= pNewExtents
->x2
||
748 pOldExtents
->y1
!= pNewExtents
->y1
||
749 pOldExtents
->y2
!= pNewExtents
->y2
)
752 if (pDraw
->type
== DRAWABLE_WINDOW
)
754 (*pScreen
->GetWindowPixmap
)((WindowPtr
)pDraw
);
756 pPortPriv
->pPixmap
= (PixmapPtr
)pDraw
;
758 if (!kaaPixmapIsOffscreen(pPortPriv
->pPixmap
))
759 kaaMoveInPixmap(pPortPriv
->pPixmap
);
761 if (!kaaPixmapIsOffscreen(pPortPriv
->pPixmap
)) {
767 /* update cliplist */
768 if (!REGION_EQUAL(screen
->pScreen
, &pPortPriv
->clip
, clipBoxes
))
769 REGION_COPY(screen
->pScreen
, &pPortPriv
->clip
, clipBoxes
);
771 /* XXX: What do the drw_x and drw_y here mean for us? */
774 RadeonDisplayVideo(screen
, pPortPriv
);
776 R128DisplayVideo(screen
, pPortPriv
);
782 ATIQueryImageAttributes(KdScreenInfo
*screen
, int id
, unsigned short *w
,
783 unsigned short *h
, int *pitches
, int *offsets
)
787 if (*w
> IMAGE_MAX_WIDTH
)
788 *w
= IMAGE_MAX_WIDTH
;
789 if (*h
> IMAGE_MAX_HEIGHT
)
790 *h
= IMAGE_MAX_HEIGHT
;
801 size
= (*w
+ 3) & ~3;
807 tmp
= ((*w
>> 1) + 3) & ~3;
809 pitches
[1] = pitches
[2] = tmp
;
830 /* client libraries expect an encoding */
831 static KdVideoEncodingRec DummyEncoding
[1] =
836 IMAGE_MAX_WIDTH
, IMAGE_MAX_HEIGHT
,
841 #define NUM_FORMATS 3
843 static KdVideoFormatRec Formats
[NUM_FORMATS
] =
845 {15, TrueColor
}, {16, TrueColor
}, {24, TrueColor
}
848 #define NUM_ATTRIBUTES 0
850 static KdAttributeRec Attributes
[NUM_ATTRIBUTES
] =
856 static KdImageRec Images
[NUM_IMAGES
] =
864 static KdVideoAdaptorPtr
865 ATISetupImageVideo(ScreenPtr pScreen
)
867 KdScreenPriv(pScreen
);
868 ATIScreenInfo(pScreenPriv
);
869 KdVideoAdaptorPtr adapt
;
870 ATIPortPrivPtr pPortPriv
;
873 atis
->num_texture_ports
= 16;
875 adapt
= xcalloc(1, sizeof(KdVideoAdaptorRec
) + atis
->num_texture_ports
*
876 (sizeof(ATIPortPrivRec
) + sizeof(DevUnion
)));
880 adapt
->type
= XvWindowMask
| XvInputMask
| XvImageMask
;
881 adapt
->flags
= VIDEO_CLIP_TO_VIEWPORT
;
882 adapt
->name
= "ATI Texture Video";
883 adapt
->nEncodings
= 1;
884 adapt
->pEncodings
= DummyEncoding
;
885 adapt
->nFormats
= NUM_FORMATS
;
886 adapt
->pFormats
= Formats
;
887 adapt
->nPorts
= atis
->num_texture_ports
;
888 adapt
->pPortPrivates
= (DevUnion
*)(&adapt
[1]);
891 (ATIPortPrivPtr
)(&adapt
->pPortPrivates
[atis
->num_texture_ports
]);
893 for (i
= 0; i
< atis
->num_texture_ports
; i
++)
894 adapt
->pPortPrivates
[i
].ptr
= &pPortPriv
[i
];
896 adapt
->nAttributes
= NUM_ATTRIBUTES
;
897 adapt
->pAttributes
= Attributes
;
898 adapt
->pImages
= Images
;
899 adapt
->nImages
= NUM_IMAGES
;
900 adapt
->PutVideo
= NULL
;
901 adapt
->PutStill
= NULL
;
902 adapt
->GetVideo
= NULL
;
903 adapt
->GetStill
= NULL
;
904 adapt
->StopVideo
= ATIStopVideo
;
905 adapt
->SetPortAttribute
= ATISetPortAttribute
;
906 adapt
->GetPortAttribute
= ATIGetPortAttribute
;
907 adapt
->QueryBestSize
= ATIQueryBestSize
;
908 adapt
->PutImage
= ATIPutImage
;
909 adapt
->ReputImage
= ATIReputImage
;
910 adapt
->QueryImageAttributes
= ATIQueryImageAttributes
;
912 /* gotta uninit this someplace */
913 REGION_INIT(pScreen
, &pPortPriv
->clip
, NullBox
, 0);
915 atis
->pAdaptor
= adapt
;
917 xvBrightness
= MAKE_ATOM("XV_BRIGHTNESS");
918 xvSaturation
= MAKE_ATOM("XV_SATURATION");
923 Bool
ATIInitVideo(ScreenPtr pScreen
)
925 KdScreenPriv(pScreen
);
926 ATIScreenInfo(pScreenPriv
);
927 ATICardInfo(pScreenPriv
);
928 KdScreenInfo
*screen
= pScreenPriv
->screen
;
929 KdVideoAdaptorPtr
*adaptors
, *newAdaptors
= NULL
;
930 KdVideoAdaptorPtr newAdaptor
= NULL
;
933 atis
->pAdaptor
= NULL
;
935 if (atic
->reg_base
== NULL
)
940 num_adaptors
= KdXVListGenericAdaptors(screen
, &adaptors
);
942 newAdaptor
= ATISetupImageVideo(pScreen
);
947 adaptors
= &newAdaptor
;
949 newAdaptors
= xalloc((num_adaptors
+ 1) *
950 sizeof(KdVideoAdaptorPtr
*));
952 memcpy(newAdaptors
, adaptors
, num_adaptors
*
953 sizeof(KdVideoAdaptorPtr
));
954 newAdaptors
[num_adaptors
] = newAdaptor
;
955 adaptors
= newAdaptors
;
962 KdXVScreenInit(pScreen
, adaptors
, num_adaptors
);
971 ATIFiniVideo(ScreenPtr pScreen
)
973 KdScreenPriv(pScreen
);
974 ATIScreenInfo(pScreenPriv
);
975 KdVideoAdaptorPtr adapt
= atis
->pAdaptor
;
976 ATIPortPrivPtr pPortPriv
;
982 for (i
= 0; i
< atis
->num_texture_ports
; i
++) {
983 pPortPriv
= (ATIPortPrivPtr
)(&adapt
->pPortPrivates
[i
].ptr
);
984 REGION_UNINIT(pScreen
, &pPortPriv
->clip
);
987 atis
->pAdaptor
= NULL
;