2 Copyright © 2004, The AROS Development Team. All rights reserved.
8 #include "radeon_reg.h"
9 #include "radeon_bios.h"
10 #include "radeon_accel.h"
11 #include "radeon_macros.h"
14 #include <hidd/graphics.h>
15 #include <hidd/hidd.h>
17 #include <proto/oop.h>
18 #include <proto/utility.h>
21 #include <aros/debug.h>
23 #define sd ((struct ati_staticdata*)SD(cl))
25 #undef HiddPCIDeviceAttrBase
26 #undef HiddGfxAttrBase
27 #undef HiddPixFmtAttrBase
28 #undef HiddSyncAttrBase
29 #undef HiddBitMapAttrBase
30 #define HiddPCIDeviceAttrBase (sd->pciAttrBase)
31 #define HiddATIBitMapAttrBase (sd->atiBitMapAttrBase)
32 #define HiddBitMapAttrBase (sd->bitMapAttrBase)
33 #define HiddPixFmtAttrBase (sd->pixFmtAttrBase)
34 #define HiddGfxAttrBase (sd->gfxAttrBase)
35 #define HiddSyncAttrBase (sd->syncAttrBase)
37 #define POINT_OUTSIDE_CLIP(gc, x, y) \
38 ( (x) < GC_CLIPX1(gc) \
39 || (x) > GC_CLIPX2(gc) \
40 || (y) < GC_CLIPY1(gc) \
41 || (y) > GC_CLIPY2(gc) )
43 struct pRoot_Dispose
{
47 OOP_Object
*METHOD(ATIOffBM
, Root
, New
)
48 __attribute__((alias(METHOD_NAME_S(ATIOnBM
, Root
, New
))));
50 OOP_Object
*METHOD(ATIOnBM
, Root
, New
)
52 if (cl
== sd
->OnBMClass
)
53 EnterFunc(bug("[ATIBitMap] OnBitmap::New()\n"));
55 EnterFunc(bug("[ATIBitMap] OffBitmap::New()\n"));
57 o
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
60 atiBitMap
*bm
= OOP_INST_DATA(cl
, o
);
62 ULONG width
, height
, depth
;
68 InitSemaphore(&bm
->bmLock
);
70 D(bug("[ATIBitMap] Super called. o=%p\n", o
));
72 bm
->onbm
= (cl
== sd
->OnBMClass
);
74 OOP_GetAttr(o
, aHidd_BitMap_Width
, &width
);
75 OOP_GetAttr(o
, aHidd_BitMap_Height
, &height
);
76 OOP_GetAttr(o
, aHidd_BitMap_PixFmt
, (APTR
)&pf
);
77 OOP_GetAttr(pf
, aHidd_PixFmt_Depth
, &depth
);
78 fb
= GetTagData(aHidd_BitMap_FrameBuffer
, FALSE
, msg
->attrList
);
80 D(bug("[ATIBitmap] width=%d height=%d depth=%d\n", width
, height
, depth
));
82 if (width
== 0 || height
== 0 || depth
== 0)
84 bug("[ATIBitMap] size mismatch!\n");
107 bm
->pitch
= (width
* bytesPerPixel
+ 63) & ~63;
109 bm
->bpp
= bytesPerPixel
;
110 bm
->framebuffer
= AllocBitmapArea(sd
, bm
->width
, bm
->height
, bm
->bpp
, TRUE
);
115 bm
->addresses
= AllocVecPooled(sd
->memPool
, height
* sizeof(void*));
117 if (bm
->framebuffer
!= -1)
120 for (__tmp
=0; __tmp
< height
; __tmp
++)
121 bm
->addresses
[__tmp
] = (void*)(bm
->framebuffer
+ sd
->Card
.FrameBuffer
+ __tmp
*bm
->pitch
);
123 ULONG pitch64
= ((bm
->pitch
)) >> 6;
140 bm
->dp_gui_master_cntl
=
141 ((bm
->datatype
<< RADEON_GMC_DST_DATATYPE_SHIFT
)
142 |RADEON_GMC_CLR_CMP_CNTL_DIS
143 |RADEON_GMC_DST_PITCH_OFFSET_CNTL
);
145 bm
->pitch_offset
= ((bm
->framebuffer
>> 10) | (bm
->pitch
<< 16));
147 D(bug("[ATIBitMap] PITCH_OFFSET=%08x\n", bm
->pitch_offset
));
150 if (cl
== sd
->OnBMClass
)
152 if (fb
&& bm
->framebuffer
!= -1)
154 bm
->state
= (struct CardState
*)AllocPooled(sd
->memPool
,
155 sizeof(struct CardState
));
157 bzero((APTR
)(sd
->Card
.FrameBuffer
+ bm
->framebuffer
), 640*480*2);
163 InitMode(sd
, bm
->state
, 640, 480, 16, 25200, bm
->framebuffer
,
168 LoadState(sd
, bm
->state
);
169 //LoadState(sd, sd->poweron_state);
172 RADEONEngineReset(sd
);
173 RADEONEngineRestore(sd
);
180 else if (bm
->framebuffer
!= -1)
185 /* We should be able to get modeID from the bitmap */
186 OOP_GetAttr(o
, aHidd_BitMap_ModeID
, &modeid
);
188 D(bug("[ATIBitMap] BM_ModeID=%x\n", modeid
));
190 if (modeid
!= vHidd_ModeID_Invalid
)
193 ULONG hdisp
, vdisp
, hstart
, hend
, htotal
, vstart
, vend
, vtotal
;
195 /* Get Sync and PixelFormat properties */
196 struct pHidd_Gfx_GetMode __getmodemsg
= {
200 }, *getmodemsg
= &__getmodemsg
;
202 getmodemsg
->mID
= OOP_GetMethodID((STRPTR
)CLID_Hidd_Gfx
, moHidd_Gfx_GetMode
);
203 OOP_DoMethod(sd
->AtiObject
, (OOP_Msg
)getmodemsg
);
205 OOP_GetAttr(sync
, aHidd_Sync_PixelClock
, &pixel
);
206 OOP_GetAttr(sync
, aHidd_Sync_HDisp
, &hdisp
);
207 OOP_GetAttr(sync
, aHidd_Sync_VDisp
, &vdisp
);
208 OOP_GetAttr(sync
, aHidd_Sync_HSyncStart
, &hstart
);
209 OOP_GetAttr(sync
, aHidd_Sync_VSyncStart
, &vstart
);
210 OOP_GetAttr(sync
, aHidd_Sync_HSyncEnd
, &hend
);
211 OOP_GetAttr(sync
, aHidd_Sync_VSyncEnd
, &vend
);
212 OOP_GetAttr(sync
, aHidd_Sync_HTotal
, &htotal
);
213 OOP_GetAttr(sync
, aHidd_Sync_VTotal
, &vtotal
);
215 bm
->state
= (struct CardState
*)AllocPooled(sd
->memPool
,
216 sizeof(struct CardState
));
224 InitMode(sd
, bm
->state
, width
, height
, depth
, pixel
, bm
->framebuffer
,
226 hstart
, hend
, htotal
,
227 vstart
, vend
, vtotal
);
229 LoadState(sd
, bm
->state
);
232 RADEONEngineReset(sd
);
233 RADEONEngineRestore(sd
);
244 if (bm
->framebuffer
== -1)
247 bm
->framebuffer
= (IPTR
)AllocMem(bm
->pitch
* bm
->height
,
248 MEMF_PUBLIC
| MEMF_CLEAR
);
251 for (__tmp
=0; __tmp
< height
; __tmp
++)
252 bm
->addresses
[__tmp
] = (void*)(bm
->framebuffer
+ __tmp
*bm
->pitch
);
257 if ((bm
->framebuffer
!= 0xffffffff) && (bm
->framebuffer
!= 0))
263 OOP_MethodID disp_mid
= OOP_GetMethodID((STRPTR
)IID_Root
, moRoot_Dispose
);
264 OOP_CoerceMethod(cl
, o
, (OOP_Msg
) &disp_mid
);
271 VOID
METHOD(ATIOffBM
, Root
, Dispose
)
272 __attribute__((alias(METHOD_NAME_S(ATIOnBM
, Root
, Dispose
))));
274 VOID
METHOD(ATIOnBM
, Root
, Dispose
)
276 atiBitMap
*bm
= OOP_INST_DATA(cl
, o
);
280 // NVDmaKickoff(&sd->Card);
281 RADEONWaitForIdleMMIO(sd
);
285 FreeBitmapArea(sd
, bm
->framebuffer
, bm
->width
, bm
->height
, bm
->bpp
);
287 bm
->framebuffer
= -1;
291 FreeMem((APTR
)bm
->framebuffer
, bm
->pitch
* bm
->height
);
293 FreeVecPooled(sd
->memPool
, bm
->addresses
);
296 FreePooled(sd
->memPool
, bm
->state
, sizeof(struct CardState
));
303 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
307 VOID
METHOD(ATIOffBM
, Root
, Get
)
308 __attribute__((alias(METHOD_NAME_S(ATIOnBM
, Root
, Get
))));
310 VOID
METHOD(ATIOnBM
, Root
, Get
)
312 atiBitMap
*bm
= OOP_INST_DATA(cl
, o
);
315 if (IS_ATIBM_ATTR(msg
->attrID
, idx
))
319 case aoHidd_ATIBitMap_Drawable
:
321 *msg
->storage
= bm
->framebuffer
+ (IPTR
)sd
->Card
.FrameBuffer
;
323 *msg
->storage
= bm
->framebuffer
;
327 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
332 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
337 VOID
METHOD(ATIOffBM
, Hidd_BitMap
, Clear
)
338 __attribute__((alias(METHOD_NAME_S(ATIOnBM
, Hidd_BitMap
, Clear
))));
340 VOID
METHOD(ATIOnBM
, Hidd_BitMap
, Clear
)
342 atiBitMap
*bm
= OOP_INST_DATA(cl
, o
);
344 D(bug("[ATI] Clear(%p)\n",
352 sd
->Card
.Busy
= TRUE
;
355 RADEONWaitForFifo(sd
, 1);
356 OUTREG(RADEON_DST_PITCH_OFFSET
, bm
->pitch_offset
);
358 bm
->dp_gui_master_cntl_clip
= (bm
->dp_gui_master_cntl
359 | RADEON_GMC_BRUSH_SOLID_COLOR
360 | RADEON_GMC_SRC_DATATYPE_COLOR
361 | RADEON_ROP
[vHidd_GC_DrawMode_Copy
].pattern
);
363 RADEONWaitForFifo(sd
, 4);
365 OUTREG(RADEON_DP_GUI_MASTER_CNTL
, bm
->dp_gui_master_cntl_clip
);
366 OUTREG(RADEON_DP_BRUSH_FRGD_CLR
, GC_BG(msg
->gc
));
367 OUTREG(RADEON_DP_WRITE_MASK
, ~0);
368 OUTREG(RADEON_DP_CNTL
, (RADEON_DST_X_LEFT_TO_RIGHT
369 | RADEON_DST_Y_TOP_TO_BOTTOM
));
371 RADEONWaitForFifo(sd
, 2);
373 OUTREG(RADEON_DST_Y_X
, 0);
374 OUTREG(RADEON_DST_WIDTH_HEIGHT
, (bm
->width
<< 16) | (UWORD
)bm
->height
);
380 ULONG
*ptr
= (ULONG
*)bm
->framebuffer
;
382 int i
= (bm
->pitch
* bm
->height
) >> 2;
387 val
= GC_BG(msg
->gc
) << 16 | (GC_BG(msg
->gc
) & 0xffff);
391 val
= GC_BG(msg
->gc
) << 16 | (GC_BG(msg
->gc
) & 0xffff);
395 do { *ptr
++ = val
; } while(--i
);
401 struct pHidd_BitMap_FillRect
{
402 struct pHidd_BitMap_DrawRect dr
;
405 VOID
METHOD(ATIOffBM
, Hidd_BitMap
, FillRect
)
406 __attribute__((alias(METHOD_NAME_S(ATIOnBM
, Hidd_BitMap
, FillRect
))));
408 VOID
METHOD(ATIOnBM
, Hidd_BitMap
, FillRect
)
410 OOP_Object
*gc
= msg
->dr
.gc
;
411 atiBitMap
*bm
= OOP_INST_DATA(cl
, o
);
413 D(bug("[ATI] FillRect(%p, %d:%d - %d:%d)\n",
414 bm
->framebuffer
, msg
->dr
.minX
, msg
->dr
.minY
, msg
->dr
.maxX
, msg
->dr
.maxY
));
421 sd
->Card
.Busy
= TRUE
;
424 RADEONWaitForFifo(sd
, 1);
425 OUTREG(RADEON_DST_PITCH_OFFSET
, bm
->pitch_offset
);
427 bm
->dp_gui_master_cntl_clip
= (bm
->dp_gui_master_cntl
428 | RADEON_GMC_BRUSH_SOLID_COLOR
429 | RADEON_GMC_SRC_DATATYPE_COLOR
430 | RADEON_ROP
[GC_DRMD(gc
)].pattern
);
432 RADEONWaitForFifo(sd
, 4);
434 OUTREG(RADEON_DP_GUI_MASTER_CNTL
, bm
->dp_gui_master_cntl_clip
);
435 OUTREG(RADEON_DP_BRUSH_FRGD_CLR
, GC_FG(gc
));
436 OUTREG(RADEON_DP_WRITE_MASK
, ~0);
437 OUTREG(RADEON_DP_CNTL
, (RADEON_DST_X_LEFT_TO_RIGHT
438 | RADEON_DST_Y_TOP_TO_BOTTOM
));
440 RADEONWaitForFifo(sd
, 2);
442 OUTREG(RADEON_DST_Y_X
, (msg
->dr
.minY
<< 16) | (UWORD
)msg
->dr
.minX
);
443 OUTREG(RADEON_DST_WIDTH_HEIGHT
, ((msg
->dr
.maxX
- msg
->dr
.minX
+ 1) << 16) | (UWORD
)(msg
->dr
.maxY
- msg
->dr
.minY
+ 1));
449 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
457 VOID
METHOD(ATIOffBM
, Hidd_BitMap
, DrawLine
)
458 __attribute__((alias(METHOD_NAME_S(ATIOnBM
, Hidd_BitMap
, DrawLine
))));
460 VOID
METHOD(ATIOnBM
, Hidd_BitMap
, DrawLine
)
462 OOP_Object
*gc
= msg
->gc
;
463 atiBitMap
*bm
= OOP_INST_DATA(cl
, o
);
465 D(bug("[ATI] DrawLine(%p, %d:%d - %d:%d) %08x\n",
466 bm
->framebuffer
, msg
->x1
, msg
->y1
, msg
->x2
, msg
->y2
,GC_FG(gc
)));
470 if ((GC_LINEPAT(gc
) =! (UWORD
)~0) || !bm
->fbgfx
)
472 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
477 sd
->Card
.Busy
= TRUE
;
480 RADEONWaitForFifo(sd
, 1);
481 OUTREG(RADEON_DST_PITCH_OFFSET
, bm
->pitch_offset
);
483 bm
->dp_gui_master_cntl_clip
= (bm
->dp_gui_master_cntl
484 | RADEON_GMC_BRUSH_SOLID_COLOR
485 | RADEON_GMC_SRC_DATATYPE_COLOR
486 | RADEON_ROP
[GC_DRMD(gc
)].pattern
);
488 if (sd
->Card
.Type
>= RV200
) {
489 RADEONWaitForFifo(sd
, 1);
490 OUTREG(RADEON_DST_LINE_PATCOUNT
,
491 0x55 << RADEON_BRES_CNTL_SHIFT
);
496 bm
->dp_gui_master_cntl_clip
|= RADEON_GMC_DST_CLIPPING
;
500 x2
= GC_CLIPX2(gc
) + 1;
501 y2
= GC_CLIPY2(gc
) + 1;
506 x1
|= RADEON_SC_SIGN_MASK_LO
;
511 x2
|= RADEON_SC_SIGN_MASK_LO
;
516 y1
|= RADEON_SC_SIGN_MASK_LO
;
521 y2
|= RADEON_SC_SIGN_MASK_LO
;
524 RADEONWaitForFifo(sd
, 5);
525 OUTREG(RADEON_DP_GUI_MASTER_CNTL
, bm
->dp_gui_master_cntl_clip
);
526 OUTREG(RADEON_SC_TOP_LEFT
, (y1
<< 16) | (UWORD
)x1
);
527 OUTREG(RADEON_SC_BOTTOM_RIGHT
, (y2
<< 16) | (UWORD
)x2
);
531 RADEONWaitForFifo(sd
, 3);
532 OUTREG(RADEON_DP_GUI_MASTER_CNTL
, bm
->dp_gui_master_cntl_clip
);
534 OUTREG(RADEON_DP_BRUSH_FRGD_CLR
, GC_FG(gc
));
535 OUTREG(RADEON_DP_WRITE_MASK
, ~0);
537 RADEONWaitForFifo(sd
, 2);
539 OUTREG(RADEON_DST_LINE_START
, (msg
->y1
<< 16) | (UWORD
)msg
->x1
);
540 OUTREG(RADEON_DST_LINE_END
, (msg
->y2
<< 16) | (UWORD
)msg
->x2
);
541 // OUTREG(RADEON_DST_LINE_START, (msg->y2 << 16) | msg->x2);
542 // OUTREG(RADEON_DST_LINE_END, ((msg->y2+1) << 16) | (msg->x2+1));
551 VOID
METHOD(ATIOffBM
, Hidd_BitMap
, DrawRect
)
552 __attribute__((alias(METHOD_NAME_S(ATIOnBM
, Hidd_BitMap
, DrawRect
))));
554 VOID
METHOD(ATIOnBM
, Hidd_BitMap
, DrawRect
)
556 OOP_Object
*gc
= msg
->gc
;
557 atiBitMap
*bm
= OOP_INST_DATA(cl
, o
);
560 D(bug("[ATI] DrawRect(%p, %d:%d - %d:%d)\n",
561 bm
->framebuffer
, msg
->minX
, msg
->minY
, msg
->maxX
, msg
->maxY
));
563 if (msg
->minX
== msg
->maxX
) addX
= 1; else addX
= 0;
564 if (msg
->minY
== msg
->maxY
) addY
= 1; else addY
= 0;
568 if ((GC_LINEPAT(gc
) =! (UWORD
)~0) || !bm
->fbgfx
)
570 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
575 sd
->Card
.Busy
= TRUE
;
578 RADEONWaitForFifo(sd
, 1);
579 OUTREG(RADEON_DST_PITCH_OFFSET
, bm
->pitch_offset
);
581 bm
->dp_gui_master_cntl_clip
= (bm
->dp_gui_master_cntl
582 | RADEON_GMC_BRUSH_SOLID_COLOR
583 | RADEON_GMC_SRC_DATATYPE_COLOR
584 | RADEON_ROP
[GC_DRMD(gc
)].pattern
);
586 if (sd
->Card
.Type
>= RV200
) {
587 RADEONWaitForFifo(sd
, 1);
588 OUTREG(RADEON_DST_LINE_PATCOUNT
,
589 0x55 << RADEON_BRES_CNTL_SHIFT
);
594 bm
->dp_gui_master_cntl_clip
|= RADEON_GMC_DST_CLIPPING
;
598 x2
= GC_CLIPX2(gc
) + 1;
599 y2
= GC_CLIPY2(gc
) + 1;
604 x1
|= RADEON_SC_SIGN_MASK_LO
;
609 x2
|= RADEON_SC_SIGN_MASK_LO
;
614 y1
|= RADEON_SC_SIGN_MASK_LO
;
619 y2
|= RADEON_SC_SIGN_MASK_LO
;
622 RADEONWaitForFifo(sd
, 5);
623 OUTREG(RADEON_DP_GUI_MASTER_CNTL
, bm
->dp_gui_master_cntl_clip
);
624 OUTREG(RADEON_SC_TOP_LEFT
, (y1
<< 16) | (UWORD
)x1
);
625 OUTREG(RADEON_SC_BOTTOM_RIGHT
, (y2
<< 16) | (UWORD
)x2
);
629 RADEONWaitForFifo(sd
, 3);
630 OUTREG(RADEON_DP_GUI_MASTER_CNTL
, bm
->dp_gui_master_cntl_clip
);
632 OUTREG(RADEON_DP_BRUSH_FRGD_CLR
, GC_FG(gc
));
633 OUTREG(RADEON_DP_WRITE_MASK
, ~0);
635 RADEONWaitForFifo(sd
, 8);
637 OUTREG(RADEON_DST_LINE_START
, (msg
->minY
<< 16) | (msg
->minX
& 0xffff));
638 OUTREG(RADEON_DST_LINE_END
, (msg
->minY
<< 16) | (msg
->maxX
& 0xffff));
640 OUTREG(RADEON_DST_LINE_START
, ((msg
->minY
+ addY
) << 16) | (msg
->maxX
& 0xffff));
641 OUTREG(RADEON_DST_LINE_END
, ((msg
->maxY
<< 16)) | (msg
->maxX
& 0xffff));
643 OUTREG(RADEON_DST_LINE_START
, ((msg
->maxY
<< 16)) | ((msg
->maxX
- addX
) & 0xffff));
644 OUTREG(RADEON_DST_LINE_END
, ((msg
->maxY
<< 16)) | ((msg
->minX
) & 0xffff));
646 OUTREG(RADEON_DST_LINE_START
, ((msg
->maxY
- addY
) << 16) | (msg
->minX
& 0xffff));
647 OUTREG(RADEON_DST_LINE_END
, ((msg
->minY
+ addY
) << 16) | (msg
->minX
& 0xffff));
656 VOID
METHOD(ATIOffBM
, Hidd_BitMap
, DrawPolygon
)
657 __attribute__((alias(METHOD_NAME_S(ATIOnBM
, Hidd_BitMap
, DrawPolygon
))));
659 VOID
METHOD(ATIOnBM
, Hidd_BitMap
, DrawPolygon
)
661 OOP_Object
*gc
= msg
->gc
;
662 atiBitMap
*bm
= OOP_INST_DATA(cl
, o
);
665 D(bug("[ATI] DrawPolygon(%p)\n",
670 if ((GC_LINEPAT(gc
) =! (UWORD
)~0) || !bm
->fbgfx
)
672 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
677 sd
->Card
.Busy
= TRUE
;
680 RADEONWaitForFifo(sd
, 1);
681 OUTREG(RADEON_DST_PITCH_OFFSET
, bm
->pitch_offset
);
683 bm
->dp_gui_master_cntl_clip
= (bm
->dp_gui_master_cntl
684 | RADEON_GMC_BRUSH_SOLID_COLOR
685 | RADEON_GMC_SRC_DATATYPE_COLOR
686 | RADEON_ROP
[GC_DRMD(gc
)].pattern
);
688 if (sd
->Card
.Type
>= RV200
) {
689 RADEONWaitForFifo(sd
, 1);
690 OUTREG(RADEON_DST_LINE_PATCOUNT
,
691 0x55 << RADEON_BRES_CNTL_SHIFT
);
696 bm
->dp_gui_master_cntl_clip
|= RADEON_GMC_DST_CLIPPING
;
700 x2
= GC_CLIPX2(gc
) + 1;
701 y2
= GC_CLIPY2(gc
) + 1;
706 x1
|= RADEON_SC_SIGN_MASK_LO
;
711 x2
|= RADEON_SC_SIGN_MASK_LO
;
716 y1
|= RADEON_SC_SIGN_MASK_LO
;
721 y2
|= RADEON_SC_SIGN_MASK_LO
;
724 RADEONWaitForFifo(sd
, 5);
725 OUTREG(RADEON_DP_GUI_MASTER_CNTL
, bm
->dp_gui_master_cntl_clip
);
726 OUTREG(RADEON_SC_TOP_LEFT
, (y1
<< 16) | (UWORD
)x1
);
727 OUTREG(RADEON_SC_BOTTOM_RIGHT
, (y2
<< 16) | (UWORD
)x2
);
731 RADEONWaitForFifo(sd
, 3);
732 OUTREG(RADEON_DP_GUI_MASTER_CNTL
, bm
->dp_gui_master_cntl_clip
);
734 OUTREG(RADEON_DP_BRUSH_FRGD_CLR
, GC_FG(gc
));
735 OUTREG(RADEON_DP_WRITE_MASK
, ~0);
737 for (i
= 2; i
< (2 * msg
->n
); i
+=2)
739 RADEONWaitForFifo(sd
, 2);
740 OUTREG(RADEON_DST_LINE_START
, (msg
->coords
[i
-1] << 16) | (UWORD
)msg
->coords
[i
-2]);
741 OUTREG(RADEON_DST_LINE_END
, (msg
->coords
[i
+1] << 16) | (UWORD
)msg
->coords
[i
]);
750 VOID
METHOD(ATIOffBM
, Hidd_BitMap
, PutPixel
)
751 __attribute__((alias(METHOD_NAME_S(ATIOnBM
, Hidd_BitMap
, PutPixel
))));
753 VOID
METHOD(ATIOnBM
, Hidd_BitMap
, PutPixel
)
755 atiBitMap
*bm
= OOP_INST_DATA(cl
, o
);
756 void *ptr
= bm
->addresses
[msg
->y
];
765 #warning TODO: NVSync(sd)
766 RADEONWaitForIdleMMIO(sd
);
775 ((UBYTE
*)ptr
)[msg
->x
] = msg
->pixel
;
778 ((UWORD
*)ptr
)[msg
->x
] = msg
->pixel
;
781 ((ULONG
*)ptr
)[msg
->x
] = msg
->pixel
;
788 VOID
METHOD(ATIOffBM
, Hidd_BitMap
, DrawPixel
)
789 __attribute__((alias(METHOD_NAME_S(ATIOnBM
, Hidd_BitMap
, DrawPixel
))));
791 VOID
METHOD(ATIOnBM
, Hidd_BitMap
, DrawPixel
)
793 atiBitMap
*bm
= OOP_INST_DATA(cl
, o
);
794 void *ptr
= bm
->addresses
[msg
->y
];
795 OOP_Object
*gc
= msg
->gc
;
797 HIDDT_Pixel src
, dest
, val
;
799 HIDDT_Pixel writeMask
;
811 #warning TODO: NVSync(sd)
812 RADEONWaitForIdleMMIO(sd
);
817 if (vHidd_GC_DrawMode_Copy
== mode
&& GC_COLMASK(gc
) == ~0)
826 dest
= ((UBYTE
*)ptr
)[msg
->x
];
829 dest
= ((UWORD
*)ptr
)[msg
->x
];
832 dest
= ((ULONG
*)ptr
)[msg
->x
];
836 writeMask
= ~GC_COLMASK(gc
) & dest
;
840 if(mode
& 1) val
= ( src
& dest
);
841 if(mode
& 2) val
= ( src
& ~dest
) | val
;
842 if(mode
& 4) val
= (~src
& dest
) | val
;
843 if(mode
& 8) val
= (~src
& ~dest
) | val
;
845 val
= (val
& (writeMask
| GC_COLMASK(gc
) )) | writeMask
;
851 ((UBYTE
*)ptr
)[msg
->x
] = val
;
854 ((UWORD
*)ptr
)[msg
->x
] = val
;
857 ((ULONG
*)ptr
)[msg
->x
] = val
;
864 VOID
METHOD(ATIOffBM
, Hidd_BitMap
, DrawEllipse
)
865 __attribute__((alias(METHOD_NAME_S(ATIOnBM
, Hidd_BitMap
, DrawEllipse
))));
867 VOID
METHOD(ATIOnBM
, Hidd_BitMap
, DrawEllipse
)
869 atiBitMap
*bm
= OOP_INST_DATA(cl
, o
);
870 OOP_Object
*gc
= msg
->gc
;
871 WORD x
= msg
->rx
, y
= 0; /* ellipse points */
874 HIDDT_Pixel writeMask
;
876 /* intermediate terms to speed up loop */
877 LONG t1
= msg
->rx
* msg
->rx
, t2
= t1
<< 1, t3
= t2
<< 1;
878 LONG t4
= msg
->ry
* msg
->ry
, t5
= t4
<< 1, t6
= t5
<< 1;
879 LONG t7
= msg
->rx
* t5
, t8
= t7
<< 1, t9
= 0L;
880 LONG d1
= t2
- t7
+ (t4
>> 1); /* error terms */
881 LONG d2
= (t1
>> 1) - t8
+ t5
;
883 BOOL doclip
= GC_DOCLIP(gc
);
888 void _drawpixel(int x
, int y
)
890 void *ptr
= bm
->addresses
[y
];
891 HIDDT_Pixel val
, dest
;
893 if (vHidd_GC_DrawMode_Copy
== mode
&& GC_COLMASK(gc
) == ~0)
902 dest
= ((UBYTE
*)ptr
)[x
];
905 dest
= ((UWORD
*)ptr
)[x
];
908 dest
= ((ULONG
*)ptr
)[x
];
912 writeMask
= ~GC_COLMASK(gc
) & dest
;
916 if(mode
& 1) val
= ( src
& dest
);
917 if(mode
& 2) val
= ( src
& ~dest
) | val
;
918 if(mode
& 4) val
= (~src
& dest
) | val
;
919 if(mode
& 8) val
= (~src
& ~dest
) | val
;
921 val
= (val
& (writeMask
| GC_COLMASK(gc
) )) | writeMask
;
927 ((UBYTE
*)ptr
)[x
] = val
;
930 ((UWORD
*)ptr
)[x
] = val
;
933 ((ULONG
*)ptr
)[x
] = val
;
940 UBYTE
*ptr
= (UBYTE
*)((IPTR
)bm
->framebuffer
);
943 ptr
+= (IPTR
)sd
->Card
.FrameBuffer
;
947 #warning TODO: NVSync(sd)
948 RADEONWaitForIdleMMIO(sd
);
953 while (d2
< 0) /* til slope = -1 */
955 /* draw 4 points using symmetry */
959 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
+ x
, msg
->y
+ y
))
960 _drawpixel(msg
->x
+ x
, msg
->y
+ y
);
962 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
+ x
, msg
->y
- y
))
963 _drawpixel(msg
->x
+ x
, msg
->y
- y
);
965 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
- x
, msg
->y
+ y
))
966 _drawpixel(msg
->x
- x
, msg
->y
+ y
);
968 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
- x
, msg
->y
- y
))
969 _drawpixel(msg
->x
- x
, msg
->y
- y
);
973 _drawpixel(msg
->x
+ x
, msg
->y
+ y
);
974 _drawpixel(msg
->x
+ x
, msg
->y
- y
);
975 _drawpixel(msg
->x
- x
, msg
->y
+ y
);
976 _drawpixel(msg
->x
- x
, msg
->y
- y
);
979 y
++; /* always move up here */
981 if (d1
< 0) /* move straight up */
986 else /* move up and left */
990 d1
= d1
+ t9
+ t2
- t8
;
991 d2
= d2
+ t9
+ t5
- t8
;
995 do /* rest of top right quadrant */
997 /* draw 4 points using symmetry */
1000 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
+ x
, msg
->y
+ y
))
1001 _drawpixel(msg
->x
+ x
, msg
->y
+ y
);
1003 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
+ x
, msg
->y
- y
))
1004 _drawpixel(msg
->x
+ x
, msg
->y
- y
);
1006 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
- x
, msg
->y
+ y
))
1007 _drawpixel(msg
->x
- x
, msg
->y
+ y
);
1009 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
- x
, msg
->y
- y
))
1010 _drawpixel(msg
->x
- x
, msg
->y
- y
);
1014 _drawpixel(msg
->x
+ x
, msg
->y
+ y
);
1015 _drawpixel(msg
->x
+ x
, msg
->y
- y
);
1016 _drawpixel(msg
->x
- x
, msg
->y
+ y
);
1017 _drawpixel(msg
->x
- x
, msg
->y
- y
);
1020 x
--; /* always move left here */
1022 if (d2
< 0) /* move up and left */
1026 d2
= d2
+ t9
+ t5
- t8
;
1028 else /* move straight left */
1039 HIDDT_Pixel
METHOD(ATIOffBM
, Hidd_BitMap
, GetPixel
)
1040 __attribute__((alias(METHOD_NAME_S(ATIOnBM
, Hidd_BitMap
, GetPixel
))));
1042 HIDDT_Pixel
METHOD(ATIOnBM
, Hidd_BitMap
, GetPixel
)
1044 HIDDT_Pixel pixel
=0;
1045 atiBitMap
*bm
= OOP_INST_DATA(cl
, o
);
1049 void *ptr
= bm
->addresses
[msg
->y
];
1056 #warning TODO: NVSync(sd)
1057 RADEONWaitForIdleMMIO(sd
);
1065 pixel
= ((UBYTE
*)ptr
)[msg
->x
];
1068 pixel
= ((UWORD
*)ptr
)[msg
->x
];
1071 pixel
= ((ULONG
*)ptr
)[msg
->x
];
1077 /* Get pen number from colortab */
1082 void METHOD(ATIOffBM
, Hidd_BitMap
, BlitColorExpansion
)
1083 __attribute__((alias(METHOD_NAME_S(ATIOnBM
, Hidd_BitMap
, BlitColorExpansion
))));
1085 void METHOD(ATIOnBM
, Hidd_BitMap
, BlitColorExpansion
)
1087 atiBitMap
*bm
= OOP_INST_DATA(cl
, o
);
1091 if ((OOP_OCLASS(msg
->srcBitMap
) == sd
->PlanarBMClass
) && bm
->fbgfx
)
1093 struct planarbm_data
*planar
= OOP_INST_DATA(OOP_OCLASS(msg
->srcBitMap
), msg
->srcBitMap
);
1096 ULONG skipleft
= msg
->srcX
- (msg
->srcX
& ~31);
1097 ULONG mask
= ~0 << bm
->depth
;
1099 if (bm
->depth
== 32)
1102 cemd
= GC_COLEXP(msg
->gc
);
1103 bg
= GC_BG(msg
->gc
) | mask
;
1104 fg
= GC_FG(msg
->gc
) | mask
;
1106 ULONG bw
= (msg
->width
+ 31 + skipleft
) & ~31;
1107 LONG x
= msg
->destX
, y
= msg
->destY
, w
= msg
->width
, h
= msg
->height
;
1112 sd
->Card
.Busy
= TRUE
;
1114 RADEONWaitForFifo(sd
, 1);
1115 OUTREG(RADEON_DST_PITCH_OFFSET
, bm
->pitch_offset
);
1117 bm
->dp_gui_master_cntl_clip
= (bm
->dp_gui_master_cntl
1118 | RADEON_GMC_WR_MSK_DIS
1119 | RADEON_GMC_BRUSH_NONE
1120 | RADEON_DP_SRC_SOURCE_HOST_DATA
1121 | RADEON_GMC_DST_CLIPPING
1122 | RADEON_GMC_BYTE_MSB_TO_LSB
1123 | RADEON_ROP
[GC_DRMD(msg
->gc
)].rop
);
1125 if (cemd
& vHidd_GC_ColExp_Transparent
)
1127 bm
->dp_gui_master_cntl_clip
|= RADEON_GMC_SRC_DATATYPE_MONO_FG_LA
;
1129 RADEONWaitForFifo(sd
, 6);
1130 OUTREG(RADEON_DP_GUI_MASTER_CNTL
, bm
->dp_gui_master_cntl_clip
);
1131 OUTREG(RADEON_DP_SRC_FRGD_CLR
, fg
);
1135 bm
->dp_gui_master_cntl_clip
|= RADEON_GMC_SRC_DATATYPE_MONO_FG_BG
;
1137 RADEONWaitForFifo(sd
, 7);
1138 OUTREG(RADEON_DP_GUI_MASTER_CNTL
, bm
->dp_gui_master_cntl_clip
);
1139 OUTREG(RADEON_DP_SRC_FRGD_CLR
, fg
);
1140 OUTREG(RADEON_DP_SRC_BKGD_CLR
, bg
);
1143 OUTREG(RADEON_SC_TOP_LEFT
, (y
<< 16) | (UWORD
)x
);
1144 OUTREG(RADEON_SC_BOTTOM_RIGHT
, ((y
+h
) << 16) | (UWORD
)(x
+w
));
1146 OUTREG(RADEON_DST_X_Y
, ((x
- skipleft
) << 16) | (UWORD
)y
);
1147 OUTREG(RADEON_DST_WIDTH_HEIGHT
, (bw
<< 16) | (UWORD
)h
);
1149 ULONG
*ptr
= (ULONG
*)planar
->planes
[0];
1150 ptr
+= ((msg
->srcY
* planar
->bytesperrow
) >> 2) + (msg
->srcX
>> 5);
1153 RADEONWaitForFifo(sd
, 1);
1154 OUTREG(RADEON_RBBM_GUICNTL
, RADEON_HOST_DATA_SWAP_32BIT
);
1161 for (i
=0; i
< bw
>> 5; i
++)
1163 RADEONWaitForFifo(sd
, 1);
1164 OUTREG(RADEON_HOST_DATA0
, ptr
[i
]);
1167 ptr
+= planar
->bytesperrow
>> 2;
1171 RADEONWaitForFifo(sd
, 1);
1172 OUTREG(RADEON_RBBM_GUICNTL
, RADEON_HOST_DATA_SWAP_NONE
);
1179 OOP_DoSuperMethod(cl
, o
, msg
);
1185 ULONG
METHOD(ATIOffBM
, Hidd_BitMap
, BytesPerLine
)
1186 __attribute__((alias(METHOD_NAME_S(ATIOnBM
, Hidd_BitMap
, BytesPerLine
))));
1188 ULONG
METHOD(ATIOnBM
, Hidd_BitMap
, BytesPerLine
)
1190 atiBitMap
*bm
= OOP_INST_DATA(cl
, o
);
1192 return (bm
->bpp
* msg
->width
+ 255) & ~255;
1196 BOOL
METHOD(ATIOffBM
, Hidd_BitMap
, ObtainDirectAccess
)
1197 __attribute__((alias(METHOD_NAME_S(ATIOnBM
, Hidd_BitMap
, ObtainDirectAccess
))));
1199 BOOL
METHOD(ATIOnBM
, Hidd_BitMap
, ObtainDirectAccess
)
1201 atiBitMap
*bm
= OOP_INST_DATA(cl
, o
);
1204 IPTR VideoData
= bm
->framebuffer
;
1208 VideoData
+= (IPTR
)sd
->Card
.FrameBuffer
;
1212 #warning TODO: NVSync(sd)
1213 RADEONWaitForIdleMMIO(sd
);
1218 *msg
->addressReturn
= (UBYTE
*)VideoData
;
1219 *msg
->widthReturn
= bm
->pitch
/ bm
->bpp
;
1220 *msg
->heightReturn
= bm
->height
;
1221 *msg
->bankSizeReturn
= *msg
->memSizeReturn
= bm
->pitch
* bm
->height
;
1226 VOID
METHOD(ATIOffBM
, Hidd_BitMap
, ReleaseDirectAccess
)
1227 __attribute__((alias(METHOD_NAME_S(ATIOnBM
, Hidd_BitMap
, ReleaseDirectAccess
))));
1229 VOID
METHOD(ATIOnBM
, Hidd_BitMap
, ReleaseDirectAccess
)
1231 atiBitMap
*bm
= OOP_INST_DATA(cl
, o
);
1238 * Unaccelerated methods
1241 VOID
METHOD(ATIOffBM
, Hidd_BitMap
, PutImageLUT
)
1242 __attribute__((alias(METHOD_NAME_S(ATIOnBM
, Hidd_BitMap
, PutImageLUT
))));
1244 VOID
METHOD(ATIOnBM
, Hidd_BitMap
, PutImageLUT
)
1246 atiBitMap
*bm
= OOP_INST_DATA(cl
, o
);
1253 UBYTE
*src
= msg
->pixels
;
1254 ULONG x_add
= msg
->modulo
;
1255 UWORD height
= msg
->height
;
1256 UWORD bw
= msg
->width
;
1257 HIDDT_Pixel
*colmap
= msg
->pixlut
->pixels
;
1265 sd
->Card
.Busy
= TRUE
;
1267 RADEONWaitForFifo(sd
, 1);
1268 OUTREG(RADEON_DST_PITCH_OFFSET
, bm
->pitch_offset
);
1270 bm
->dp_gui_master_cntl_clip
= (bm
->dp_gui_master_cntl
1271 | RADEON_GMC_WR_MSK_DIS
1272 | RADEON_GMC_BRUSH_NONE
1273 | RADEON_DP_SRC_SOURCE_HOST_DATA
1274 | RADEON_GMC_DST_CLIPPING
1275 | RADEON_GMC_SRC_DATATYPE_COLOR
1276 | RADEON_ROP
[vHidd_GC_DrawMode_Copy
].rop
);
1278 RADEONWaitForFifo(sd
, 5);
1279 OUTREG(RADEON_DP_GUI_MASTER_CNTL
, bm
->dp_gui_master_cntl_clip
);
1281 OUTREG(RADEON_SC_TOP_LEFT
, (msg
->y
<< 16) | (UWORD
)msg
->x
);
1282 OUTREG(RADEON_SC_BOTTOM_RIGHT
, ((msg
->y
+msg
->height
) << 16) | (UWORD
)(msg
->x
+msg
->width
));
1284 OUTREG(RADEON_DST_X_Y
, ((msg
->x
) << 16) | (UWORD
)msg
->y
);
1285 OUTREG(RADEON_DST_WIDTH_HEIGHT
, (bw
<< 16) | (UWORD
)msg
->height
);
1290 RADEONWaitForFifo(sd
, 1);
1291 OUTREG(RADEON_RBBM_GUICNTL
, RADEON_HOST_DATA_SWAP_32BIT
);
1295 UBYTE
*line
= (UBYTE
*)src
;
1296 ULONG width
= msg
->width
;
1302 RADEONWaitForFifo(sd
, width
);
1305 case 8: OUTREGN(RADEON_HOST_DATA0
, colmap
[*line
++]);
1306 case 7: OUTREGN(RADEON_HOST_DATA1
, colmap
[*line
++]);
1307 case 6: OUTREGN(RADEON_HOST_DATA2
, colmap
[*line
++]);
1308 case 5: OUTREGN(RADEON_HOST_DATA3
, colmap
[*line
++]);
1309 case 4: OUTREGN(RADEON_HOST_DATA4
, colmap
[*line
++]);
1310 case 3: OUTREGN(RADEON_HOST_DATA5
, colmap
[*line
++]);
1311 case 2: OUTREGN(RADEON_HOST_DATA6
, colmap
[*line
++]);
1312 case 1: OUTREGN(RADEON_HOST_DATA7
, colmap
[*line
++]);
1318 RADEONWaitForFifo(sd
, 8);
1320 OUTREGN(RADEON_HOST_DATA0
, colmap
[*line
++]);
1321 OUTREGN(RADEON_HOST_DATA1
, colmap
[*line
++]);
1322 OUTREGN(RADEON_HOST_DATA2
, colmap
[*line
++]);
1323 OUTREGN(RADEON_HOST_DATA3
, colmap
[*line
++]);
1324 OUTREGN(RADEON_HOST_DATA4
, colmap
[*line
++]);
1325 OUTREGN(RADEON_HOST_DATA5
, colmap
[*line
++]);
1326 OUTREGN(RADEON_HOST_DATA6
, colmap
[*line
++]);
1327 OUTREGN(RADEON_HOST_DATA7
, colmap
[*line
++]);
1336 else if (bm
->bpp
== 2)
1339 RADEONWaitForFifo(sd
, 1);
1340 OUTREG(RADEON_RBBM_GUICNTL
, RADEON_HOST_DATA_SWAP_HDW
);
1344 UBYTE
*line
= (UBYTE
*)src
;
1345 ULONG width
= bw
>> 1;
1349 ULONG tmp
= (colmap
[line
[0]] << 16) | (colmap
[line
[1]] & 0x0000ffff);
1350 RADEONWaitForFifo(sd
, 1);
1351 OUTREG(RADEON_HOST_DATA0
, tmp
);
1361 RADEONWaitForFifo(sd
, 1);
1362 OUTREG(RADEON_RBBM_GUICNTL
, RADEON_HOST_DATA_SWAP_NONE
);
1368 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
1373 static inline int do_alpha(int a
, int v
)
1376 return ((tmp
<< 8) + tmp
+ 32768) >> 16;
1379 VOID
METHOD(ATIOffBM
, Hidd_BitMap
, PutAlphaImage
)
1380 __attribute__((alias(METHOD_NAME_S(ATIOnBM
, Hidd_BitMap
, PutAlphaImage
))));
1382 VOID
METHOD(ATIOnBM
, Hidd_BitMap
, PutAlphaImage
)
1384 atiBitMap
*bm
= OOP_INST_DATA(cl
, o
);
1389 IPTR VideoData
= bm
->framebuffer
;
1391 /* Try to PutAlphaImage with 2D engine first */
1394 ULONG x_add
= (msg
->modulo
- msg
->width
* 4) >> 2;
1395 UWORD height
= msg
->height
;
1396 UWORD bw
= msg
->width
;
1397 ULONG
*pixarray
= msg
->pixels
;
1401 D(bug("ATI: PutAlphaImage(%d, %d, %d:%d)\n", msg
->x
, msg
->y
, msg
->width
, msg
->height
));
1403 /* We're not going to use the 2D engine now. Therefore, flush the chip */
1407 RADEONWaitForIdleMMIO(sd
);
1412 * Treat each depth case separately
1418 ULONG
*xbuf
= bm
->addresses
[y
];
1421 for (x
=0; x
< bw
; x
++)
1425 LONG src_red
, src_green
, src_blue
, src_alpha
;
1426 LONG dst_red
, dst_green
, dst_blue
;
1428 /* Read RGBA pixel from input array */
1429 srcpix
= *pixarray
++;
1431 src_red
= (srcpix
& 0x00FF0000) >> 16;
1432 src_green
= (srcpix
& 0x0000FF00) >> 8;
1433 src_blue
= (srcpix
& 0x000000FF);
1434 src_alpha
= (srcpix
& 0xFF000000) >> 24;
1436 src_red
= (srcpix
& 0x0000FF00) >> 8;
1437 src_green
= (srcpix
& 0x00FF0000) >> 16;
1438 src_blue
= (srcpix
& 0xFF000000) >> 24;
1439 src_alpha
= (srcpix
& 0x000000FF);
1443 * If alpha=0, do not change the destination pixel at all.
1444 * This saves us unnecessary reads and writes to VRAM.
1449 * Full opacity. Do not read the destination pixel, as
1450 * it's value does not matter anyway.
1452 if (src_alpha
== 0xff)
1455 dst_green
= src_green
;
1456 dst_blue
= src_blue
;
1461 * Alpha blending with source and destination pixels.
1466 // #if AROS_BIG_ENDIAN
1467 // dst_red = (destpix & 0x0000FF00) >> 8;
1468 // dst_green = (destpix & 0x00FF0000) >> 16;
1469 // dst_blue = (destpix & 0xFF000000) >> 24;
1471 dst_red
= (destpix
& 0x00FF0000) >> 16;
1472 dst_green
= (destpix
& 0x0000FF00) >> 8;
1473 dst_blue
= (destpix
& 0x000000FF);
1476 dst_red
+= do_alpha(src_alpha
, src_red
- dst_red
);
1477 dst_green
+= do_alpha(src_alpha
, src_green
- dst_green
);
1478 dst_blue
+= do_alpha(src_alpha
, src_blue
- dst_blue
);
1482 // #if AROS_BIG_ENDIAN
1483 // destpix = (dst_blue << 24) + (dst_green << 16) + (dst_red << 8);
1485 destpix
= (dst_red
<< 16) + (dst_green
<< 8) + (dst_blue
);
1488 /* Store the new pixel */
1498 else if (bm
->bpp
== 2)
1500 if (bm
->depth
== 16)
1504 UWORD
*xbuf
= bm
->addresses
[y
];
1507 for (x
=0; x
< bw
; x
++)
1511 LONG src_red
, src_green
, src_blue
, src_alpha
;
1512 LONG dst_red
, dst_green
, dst_blue
;
1514 srcpix
= *pixarray
++;
1516 src_red
= (srcpix
& 0x00FF0000) >> 16;
1517 src_green
= (srcpix
& 0x0000FF00) >> 8;
1518 src_blue
= (srcpix
& 0x000000FF);
1519 src_alpha
= (srcpix
& 0xFF000000) >> 24;
1521 src_red
= (srcpix
& 0x0000FF00) >> 8;
1522 src_green
= (srcpix
& 0x00FF0000) >> 16;
1523 src_blue
= (srcpix
& 0xFF000000) >> 24;
1524 src_alpha
= (srcpix
& 0x000000FF);
1528 * If alpha=0, do not change the destination pixel at all.
1529 * This saves us unnecessary reads and writes to VRAM.
1534 * Full opacity. Do not read the destination pixel, as
1535 * it's value does not matter anyway.
1537 if (src_alpha
== 0xff)
1540 dst_green
= src_green
;
1541 dst_blue
= src_blue
;
1546 * Alpha blending with source and destination pixels.
1552 dst_red
= (destpix
& 0x0000F800) >> 8;
1553 dst_green
= (destpix
& 0x000007e0) >> 3;
1554 dst_blue
= (destpix
& 0x0000001f) << 3;
1556 dst_red
+= do_alpha(src_alpha
, src_red
- dst_red
);
1557 dst_green
+= do_alpha(src_alpha
, src_green
- dst_green
);
1558 dst_blue
+= do_alpha(src_alpha
, src_blue
- dst_blue
);
1561 destpix
= (((dst_red
<< 8) & 0xf800) | ((dst_green
<< 3) & 0x07e0) | ((dst_blue
>> 3) & 0x001f));
1571 else if (bm
->depth
== 15)
1575 UWORD
*xbuf
= bm
->addresses
[y
];
1578 for (x
=0; x
< bw
; x
++)
1582 LONG src_red
, src_green
, src_blue
, src_alpha
;
1583 LONG dst_red
, dst_green
, dst_blue
;
1585 srcpix
= *pixarray
++;
1587 src_red
= (srcpix
& 0x00FF0000) >> 16;
1588 src_green
= (srcpix
& 0x0000FF00) >> 8;
1589 src_blue
= (srcpix
& 0x000000FF);
1590 src_alpha
= (srcpix
& 0xFF000000) >> 24;
1592 src_red
= (srcpix
& 0x0000FF00) >> 8;
1593 src_green
= (srcpix
& 0x00FF0000) >> 16;
1594 src_blue
= (srcpix
& 0xFF000000) >> 24;
1595 src_alpha
= (srcpix
& 0x000000FF);
1598 * If alpha=0, do not change the destination pixel at all.
1599 * This saves us unnecessary reads and writes to VRAM.
1604 * Full opacity. Do not read the destination pixel, as
1605 * it's value does not matter anyway.
1607 if (src_alpha
== 0xff)
1610 dst_green
= src_green
;
1611 dst_blue
= src_blue
;
1616 * Alpha blending with source and destination pixels.
1622 dst_red
= (destpix
& 0x00007c00) >> 7;
1623 dst_green
= (destpix
& 0x000003e0) >> 2;
1624 dst_blue
= (destpix
& 0x0000001f) << 3;
1626 dst_red
+= do_alpha(src_alpha
, src_red
- dst_red
);
1627 dst_green
+= do_alpha(src_alpha
, src_green
- dst_green
);
1628 dst_blue
+= do_alpha(src_alpha
, src_blue
- dst_blue
);
1630 destpix
= (ULONG
)(((dst_red
<< 7) & 0x7c00) | ((dst_green
<< 2) & 0x03e0) | ((dst_blue
>> 3) & 0x001f));
1642 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
1646 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
1649 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
1654 VOID
METHOD(ATIOffBM
, Hidd_BitMap
, PutImage
)
1655 __attribute__((alias(METHOD_NAME_S(ATIOnBM
, Hidd_BitMap
, PutImage
))));
1657 VOID
METHOD(ATIOnBM
, Hidd_BitMap
, PutImage
)
1659 atiBitMap
*bm
= OOP_INST_DATA(cl
, o
);
1664 IPTR VideoData
= bm
->framebuffer
;
1666 /* Try to PutImage with 2D engine first */
1669 UBYTE
*src
= msg
->pixels
;
1670 ULONG x_add
= msg
->modulo
;
1671 UWORD height
= msg
->height
;
1672 UWORD bw
= msg
->width
;
1684 sd
->Card
.Busy
= TRUE
;
1686 RADEONWaitForFifo(sd
, 1);
1687 OUTREG(RADEON_DST_PITCH_OFFSET
, bm
->pitch_offset
);
1689 bm
->dp_gui_master_cntl_clip
= (bm
->dp_gui_master_cntl
1690 | RADEON_GMC_WR_MSK_DIS
1691 | RADEON_GMC_BRUSH_NONE
1692 | RADEON_DP_SRC_SOURCE_HOST_DATA
1693 | RADEON_GMC_DST_CLIPPING
1694 | RADEON_GMC_SRC_DATATYPE_COLOR
1695 | RADEON_ROP
[vHidd_GC_DrawMode_Copy
].rop
);
1697 RADEONWaitForFifo(sd
, 5);
1698 OUTREG(RADEON_DP_GUI_MASTER_CNTL
, bm
->dp_gui_master_cntl_clip
);
1700 OUTREG(RADEON_SC_TOP_LEFT
, (msg
->y
<< 16) | (UWORD
)msg
->x
);
1701 OUTREG(RADEON_SC_BOTTOM_RIGHT
, ((msg
->y
+msg
->height
) << 16) | (UWORD
)(msg
->x
+msg
->width
));
1703 OUTREG(RADEON_DST_X_Y
, ((msg
->x
) << 16) | (UWORD
)msg
->y
);
1704 OUTREG(RADEON_DST_WIDTH_HEIGHT
, (bw
<< 16) | (UWORD
)msg
->height
);
1706 switch (msg
->pixFmt
)
1708 case vHidd_StdPixFmt_Native32
:
1709 case vHidd_StdPixFmt_Native
:
1713 RADEONWaitForFifo(sd
, 1);
1714 OUTREG(RADEON_RBBM_GUICNTL
, RADEON_HOST_DATA_SWAP_32BIT
);
1718 ULONG
*line
= (ULONG
*)src
;
1719 ULONG width
= msg
->width
;
1725 RADEONWaitForFifo(sd
, width
);
1728 case 8: OUTREGN(RADEON_HOST_DATA0
, *line
++);
1729 case 7: OUTREGN(RADEON_HOST_DATA1
, *line
++);
1730 case 6: OUTREGN(RADEON_HOST_DATA2
, *line
++);
1731 case 5: OUTREGN(RADEON_HOST_DATA3
, *line
++);
1732 case 4: OUTREGN(RADEON_HOST_DATA4
, *line
++);
1733 case 3: OUTREGN(RADEON_HOST_DATA5
, *line
++);
1734 case 2: OUTREGN(RADEON_HOST_DATA6
, *line
++);
1735 case 1: OUTREGN(RADEON_HOST_DATA7
, *line
++);
1741 RADEONWaitForFifo(sd
, 8);
1743 OUTREGN(RADEON_HOST_DATA0
, *line
++);
1744 OUTREGN(RADEON_HOST_DATA1
, *line
++);
1745 OUTREGN(RADEON_HOST_DATA2
, *line
++);
1746 OUTREGN(RADEON_HOST_DATA3
, *line
++);
1747 OUTREGN(RADEON_HOST_DATA4
, *line
++);
1748 OUTREGN(RADEON_HOST_DATA5
, *line
++);
1749 OUTREGN(RADEON_HOST_DATA6
, *line
++);
1750 OUTREGN(RADEON_HOST_DATA7
, *line
++);
1759 RADEONWaitForFifo(sd
, 1);
1760 OUTREG(RADEON_RBBM_GUICNTL
, RADEON_HOST_DATA_SWAP_NONE
);
1764 else if (bm
->bpp
== 2)
1767 RADEONWaitForFifo(sd
, 1);
1768 OUTREG(RADEON_RBBM_GUICNTL
, RADEON_HOST_DATA_SWAP_HDW
);
1770 if (msg
->pixFmt
== vHidd_StdPixFmt_Native
)
1774 ULONG
*line
= (ULONG
*)src
;
1775 ULONG width
= bw
>> 1;
1779 RADEONWaitForFifo(sd
, 1);
1780 OUTREG(RADEON_HOST_DATA0
, *line
++);
1790 ULONG
*line
= (ULONG
*)src
;
1791 ULONG width
= bw
>> 1;
1795 ULONG tmp
= (line
[0] << 16) | (line
[1] & 0x0000ffff);
1796 RADEONWaitForFifo(sd
, 1);
1797 OUTREG(RADEON_HOST_DATA0
, tmp
);
1807 RADEONWaitForFifo(sd
, 1);
1808 OUTREG(RADEON_RBBM_GUICNTL
, RADEON_HOST_DATA_SWAP_NONE
);
1818 srcpf
= HIDD_Gfx_GetPixFmt(sd
->AtiObject
, msg
->pixFmt
);
1819 OOP_GetAttr(o
, aHidd_BitMap_PixFmt
, (APTR
)&dstpf
);
1824 RADEONWaitForFifo(sd
, 1);
1825 OUTREG(RADEON_RBBM_GUICNTL
, RADEON_HOST_DATA_SWAP_32BIT
);
1829 ULONG
*line
= (ULONG
*)sd
->cpuscratch
;
1833 HIDD_BM_ConvertPixels(o
, &_src
, srcpf
, msg
->modulo
, &line
, dstpf
, msg
->modulo
, msg
->width
, 1, NULL
);
1835 line
= (ULONG
*)sd
->cpuscratch
;
1841 RADEONWaitForFifo(sd
, width
);
1844 case 8: OUTREGN(RADEON_HOST_DATA0
, *line
++);
1845 case 7: OUTREGN(RADEON_HOST_DATA1
, *line
++);
1846 case 6: OUTREGN(RADEON_HOST_DATA2
, *line
++);
1847 case 5: OUTREGN(RADEON_HOST_DATA3
, *line
++);
1848 case 4: OUTREGN(RADEON_HOST_DATA4
, *line
++);
1849 case 3: OUTREGN(RADEON_HOST_DATA5
, *line
++);
1850 case 2: OUTREGN(RADEON_HOST_DATA6
, *line
++);
1851 case 1: OUTREGN(RADEON_HOST_DATA7
, *line
++);
1857 RADEONWaitForFifo(sd
, 8);
1859 OUTREGN(RADEON_HOST_DATA0
, *line
++);
1860 OUTREGN(RADEON_HOST_DATA1
, *line
++);
1861 OUTREGN(RADEON_HOST_DATA2
, *line
++);
1862 OUTREGN(RADEON_HOST_DATA3
, *line
++);
1863 OUTREGN(RADEON_HOST_DATA4
, *line
++);
1864 OUTREGN(RADEON_HOST_DATA5
, *line
++);
1865 OUTREGN(RADEON_HOST_DATA6
, *line
++);
1866 OUTREGN(RADEON_HOST_DATA7
, *line
++);
1875 RADEONWaitForFifo(sd
, 1);
1876 OUTREG(RADEON_RBBM_GUICNTL
, RADEON_HOST_DATA_SWAP_NONE
);
1880 else if (bm
->bpp
== 2)
1883 RADEONWaitForFifo(sd
, 1);
1884 OUTREG(RADEON_RBBM_GUICNTL
, RADEON_HOST_DATA_SWAP_HDW
);
1889 ULONG
*line
= (ULONG
*)sd
->cpuscratch
;
1893 HIDD_BM_ConvertPixels(o
, &_src
, srcpf
, msg
->modulo
, &line
, dstpf
, msg
->modulo
, msg
->width
, 1, NULL
);
1895 line
= (ULONG
*)sd
->cpuscratch
;
1901 RADEONWaitForFifo(sd
, width
>> 1);
1904 case 16: OUTREG(RADEON_HOST_DATA0
, *line
++);
1905 case 14: OUTREG(RADEON_HOST_DATA1
, *line
++);
1906 case 12: OUTREG(RADEON_HOST_DATA2
, *line
++);
1907 case 10: OUTREG(RADEON_HOST_DATA3
, *line
++);
1908 case 8: OUTREG(RADEON_HOST_DATA4
, *line
++);
1909 case 6: OUTREG(RADEON_HOST_DATA5
, *line
++);
1910 case 4: OUTREG(RADEON_HOST_DATA6
, *line
++);
1911 case 2: OUTREG(RADEON_HOST_DATA7
, *line
++);
1917 RADEONWaitForFifo(sd
, 8);
1919 OUTREG(RADEON_HOST_DATA0
, *line
++);
1920 OUTREG(RADEON_HOST_DATA1
, *line
++);
1921 OUTREG(RADEON_HOST_DATA2
, *line
++);
1922 OUTREG(RADEON_HOST_DATA3
, *line
++);
1923 OUTREG(RADEON_HOST_DATA4
, *line
++);
1924 OUTREG(RADEON_HOST_DATA5
, *line
++);
1925 OUTREG(RADEON_HOST_DATA6
, *line
++);
1926 OUTREG(RADEON_HOST_DATA7
, *line
++);
1936 RADEONWaitForFifo(sd
, 1);
1937 OUTREG(RADEON_RBBM_GUICNTL
, RADEON_HOST_DATA_SWAP_NONE
);
1951 VideoData
+= (IPTR
)sd
->Card
.FrameBuffer
;
1956 #warning TODO: NVSync(sd)
1957 RADEONWaitForIdleMMIO(sd
);
1964 case vHidd_StdPixFmt_Native
:
1969 struct pHidd_BitMap_CopyMemBox8 __m
= {
1970 sd
->mid_CopyMemBox8
,
1983 OOP_DoMethod(o
, (OOP_Msg
)m
);
1989 struct pHidd_BitMap_CopyMemBox16 __m
= {
1990 sd
->mid_CopyMemBox16
,
2003 OOP_DoMethod(o
, (OOP_Msg
)m
);
2009 struct pHidd_BitMap_CopyMemBox32 __m
= {
2010 sd
->mid_CopyMemBox32
,
2023 OOP_DoMethod(o
, (OOP_Msg
)m
);
2027 } /* switch(data->bytesperpix) */
2030 case vHidd_StdPixFmt_Native32
:
2035 struct pHidd_BitMap_PutMem32Image8 __m
= {
2036 sd
->mid_PutMem32Image8
,
2046 OOP_DoMethod(o
, (OOP_Msg
)m
);
2052 struct pHidd_BitMap_PutMem32Image16 __m
= {
2053 sd
->mid_PutMem32Image16
,
2063 OOP_DoMethod(o
, (OOP_Msg
)m
);
2069 struct pHidd_BitMap_CopyMemBox32 __m
= {
2070 sd
->mid_CopyMemBox32
,
2083 OOP_DoMethod(o
, (OOP_Msg
)m
);
2087 } /* switch(data->bytesperpix) */
2091 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
2093 } /* switch(msg->pixFmt) */
2099 VOID
METHOD(ATIOffBM
, Hidd_BitMap
, GetImage
)
2100 __attribute__((alias(METHOD_NAME_S(ATIOnBM
, Hidd_BitMap
, GetImage
))));
2102 VOID
METHOD(ATIOnBM
, Hidd_BitMap
, GetImage
)
2104 atiBitMap
*bm
= OOP_INST_DATA(cl
, o
);
2108 IPTR VideoData
= bm
->framebuffer
;
2112 VideoData
+= (IPTR
)sd
->Card
.FrameBuffer
;
2116 #warning TODO: NVSync(sd)
2117 RADEONWaitForIdleMMIO(sd
);
2124 case vHidd_StdPixFmt_Native
:
2129 struct pHidd_BitMap_CopyMemBox8 __m
= {
2130 sd
->mid_CopyMemBox8
,
2143 OOP_DoMethod(o
, (OOP_Msg
)m
);
2149 struct pHidd_BitMap_CopyMemBox16 __m
= {
2150 sd
->mid_CopyMemBox16
,
2163 OOP_DoMethod(o
, (OOP_Msg
)m
);
2169 struct pHidd_BitMap_CopyMemBox32 __m
= {
2170 sd
->mid_CopyMemBox32
,
2183 OOP_DoMethod(o
, (OOP_Msg
)m
);
2187 } /* switch(data->bytesperpix) */
2190 case vHidd_StdPixFmt_Native32
:
2195 struct pHidd_BitMap_GetMem32Image8 __m
= {
2196 sd
->mid_GetMem32Image8
,
2207 OOP_DoMethod(o
, (OOP_Msg
)m
);
2213 struct pHidd_BitMap_GetMem32Image16 __m
= {
2214 sd
->mid_GetMem32Image16
,
2225 OOP_DoMethod(o
, (OOP_Msg
)m
);
2231 struct pHidd_BitMap_CopyMemBox32 __m
= {
2232 sd
->mid_CopyMemBox32
,
2245 OOP_DoMethod(o
, (OOP_Msg
)m
);
2249 } /* switch(data->bytesperpix) */
2253 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
2256 } /* switch(msg->pixFmt) */
2262 VOID
METHOD(ATIOffBM
, Hidd_BitMap
, PutTemplate
)
2263 __attribute__((alias(METHOD_NAME_S(ATIOnBM
, Hidd_BitMap
, PutTemplate
))));
2265 VOID
METHOD(ATIOnBM
, Hidd_BitMap
, PutTemplate
)
2267 atiBitMap
*bm
= OOP_INST_DATA(cl
, o
);
2269 D(bug("[ATI] NO-ACCEL: BitMap::PutTemplate\n"));
2273 IPTR VideoData
= bm
->framebuffer
;
2277 VideoData
+= (IPTR
)sd
->Card
.FrameBuffer
;
2281 #warning TODO: NVSync(sd)
2282 RADEONWaitForIdleMMIO(sd
);
2292 struct pHidd_BitMap_PutMemTemplate8 __m
= {
2293 sd
->mid_PutMemTemplate8
,
2307 OOP_DoMethod(o
, (OOP_Msg
)m
);
2313 struct pHidd_BitMap_PutMemTemplate16 __m
= {
2314 sd
->mid_PutMemTemplate16
,
2328 OOP_DoMethod(o
, (OOP_Msg
)m
);
2334 struct pHidd_BitMap_PutMemTemplate32 __m
= {
2335 sd
->mid_PutMemTemplate32
,
2349 OOP_DoMethod(o
, (OOP_Msg
)m
);
2352 } /* switch(bm->bpp) */
2357 VOID
METHOD(ATIOffBM
, Hidd_BitMap
, PutPattern
)
2358 __attribute__((alias(METHOD_NAME_S(ATIOnBM
, Hidd_BitMap
, PutPattern
))));
2360 VOID
METHOD(ATIOnBM
, Hidd_BitMap
, PutPattern
)
2362 atiBitMap
*bm
= OOP_INST_DATA(cl
, o
);
2364 D(bug("[ATI] NO-ACCEL: BitMap::PutPattern\n"));
2368 IPTR VideoData
= bm
->framebuffer
;
2372 VideoData
+= (IPTR
)sd
->Card
.FrameBuffer
;
2376 #warning TODO: NVSync(sd)
2377 RADEONWaitForIdleMMIO(sd
);
2387 struct pHidd_BitMap_PutMemPattern8 __m
= {
2388 sd
->mid_PutMemPattern8
,
2408 OOP_DoMethod(o
, (OOP_Msg
)m
);
2414 struct pHidd_BitMap_PutMemPattern16 __m
= {
2415 sd
->mid_PutMemPattern16
,
2435 OOP_DoMethod(o
, (OOP_Msg
)m
);
2441 struct pHidd_BitMap_PutMemPattern32 __m
= {
2442 sd
->mid_PutMemPattern32
,
2462 OOP_DoMethod(o
, (OOP_Msg
)m
);
2465 } /* switch(bm->bpp) */