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 OOP_Object
*METHOD(ATIOffBM
, Root
, New
)
44 __attribute__((alias(METHOD_NAME_S(ATIOnBM
, Root
, New
))));
46 OOP_Object
*METHOD(ATIOnBM
, Root
, New
)
48 if (cl
== sd
->OnBMClass
)
49 EnterFunc(bug("[ATIBitMap] OnBitmap::New()\n"));
51 EnterFunc(bug("[ATIBitMap] OffBitmap::New()\n"));
53 o
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
56 atiBitMap
*bm
= OOP_INST_DATA(cl
, o
);
58 IPTR width
, height
, depth
;
64 InitSemaphore(&bm
->bmLock
);
66 D(bug("[ATIBitMap] Super called. o=%p\n", o
));
68 bm
->onbm
= (cl
== sd
->OnBMClass
);
70 OOP_GetAttr(o
, aHidd_BitMap_Width
, &width
);
71 OOP_GetAttr(o
, aHidd_BitMap_Height
, &height
);
72 OOP_GetAttr(o
, aHidd_BitMap_PixFmt
, (IPTR
*)&pf
);
73 OOP_GetAttr(pf
, aHidd_PixFmt_Depth
, &depth
);
74 fb
= GetTagData(aHidd_BitMap_FrameBuffer
, FALSE
, msg
->attrList
);
76 D(bug("[ATIBitmap] width=%d height=%d depth=%d\n", width
, height
, depth
));
78 if (width
== 0 || height
== 0 || depth
== 0)
80 bug("[ATIBitMap] size mismatch!\n");
103 bm
->pitch
= (width
* bytesPerPixel
+ 63) & ~63;
105 bm
->bpp
= bytesPerPixel
;
106 bm
->framebuffer
= AllocBitmapArea(sd
, bm
->width
, bm
->height
, bm
->bpp
, TRUE
);
111 bm
->addresses
= AllocVecPooled(sd
->memPool
, height
* sizeof(void*));
113 if (bm
->framebuffer
!= -1)
116 for (__tmp
=0; __tmp
< height
; __tmp
++)
117 bm
->addresses
[__tmp
] = (void*)(bm
->framebuffer
+ sd
->Card
.FrameBuffer
+ __tmp
*bm
->pitch
);
134 bm
->dp_gui_master_cntl
=
135 ((bm
->datatype
<< RADEON_GMC_DST_DATATYPE_SHIFT
)
136 |RADEON_GMC_CLR_CMP_CNTL_DIS
137 |RADEON_GMC_DST_PITCH_OFFSET_CNTL
);
139 bm
->pitch_offset
= ((bm
->framebuffer
>> 10) | (bm
->pitch
<< 16));
141 D(bug("[ATIBitMap] PITCH_OFFSET=%08x\n", bm
->pitch_offset
));
144 if (cl
== sd
->OnBMClass
)
146 if (fb
&& bm
->framebuffer
!= -1)
148 bm
->state
= (struct CardState
*)AllocPooled(sd
->memPool
,
149 sizeof(struct CardState
));
151 bzero((APTR
)(sd
->Card
.FrameBuffer
+ bm
->framebuffer
), 640*480*2);
157 InitMode(sd
, bm
->state
, 640, 480, 16, 25200, bm
->framebuffer
,
162 LoadState(sd
, bm
->state
);
163 //LoadState(sd, sd->poweron_state);
166 RADEONEngineReset(sd
);
167 RADEONEngineRestore(sd
);
174 else if (bm
->framebuffer
!= -1)
179 /* We should be able to get modeID from the bitmap */
180 OOP_GetAttr(o
, aHidd_BitMap_ModeID
, &modeid
);
182 D(bug("[ATIBitMap] BM_ModeID=%x\n", modeid
));
184 if (modeid
!= vHidd_ModeID_Invalid
)
187 IPTR hdisp
, vdisp
, hstart
, hend
, htotal
, vstart
, vend
, vtotal
;
189 /* Get Sync and PixelFormat properties */
190 struct pHidd_Gfx_GetMode __getmodemsg
= {
194 }, *getmodemsg
= &__getmodemsg
;
196 getmodemsg
->mID
= OOP_GetMethodID((STRPTR
)CLID_Hidd_Gfx
, moHidd_Gfx_GetMode
);
197 OOP_DoMethod(sd
->AtiObject
, (OOP_Msg
)getmodemsg
);
199 OOP_GetAttr(sync
, aHidd_Sync_PixelClock
, &pixel
);
200 OOP_GetAttr(sync
, aHidd_Sync_HDisp
, &hdisp
);
201 OOP_GetAttr(sync
, aHidd_Sync_VDisp
, &vdisp
);
202 OOP_GetAttr(sync
, aHidd_Sync_HSyncStart
, &hstart
);
203 OOP_GetAttr(sync
, aHidd_Sync_VSyncStart
, &vstart
);
204 OOP_GetAttr(sync
, aHidd_Sync_HSyncEnd
, &hend
);
205 OOP_GetAttr(sync
, aHidd_Sync_VSyncEnd
, &vend
);
206 OOP_GetAttr(sync
, aHidd_Sync_HTotal
, &htotal
);
207 OOP_GetAttr(sync
, aHidd_Sync_VTotal
, &vtotal
);
209 bm
->state
= (struct CardState
*)AllocPooled(sd
->memPool
,
210 sizeof(struct CardState
));
218 InitMode(sd
, bm
->state
, width
, height
, depth
, pixel
, bm
->framebuffer
,
220 hstart
, hend
, htotal
,
221 vstart
, vend
, vtotal
);
223 LoadState(sd
, bm
->state
);
226 RADEONEngineReset(sd
);
227 RADEONEngineRestore(sd
);
238 if (bm
->framebuffer
== -1)
241 bm
->framebuffer
= (IPTR
)AllocMem(bm
->pitch
* bm
->height
,
242 MEMF_PUBLIC
| MEMF_CLEAR
);
245 for (__tmp
=0; __tmp
< height
; __tmp
++)
246 bm
->addresses
[__tmp
] = (void*)(bm
->framebuffer
+ __tmp
*bm
->pitch
);
251 if ((bm
->framebuffer
!= 0xffffffff) && (bm
->framebuffer
!= 0))
257 OOP_MethodID disp_mid
= OOP_GetMethodID((STRPTR
)IID_Root
, moRoot_Dispose
);
258 OOP_CoerceMethod(cl
, o
, (OOP_Msg
) &disp_mid
);
265 VOID
METHOD(ATIOffBM
, Root
, Dispose
)
266 __attribute__((alias(METHOD_NAME_S(ATIOnBM
, Root
, Dispose
))));
268 VOID
METHOD(ATIOnBM
, Root
, Dispose
)
270 atiBitMap
*bm
= OOP_INST_DATA(cl
, o
);
274 // NVDmaKickoff(&sd->Card);
275 RADEONWaitForIdleMMIO(sd
);
279 FreeBitmapArea(sd
, bm
->framebuffer
, bm
->width
, bm
->height
, bm
->bpp
);
281 bm
->framebuffer
= -1;
285 FreeMem((APTR
)bm
->framebuffer
, bm
->pitch
* bm
->height
);
287 FreeVecPooled(sd
->memPool
, bm
->addresses
);
290 FreePooled(sd
->memPool
, bm
->state
, sizeof(struct CardState
));
297 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
301 VOID
METHOD(ATIOffBM
, Root
, Get
)
302 __attribute__((alias(METHOD_NAME_S(ATIOnBM
, Root
, Get
))));
304 VOID
METHOD(ATIOnBM
, Root
, Get
)
306 atiBitMap
*bm
= OOP_INST_DATA(cl
, o
);
309 if (IS_ATIBM_ATTR(msg
->attrID
, idx
))
313 case aoHidd_ATIBitMap_Drawable
:
315 *msg
->storage
= bm
->framebuffer
+ (IPTR
)sd
->Card
.FrameBuffer
;
317 *msg
->storage
= bm
->framebuffer
;
321 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
326 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
331 VOID
METHOD(ATIOffBM
, Hidd_BitMap
, Clear
)
332 __attribute__((alias(METHOD_NAME_S(ATIOnBM
, Hidd_BitMap
, Clear
))));
334 VOID
METHOD(ATIOnBM
, Hidd_BitMap
, Clear
)
336 atiBitMap
*bm
= OOP_INST_DATA(cl
, o
);
338 D(bug("[ATI] Clear(%p)\n",
346 sd
->Card
.Busy
= TRUE
;
349 RADEONWaitForFifo(sd
, 1);
350 OUTREG(RADEON_DST_PITCH_OFFSET
, bm
->pitch_offset
);
352 bm
->dp_gui_master_cntl_clip
= (bm
->dp_gui_master_cntl
353 | RADEON_GMC_BRUSH_SOLID_COLOR
354 | RADEON_GMC_SRC_DATATYPE_COLOR
355 | RADEON_ROP
[vHidd_GC_DrawMode_Copy
].pattern
);
357 RADEONWaitForFifo(sd
, 4);
359 OUTREG(RADEON_DP_GUI_MASTER_CNTL
, bm
->dp_gui_master_cntl_clip
);
360 OUTREG(RADEON_DP_BRUSH_FRGD_CLR
, GC_BG(msg
->gc
));
361 OUTREG(RADEON_DP_WRITE_MASK
, ~0);
362 OUTREG(RADEON_DP_CNTL
, (RADEON_DST_X_LEFT_TO_RIGHT
363 | RADEON_DST_Y_TOP_TO_BOTTOM
));
365 RADEONWaitForFifo(sd
, 2);
367 OUTREG(RADEON_DST_Y_X
, 0);
368 OUTREG(RADEON_DST_WIDTH_HEIGHT
, (bm
->width
<< 16) | (UWORD
)bm
->height
);
374 ULONG
*ptr
= (ULONG
*)bm
->framebuffer
;
376 int i
= (bm
->pitch
* bm
->height
) >> 2;
381 val
= GC_BG(msg
->gc
) << 16 | (GC_BG(msg
->gc
) & 0xffff);
385 val
= GC_BG(msg
->gc
) << 16 | (GC_BG(msg
->gc
) & 0xffff);
389 do { *ptr
++ = val
; } while(--i
);
395 VOID
METHOD(ATIOffBM
, Hidd_BitMap
, FillRect
)
396 __attribute__((alias(METHOD_NAME_S(ATIOnBM
, Hidd_BitMap
, FillRect
))));
398 VOID
METHOD(ATIOnBM
, Hidd_BitMap
, FillRect
)
400 OOP_Object
*gc
= msg
->gc
;
401 atiBitMap
*bm
= OOP_INST_DATA(cl
, o
);
403 D(bug("[ATI] FillRect(%p, %d:%d - %d:%d)\n",
404 bm
->framebuffer
, msg
->minX
, msg
->minY
, msg
->maxX
, msg
->maxY
));
411 sd
->Card
.Busy
= TRUE
;
414 RADEONWaitForFifo(sd
, 1);
415 OUTREG(RADEON_DST_PITCH_OFFSET
, bm
->pitch_offset
);
417 bm
->dp_gui_master_cntl_clip
= (bm
->dp_gui_master_cntl
418 | RADEON_GMC_BRUSH_SOLID_COLOR
419 | RADEON_GMC_SRC_DATATYPE_COLOR
420 | RADEON_ROP
[GC_DRMD(gc
)].pattern
);
422 RADEONWaitForFifo(sd
, 4);
424 OUTREG(RADEON_DP_GUI_MASTER_CNTL
, bm
->dp_gui_master_cntl_clip
);
425 OUTREG(RADEON_DP_BRUSH_FRGD_CLR
, GC_FG(gc
));
426 OUTREG(RADEON_DP_WRITE_MASK
, ~0);
427 OUTREG(RADEON_DP_CNTL
, (RADEON_DST_X_LEFT_TO_RIGHT
428 | RADEON_DST_Y_TOP_TO_BOTTOM
));
430 RADEONWaitForFifo(sd
, 2);
432 OUTREG(RADEON_DST_Y_X
, (msg
->minY
<< 16) | (UWORD
)msg
->minX
);
433 OUTREG(RADEON_DST_WIDTH_HEIGHT
, ((msg
->maxX
- msg
->minX
+ 1) << 16) | (UWORD
)(msg
->maxY
- msg
->minY
+ 1));
439 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
447 VOID
METHOD(ATIOffBM
, Hidd_BitMap
, DrawLine
)
448 __attribute__((alias(METHOD_NAME_S(ATIOnBM
, Hidd_BitMap
, DrawLine
))));
450 VOID
METHOD(ATIOnBM
, Hidd_BitMap
, DrawLine
)
452 OOP_Object
*gc
= msg
->gc
;
453 atiBitMap
*bm
= OOP_INST_DATA(cl
, o
);
455 D(bug("[ATI] DrawLine(%p, %d:%d - %d:%d) %08x\n",
456 bm
->framebuffer
, msg
->x1
, msg
->y1
, msg
->x2
, msg
->y2
,GC_FG(gc
)));
460 if ((GC_LINEPAT(gc
) =! (UWORD
)~0) || !bm
->fbgfx
)
462 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
467 sd
->Card
.Busy
= TRUE
;
470 RADEONWaitForFifo(sd
, 1);
471 OUTREG(RADEON_DST_PITCH_OFFSET
, bm
->pitch_offset
);
473 bm
->dp_gui_master_cntl_clip
= (bm
->dp_gui_master_cntl
474 | RADEON_GMC_BRUSH_SOLID_COLOR
475 | RADEON_GMC_SRC_DATATYPE_COLOR
476 | RADEON_ROP
[GC_DRMD(gc
)].pattern
);
478 if (sd
->Card
.Type
>= RV200
) {
479 RADEONWaitForFifo(sd
, 1);
480 OUTREG(RADEON_DST_LINE_PATCOUNT
,
481 0x55 << RADEON_BRES_CNTL_SHIFT
);
486 bm
->dp_gui_master_cntl_clip
|= RADEON_GMC_DST_CLIPPING
;
490 x2
= GC_CLIPX2(gc
) + 1;
491 y2
= GC_CLIPY2(gc
) + 1;
496 x1
|= RADEON_SC_SIGN_MASK_LO
;
501 x2
|= RADEON_SC_SIGN_MASK_LO
;
506 y1
|= RADEON_SC_SIGN_MASK_LO
;
511 y2
|= RADEON_SC_SIGN_MASK_LO
;
514 RADEONWaitForFifo(sd
, 5);
515 OUTREG(RADEON_DP_GUI_MASTER_CNTL
, bm
->dp_gui_master_cntl_clip
);
516 OUTREG(RADEON_SC_TOP_LEFT
, (y1
<< 16) | (UWORD
)x1
);
517 OUTREG(RADEON_SC_BOTTOM_RIGHT
, (y2
<< 16) | (UWORD
)x2
);
521 RADEONWaitForFifo(sd
, 3);
522 OUTREG(RADEON_DP_GUI_MASTER_CNTL
, bm
->dp_gui_master_cntl_clip
);
524 OUTREG(RADEON_DP_BRUSH_FRGD_CLR
, GC_FG(gc
));
525 OUTREG(RADEON_DP_WRITE_MASK
, ~0);
527 RADEONWaitForFifo(sd
, 2);
529 OUTREG(RADEON_DST_LINE_START
, (msg
->y1
<< 16) | (UWORD
)msg
->x1
);
530 OUTREG(RADEON_DST_LINE_END
, (msg
->y2
<< 16) | (UWORD
)msg
->x2
);
531 // OUTREG(RADEON_DST_LINE_START, (msg->y2 << 16) | msg->x2);
532 // OUTREG(RADEON_DST_LINE_END, ((msg->y2+1) << 16) | (msg->x2+1));
541 VOID
METHOD(ATIOffBM
, Hidd_BitMap
, DrawRect
)
542 __attribute__((alias(METHOD_NAME_S(ATIOnBM
, Hidd_BitMap
, DrawRect
))));
544 VOID
METHOD(ATIOnBM
, Hidd_BitMap
, DrawRect
)
546 OOP_Object
*gc
= msg
->gc
;
547 atiBitMap
*bm
= OOP_INST_DATA(cl
, o
);
550 D(bug("[ATI] DrawRect(%p, %d:%d - %d:%d)\n",
551 bm
->framebuffer
, msg
->minX
, msg
->minY
, msg
->maxX
, msg
->maxY
));
553 if (msg
->minX
== msg
->maxX
) addX
= 1; else addX
= 0;
554 if (msg
->minY
== msg
->maxY
) addY
= 1; else addY
= 0;
558 if ((GC_LINEPAT(gc
) =! (UWORD
)~0) || !bm
->fbgfx
)
560 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
565 sd
->Card
.Busy
= TRUE
;
568 RADEONWaitForFifo(sd
, 1);
569 OUTREG(RADEON_DST_PITCH_OFFSET
, bm
->pitch_offset
);
571 bm
->dp_gui_master_cntl_clip
= (bm
->dp_gui_master_cntl
572 | RADEON_GMC_BRUSH_SOLID_COLOR
573 | RADEON_GMC_SRC_DATATYPE_COLOR
574 | RADEON_ROP
[GC_DRMD(gc
)].pattern
);
576 if (sd
->Card
.Type
>= RV200
) {
577 RADEONWaitForFifo(sd
, 1);
578 OUTREG(RADEON_DST_LINE_PATCOUNT
,
579 0x55 << RADEON_BRES_CNTL_SHIFT
);
584 bm
->dp_gui_master_cntl_clip
|= RADEON_GMC_DST_CLIPPING
;
588 x2
= GC_CLIPX2(gc
) + 1;
589 y2
= GC_CLIPY2(gc
) + 1;
594 x1
|= RADEON_SC_SIGN_MASK_LO
;
599 x2
|= RADEON_SC_SIGN_MASK_LO
;
604 y1
|= RADEON_SC_SIGN_MASK_LO
;
609 y2
|= RADEON_SC_SIGN_MASK_LO
;
612 RADEONWaitForFifo(sd
, 5);
613 OUTREG(RADEON_DP_GUI_MASTER_CNTL
, bm
->dp_gui_master_cntl_clip
);
614 OUTREG(RADEON_SC_TOP_LEFT
, (y1
<< 16) | (UWORD
)x1
);
615 OUTREG(RADEON_SC_BOTTOM_RIGHT
, (y2
<< 16) | (UWORD
)x2
);
619 RADEONWaitForFifo(sd
, 3);
620 OUTREG(RADEON_DP_GUI_MASTER_CNTL
, bm
->dp_gui_master_cntl_clip
);
622 OUTREG(RADEON_DP_BRUSH_FRGD_CLR
, GC_FG(gc
));
623 OUTREG(RADEON_DP_WRITE_MASK
, ~0);
625 RADEONWaitForFifo(sd
, 8);
627 OUTREG(RADEON_DST_LINE_START
, (msg
->minY
<< 16) | (msg
->minX
& 0xffff));
628 OUTREG(RADEON_DST_LINE_END
, (msg
->minY
<< 16) | (msg
->maxX
& 0xffff));
630 OUTREG(RADEON_DST_LINE_START
, ((msg
->minY
+ addY
) << 16) | (msg
->maxX
& 0xffff));
631 OUTREG(RADEON_DST_LINE_END
, ((msg
->maxY
<< 16)) | (msg
->maxX
& 0xffff));
633 OUTREG(RADEON_DST_LINE_START
, ((msg
->maxY
<< 16)) | ((msg
->maxX
- addX
) & 0xffff));
634 OUTREG(RADEON_DST_LINE_END
, ((msg
->maxY
<< 16)) | ((msg
->minX
) & 0xffff));
636 OUTREG(RADEON_DST_LINE_START
, ((msg
->maxY
- addY
) << 16) | (msg
->minX
& 0xffff));
637 OUTREG(RADEON_DST_LINE_END
, ((msg
->minY
+ addY
) << 16) | (msg
->minX
& 0xffff));
646 VOID
METHOD(ATIOffBM
, Hidd_BitMap
, DrawPolygon
)
647 __attribute__((alias(METHOD_NAME_S(ATIOnBM
, Hidd_BitMap
, DrawPolygon
))));
649 VOID
METHOD(ATIOnBM
, Hidd_BitMap
, DrawPolygon
)
651 OOP_Object
*gc
= msg
->gc
;
652 atiBitMap
*bm
= OOP_INST_DATA(cl
, o
);
655 D(bug("[ATI] DrawPolygon(%p)\n",
660 if ((GC_LINEPAT(gc
) =! (UWORD
)~0) || !bm
->fbgfx
)
662 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
667 sd
->Card
.Busy
= TRUE
;
670 RADEONWaitForFifo(sd
, 1);
671 OUTREG(RADEON_DST_PITCH_OFFSET
, bm
->pitch_offset
);
673 bm
->dp_gui_master_cntl_clip
= (bm
->dp_gui_master_cntl
674 | RADEON_GMC_BRUSH_SOLID_COLOR
675 | RADEON_GMC_SRC_DATATYPE_COLOR
676 | RADEON_ROP
[GC_DRMD(gc
)].pattern
);
678 if (sd
->Card
.Type
>= RV200
) {
679 RADEONWaitForFifo(sd
, 1);
680 OUTREG(RADEON_DST_LINE_PATCOUNT
,
681 0x55 << RADEON_BRES_CNTL_SHIFT
);
686 bm
->dp_gui_master_cntl_clip
|= RADEON_GMC_DST_CLIPPING
;
690 x2
= GC_CLIPX2(gc
) + 1;
691 y2
= GC_CLIPY2(gc
) + 1;
696 x1
|= RADEON_SC_SIGN_MASK_LO
;
701 x2
|= RADEON_SC_SIGN_MASK_LO
;
706 y1
|= RADEON_SC_SIGN_MASK_LO
;
711 y2
|= RADEON_SC_SIGN_MASK_LO
;
714 RADEONWaitForFifo(sd
, 5);
715 OUTREG(RADEON_DP_GUI_MASTER_CNTL
, bm
->dp_gui_master_cntl_clip
);
716 OUTREG(RADEON_SC_TOP_LEFT
, (y1
<< 16) | (UWORD
)x1
);
717 OUTREG(RADEON_SC_BOTTOM_RIGHT
, (y2
<< 16) | (UWORD
)x2
);
721 RADEONWaitForFifo(sd
, 3);
722 OUTREG(RADEON_DP_GUI_MASTER_CNTL
, bm
->dp_gui_master_cntl_clip
);
724 OUTREG(RADEON_DP_BRUSH_FRGD_CLR
, GC_FG(gc
));
725 OUTREG(RADEON_DP_WRITE_MASK
, ~0);
727 for (i
= 2; i
< (2 * msg
->n
); i
+=2)
729 RADEONWaitForFifo(sd
, 2);
730 OUTREG(RADEON_DST_LINE_START
, (msg
->coords
[i
-1] << 16) | (UWORD
)msg
->coords
[i
-2]);
731 OUTREG(RADEON_DST_LINE_END
, (msg
->coords
[i
+1] << 16) | (UWORD
)msg
->coords
[i
]);
740 VOID
METHOD(ATIOffBM
, Hidd_BitMap
, PutPixel
)
741 __attribute__((alias(METHOD_NAME_S(ATIOnBM
, Hidd_BitMap
, PutPixel
))));
743 VOID
METHOD(ATIOnBM
, Hidd_BitMap
, PutPixel
)
745 atiBitMap
*bm
= OOP_INST_DATA(cl
, o
);
746 void *ptr
= bm
->addresses
[msg
->y
];
755 /* TODO: NVSync(sd) */
756 RADEONWaitForIdleMMIO(sd
);
765 ((UBYTE
*)ptr
)[msg
->x
] = msg
->pixel
;
768 ((UWORD
*)ptr
)[msg
->x
] = msg
->pixel
;
771 ((ULONG
*)ptr
)[msg
->x
] = msg
->pixel
;
778 VOID
METHOD(ATIOffBM
, Hidd_BitMap
, DrawPixel
)
779 __attribute__((alias(METHOD_NAME_S(ATIOnBM
, Hidd_BitMap
, DrawPixel
))));
781 VOID
METHOD(ATIOnBM
, Hidd_BitMap
, DrawPixel
)
783 atiBitMap
*bm
= OOP_INST_DATA(cl
, o
);
784 void *ptr
= bm
->addresses
[msg
->y
];
785 OOP_Object
*gc
= msg
->gc
;
787 HIDDT_Pixel src
, dest
= 0, val
;
789 HIDDT_Pixel writeMask
;
801 /* TODO: NVSync(sd) */
802 RADEONWaitForIdleMMIO(sd
);
807 if (vHidd_GC_DrawMode_Copy
== mode
&& GC_COLMASK(gc
) == ~0)
816 dest
= ((UBYTE
*)ptr
)[msg
->x
];
819 dest
= ((UWORD
*)ptr
)[msg
->x
];
822 dest
= ((ULONG
*)ptr
)[msg
->x
];
826 writeMask
= ~GC_COLMASK(gc
) & dest
;
830 if(mode
& 1) val
= ( src
& dest
);
831 if(mode
& 2) val
= ( src
& ~dest
) | val
;
832 if(mode
& 4) val
= (~src
& dest
) | val
;
833 if(mode
& 8) val
= (~src
& ~dest
) | val
;
835 val
= (val
& (writeMask
| GC_COLMASK(gc
) )) | writeMask
;
841 ((UBYTE
*)ptr
)[msg
->x
] = val
;
844 ((UWORD
*)ptr
)[msg
->x
] = val
;
847 ((ULONG
*)ptr
)[msg
->x
] = val
;
854 VOID
METHOD(ATIOffBM
, Hidd_BitMap
, DrawEllipse
)
855 __attribute__((alias(METHOD_NAME_S(ATIOnBM
, Hidd_BitMap
, DrawEllipse
))));
857 VOID
METHOD(ATIOnBM
, Hidd_BitMap
, DrawEllipse
)
859 atiBitMap
*bm
= OOP_INST_DATA(cl
, o
);
860 OOP_Object
*gc
= msg
->gc
;
861 WORD x
= msg
->rx
, y
= 0; /* ellipse points */
864 HIDDT_Pixel writeMask
;
866 /* intermediate terms to speed up loop */
867 LONG t1
= msg
->rx
* msg
->rx
, t2
= t1
<< 1, t3
= t2
<< 1;
868 LONG t4
= msg
->ry
* msg
->ry
, t5
= t4
<< 1, t6
= t5
<< 1;
869 LONG t7
= msg
->rx
* t5
, t8
= t7
<< 1, t9
= 0L;
870 LONG d1
= t2
- t7
+ (t4
>> 1); /* error terms */
871 LONG d2
= (t1
>> 1) - t8
+ t5
;
873 APTR doclip
= GC_DOCLIP(gc
);
878 void _drawpixel(int x
, int y
)
880 void *ptr
= bm
->addresses
[y
];
881 HIDDT_Pixel val
, dest
= 0;
883 if (vHidd_GC_DrawMode_Copy
== mode
&& GC_COLMASK(gc
) == ~0)
892 dest
= ((UBYTE
*)ptr
)[x
];
895 dest
= ((UWORD
*)ptr
)[x
];
898 dest
= ((ULONG
*)ptr
)[x
];
902 writeMask
= ~GC_COLMASK(gc
) & dest
;
906 if(mode
& 1) val
= ( src
& dest
);
907 if(mode
& 2) val
= ( src
& ~dest
) | val
;
908 if(mode
& 4) val
= (~src
& dest
) | val
;
909 if(mode
& 8) val
= (~src
& ~dest
) | val
;
911 val
= (val
& (writeMask
| GC_COLMASK(gc
) )) | writeMask
;
917 ((UBYTE
*)ptr
)[x
] = val
;
920 ((UWORD
*)ptr
)[x
] = val
;
923 ((ULONG
*)ptr
)[x
] = val
;
930 UBYTE
*ptr
= (UBYTE
*)((IPTR
)bm
->framebuffer
);
933 ptr
+= (IPTR
)sd
->Card
.FrameBuffer
;
937 /* TODO: NVSync(sd) */
938 RADEONWaitForIdleMMIO(sd
);
943 while (d2
< 0) /* til slope = -1 */
945 /* draw 4 points using symmetry */
949 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
+ x
, msg
->y
+ y
))
950 _drawpixel(msg
->x
+ x
, msg
->y
+ y
);
952 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
+ x
, msg
->y
- y
))
953 _drawpixel(msg
->x
+ x
, msg
->y
- y
);
955 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
- x
, msg
->y
+ y
))
956 _drawpixel(msg
->x
- x
, msg
->y
+ y
);
958 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
- x
, msg
->y
- y
))
959 _drawpixel(msg
->x
- x
, msg
->y
- y
);
963 _drawpixel(msg
->x
+ x
, msg
->y
+ y
);
964 _drawpixel(msg
->x
+ x
, msg
->y
- y
);
965 _drawpixel(msg
->x
- x
, msg
->y
+ y
);
966 _drawpixel(msg
->x
- x
, msg
->y
- y
);
969 y
++; /* always move up here */
971 if (d1
< 0) /* move straight up */
976 else /* move up and left */
980 d1
= d1
+ t9
+ t2
- t8
;
981 d2
= d2
+ t9
+ t5
- t8
;
985 do /* rest of top right quadrant */
987 /* draw 4 points using symmetry */
990 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
+ x
, msg
->y
+ y
))
991 _drawpixel(msg
->x
+ x
, msg
->y
+ y
);
993 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
+ x
, msg
->y
- y
))
994 _drawpixel(msg
->x
+ x
, msg
->y
- y
);
996 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
- x
, msg
->y
+ y
))
997 _drawpixel(msg
->x
- x
, msg
->y
+ y
);
999 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
- x
, msg
->y
- y
))
1000 _drawpixel(msg
->x
- x
, msg
->y
- y
);
1004 _drawpixel(msg
->x
+ x
, msg
->y
+ y
);
1005 _drawpixel(msg
->x
+ x
, msg
->y
- y
);
1006 _drawpixel(msg
->x
- x
, msg
->y
+ y
);
1007 _drawpixel(msg
->x
- x
, msg
->y
- y
);
1010 x
--; /* always move left here */
1012 if (d2
< 0) /* move up and left */
1016 d2
= d2
+ t9
+ t5
- t8
;
1018 else /* move straight left */
1029 HIDDT_Pixel
METHOD(ATIOffBM
, Hidd_BitMap
, GetPixel
)
1030 __attribute__((alias(METHOD_NAME_S(ATIOnBM
, Hidd_BitMap
, GetPixel
))));
1032 HIDDT_Pixel
METHOD(ATIOnBM
, Hidd_BitMap
, GetPixel
)
1034 HIDDT_Pixel pixel
=0;
1035 atiBitMap
*bm
= OOP_INST_DATA(cl
, o
);
1039 void *ptr
= bm
->addresses
[msg
->y
];
1046 /* TODO: NVSync(sd) */
1047 RADEONWaitForIdleMMIO(sd
);
1055 pixel
= ((UBYTE
*)ptr
)[msg
->x
];
1058 pixel
= ((UWORD
*)ptr
)[msg
->x
];
1061 pixel
= ((ULONG
*)ptr
)[msg
->x
];
1067 /* Get pen number from colortab */
1072 void METHOD(ATIOffBM
, Hidd_BitMap
, BlitColorExpansion
)
1073 __attribute__((alias(METHOD_NAME_S(ATIOnBM
, Hidd_BitMap
, BlitColorExpansion
))));
1075 void METHOD(ATIOnBM
, Hidd_BitMap
, BlitColorExpansion
)
1077 atiBitMap
*bm
= OOP_INST_DATA(cl
, o
);
1081 if ((OOP_OCLASS(msg
->srcBitMap
) == sd
->PlanarBMClass
) && bm
->fbgfx
)
1083 struct planarbm_data
*planar
= OOP_INST_DATA(OOP_OCLASS(msg
->srcBitMap
), msg
->srcBitMap
);
1086 ULONG skipleft
= msg
->srcX
- (msg
->srcX
& ~31);
1087 ULONG mask
= ~0 << bm
->depth
;
1089 if (bm
->depth
== 32)
1092 cemd
= GC_COLEXP(msg
->gc
);
1093 bg
= GC_BG(msg
->gc
) | mask
;
1094 fg
= GC_FG(msg
->gc
) | mask
;
1096 ULONG bw
= (msg
->width
+ 31 + skipleft
) & ~31;
1097 LONG x
= msg
->destX
, y
= msg
->destY
, w
= msg
->width
, h
= msg
->height
;
1102 sd
->Card
.Busy
= TRUE
;
1104 RADEONWaitForFifo(sd
, 1);
1105 OUTREG(RADEON_DST_PITCH_OFFSET
, bm
->pitch_offset
);
1107 bm
->dp_gui_master_cntl_clip
= (bm
->dp_gui_master_cntl
1108 | RADEON_GMC_WR_MSK_DIS
1109 | RADEON_GMC_BRUSH_NONE
1110 | RADEON_DP_SRC_SOURCE_HOST_DATA
1111 | RADEON_GMC_DST_CLIPPING
1112 | RADEON_GMC_BYTE_MSB_TO_LSB
1113 | RADEON_ROP
[GC_DRMD(msg
->gc
)].rop
);
1115 if (cemd
& vHidd_GC_ColExp_Transparent
)
1117 bm
->dp_gui_master_cntl_clip
|= RADEON_GMC_SRC_DATATYPE_MONO_FG_LA
;
1119 RADEONWaitForFifo(sd
, 6);
1120 OUTREG(RADEON_DP_GUI_MASTER_CNTL
, bm
->dp_gui_master_cntl_clip
);
1121 OUTREG(RADEON_DP_SRC_FRGD_CLR
, fg
);
1125 bm
->dp_gui_master_cntl_clip
|= RADEON_GMC_SRC_DATATYPE_MONO_FG_BG
;
1127 RADEONWaitForFifo(sd
, 7);
1128 OUTREG(RADEON_DP_GUI_MASTER_CNTL
, bm
->dp_gui_master_cntl_clip
);
1129 OUTREG(RADEON_DP_SRC_FRGD_CLR
, fg
);
1130 OUTREG(RADEON_DP_SRC_BKGD_CLR
, bg
);
1133 OUTREG(RADEON_SC_TOP_LEFT
, (y
<< 16) | (UWORD
)x
);
1134 OUTREG(RADEON_SC_BOTTOM_RIGHT
, ((y
+h
) << 16) | (UWORD
)(x
+w
));
1136 OUTREG(RADEON_DST_X_Y
, ((x
- skipleft
) << 16) | (UWORD
)y
);
1137 OUTREG(RADEON_DST_WIDTH_HEIGHT
, (bw
<< 16) | (UWORD
)h
);
1139 ULONG
*ptr
= (ULONG
*)planar
->planes
[0];
1140 ptr
+= ((msg
->srcY
* planar
->bytesperrow
) >> 2) + (msg
->srcX
>> 5);
1143 RADEONWaitForFifo(sd
, 1);
1144 OUTREG(RADEON_RBBM_GUICNTL
, RADEON_HOST_DATA_SWAP_32BIT
);
1151 for (i
=0; i
< bw
>> 5; i
++)
1153 RADEONWaitForFifo(sd
, 1);
1154 OUTREG(RADEON_HOST_DATA0
, ptr
[i
]);
1157 ptr
+= planar
->bytesperrow
>> 2;
1161 RADEONWaitForFifo(sd
, 1);
1162 OUTREG(RADEON_RBBM_GUICNTL
, RADEON_HOST_DATA_SWAP_NONE
);
1169 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
1175 ULONG
METHOD(ATIOffBM
, Hidd_BitMap
, BytesPerLine
)
1176 __attribute__((alias(METHOD_NAME_S(ATIOnBM
, Hidd_BitMap
, BytesPerLine
))));
1178 ULONG
METHOD(ATIOnBM
, Hidd_BitMap
, BytesPerLine
)
1180 atiBitMap
*bm
= OOP_INST_DATA(cl
, o
);
1182 return (bm
->bpp
* msg
->width
+ 255) & ~255;
1186 BOOL
METHOD(ATIOffBM
, Hidd_BitMap
, ObtainDirectAccess
)
1187 __attribute__((alias(METHOD_NAME_S(ATIOnBM
, Hidd_BitMap
, ObtainDirectAccess
))));
1189 BOOL
METHOD(ATIOnBM
, Hidd_BitMap
, ObtainDirectAccess
)
1191 atiBitMap
*bm
= OOP_INST_DATA(cl
, o
);
1194 IPTR VideoData
= bm
->framebuffer
;
1198 VideoData
+= (IPTR
)sd
->Card
.FrameBuffer
;
1202 /* TODO: NVSync(sd) */
1203 RADEONWaitForIdleMMIO(sd
);
1208 *msg
->addressReturn
= (UBYTE
*)VideoData
;
1209 *msg
->widthReturn
= bm
->pitch
/ bm
->bpp
;
1210 *msg
->heightReturn
= bm
->height
;
1211 *msg
->bankSizeReturn
= *msg
->memSizeReturn
= bm
->pitch
* bm
->height
;
1216 VOID
METHOD(ATIOffBM
, Hidd_BitMap
, ReleaseDirectAccess
)
1217 __attribute__((alias(METHOD_NAME_S(ATIOnBM
, Hidd_BitMap
, ReleaseDirectAccess
))));
1219 VOID
METHOD(ATIOnBM
, Hidd_BitMap
, ReleaseDirectAccess
)
1221 atiBitMap
*bm
= OOP_INST_DATA(cl
, o
);
1228 * Unaccelerated methods
1231 VOID
METHOD(ATIOffBM
, Hidd_BitMap
, PutImageLUT
)
1232 __attribute__((alias(METHOD_NAME_S(ATIOnBM
, Hidd_BitMap
, PutImageLUT
))));
1234 VOID
METHOD(ATIOnBM
, Hidd_BitMap
, PutImageLUT
)
1236 atiBitMap
*bm
= OOP_INST_DATA(cl
, o
);
1243 UBYTE
*src
= msg
->pixels
;
1244 ULONG x_add
= msg
->modulo
;
1245 UWORD height
= msg
->height
;
1246 UWORD bw
= msg
->width
;
1247 HIDDT_Pixel
*colmap
= msg
->pixlut
->pixels
;
1255 sd
->Card
.Busy
= TRUE
;
1257 RADEONWaitForFifo(sd
, 1);
1258 OUTREG(RADEON_DST_PITCH_OFFSET
, bm
->pitch_offset
);
1260 bm
->dp_gui_master_cntl_clip
= (bm
->dp_gui_master_cntl
1261 | RADEON_GMC_WR_MSK_DIS
1262 | RADEON_GMC_BRUSH_NONE
1263 | RADEON_DP_SRC_SOURCE_HOST_DATA
1264 | RADEON_GMC_DST_CLIPPING
1265 | RADEON_GMC_SRC_DATATYPE_COLOR
1266 | RADEON_ROP
[vHidd_GC_DrawMode_Copy
].rop
);
1268 RADEONWaitForFifo(sd
, 5);
1269 OUTREG(RADEON_DP_GUI_MASTER_CNTL
, bm
->dp_gui_master_cntl_clip
);
1271 OUTREG(RADEON_SC_TOP_LEFT
, (msg
->y
<< 16) | (UWORD
)msg
->x
);
1272 OUTREG(RADEON_SC_BOTTOM_RIGHT
, ((msg
->y
+msg
->height
) << 16) | (UWORD
)(msg
->x
+msg
->width
));
1274 OUTREG(RADEON_DST_X_Y
, ((msg
->x
) << 16) | (UWORD
)msg
->y
);
1275 OUTREG(RADEON_DST_WIDTH_HEIGHT
, (bw
<< 16) | (UWORD
)msg
->height
);
1280 RADEONWaitForFifo(sd
, 1);
1281 OUTREG(RADEON_RBBM_GUICNTL
, RADEON_HOST_DATA_SWAP_32BIT
);
1285 UBYTE
*line
= (UBYTE
*)src
;
1286 ULONG width
= msg
->width
;
1292 RADEONWaitForFifo(sd
, width
);
1295 case 8: OUTREGN(RADEON_HOST_DATA0
, colmap
[*line
++]);
1296 case 7: OUTREGN(RADEON_HOST_DATA1
, colmap
[*line
++]);
1297 case 6: OUTREGN(RADEON_HOST_DATA2
, colmap
[*line
++]);
1298 case 5: OUTREGN(RADEON_HOST_DATA3
, colmap
[*line
++]);
1299 case 4: OUTREGN(RADEON_HOST_DATA4
, colmap
[*line
++]);
1300 case 3: OUTREGN(RADEON_HOST_DATA5
, colmap
[*line
++]);
1301 case 2: OUTREGN(RADEON_HOST_DATA6
, colmap
[*line
++]);
1302 case 1: OUTREGN(RADEON_HOST_DATA7
, colmap
[*line
++]);
1308 RADEONWaitForFifo(sd
, 8);
1310 OUTREGN(RADEON_HOST_DATA0
, colmap
[*line
++]);
1311 OUTREGN(RADEON_HOST_DATA1
, colmap
[*line
++]);
1312 OUTREGN(RADEON_HOST_DATA2
, colmap
[*line
++]);
1313 OUTREGN(RADEON_HOST_DATA3
, colmap
[*line
++]);
1314 OUTREGN(RADEON_HOST_DATA4
, colmap
[*line
++]);
1315 OUTREGN(RADEON_HOST_DATA5
, colmap
[*line
++]);
1316 OUTREGN(RADEON_HOST_DATA6
, colmap
[*line
++]);
1317 OUTREGN(RADEON_HOST_DATA7
, colmap
[*line
++]);
1326 else if (bm
->bpp
== 2)
1329 RADEONWaitForFifo(sd
, 1);
1330 OUTREG(RADEON_RBBM_GUICNTL
, RADEON_HOST_DATA_SWAP_HDW
);
1334 UBYTE
*line
= (UBYTE
*)src
;
1335 ULONG width
= bw
>> 1;
1339 ULONG tmp
= (colmap
[line
[0]] << 16) | (colmap
[line
[1]] & 0x0000ffff);
1340 RADEONWaitForFifo(sd
, 1);
1341 OUTREG(RADEON_HOST_DATA0
, tmp
);
1351 RADEONWaitForFifo(sd
, 1);
1352 OUTREG(RADEON_RBBM_GUICNTL
, RADEON_HOST_DATA_SWAP_NONE
);
1358 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
1363 static inline int do_alpha(int a
, int v
)
1366 return ((tmp
<< 8) + tmp
+ 32768) >> 16;
1369 VOID
METHOD(ATIOffBM
, Hidd_BitMap
, PutAlphaImage
)
1370 __attribute__((alias(METHOD_NAME_S(ATIOnBM
, Hidd_BitMap
, PutAlphaImage
))));
1372 VOID
METHOD(ATIOnBM
, Hidd_BitMap
, PutAlphaImage
)
1374 atiBitMap
*bm
= OOP_INST_DATA(cl
, o
);
1378 /* Try to PutAlphaImage with 2D engine first */
1381 ULONG x_add
= (msg
->modulo
- msg
->width
* 4) >> 2;
1382 UWORD height
= msg
->height
;
1383 UWORD bw
= msg
->width
;
1384 ULONG
*pixarray
= (ULONG
*)msg
->pixels
;
1388 D(bug("ATI: PutAlphaImage(%d, %d, %d:%d)\n", msg
->x
, msg
->y
, msg
->width
, msg
->height
));
1390 /* We're not going to use the 2D engine now. Therefore, flush the chip */
1394 RADEONWaitForIdleMMIO(sd
);
1399 * Treat each depth case separately
1405 ULONG
*xbuf
= bm
->addresses
[y
];
1408 for (x
=0; x
< bw
; x
++)
1412 LONG src_red
, src_green
, src_blue
, src_alpha
;
1413 LONG dst_red
, dst_green
, dst_blue
;
1415 /* Read RGBA pixel from input array */
1416 srcpix
= *pixarray
++;
1418 src_red
= (srcpix
& 0x00FF0000) >> 16;
1419 src_green
= (srcpix
& 0x0000FF00) >> 8;
1420 src_blue
= (srcpix
& 0x000000FF);
1421 src_alpha
= (srcpix
& 0xFF000000) >> 24;
1423 src_red
= (srcpix
& 0x0000FF00) >> 8;
1424 src_green
= (srcpix
& 0x00FF0000) >> 16;
1425 src_blue
= (srcpix
& 0xFF000000) >> 24;
1426 src_alpha
= (srcpix
& 0x000000FF);
1430 * If alpha=0, do not change the destination pixel at all.
1431 * This saves us unnecessary reads and writes to VRAM.
1436 * Full opacity. Do not read the destination pixel, as
1437 * it's value does not matter anyway.
1439 if (src_alpha
== 0xff)
1442 dst_green
= src_green
;
1443 dst_blue
= src_blue
;
1448 * Alpha blending with source and destination pixels.
1453 // #if AROS_BIG_ENDIAN
1454 // dst_red = (destpix & 0x0000FF00) >> 8;
1455 // dst_green = (destpix & 0x00FF0000) >> 16;
1456 // dst_blue = (destpix & 0xFF000000) >> 24;
1458 dst_red
= (destpix
& 0x00FF0000) >> 16;
1459 dst_green
= (destpix
& 0x0000FF00) >> 8;
1460 dst_blue
= (destpix
& 0x000000FF);
1463 dst_red
+= do_alpha(src_alpha
, src_red
- dst_red
);
1464 dst_green
+= do_alpha(src_alpha
, src_green
- dst_green
);
1465 dst_blue
+= do_alpha(src_alpha
, src_blue
- dst_blue
);
1469 // #if AROS_BIG_ENDIAN
1470 // destpix = (dst_blue << 24) + (dst_green << 16) + (dst_red << 8);
1472 destpix
= (dst_red
<< 16) + (dst_green
<< 8) + (dst_blue
);
1475 /* Store the new pixel */
1485 else if (bm
->bpp
== 2)
1487 if (bm
->depth
== 16)
1491 UWORD
*xbuf
= bm
->addresses
[y
];
1494 for (x
=0; x
< bw
; x
++)
1498 LONG src_red
, src_green
, src_blue
, src_alpha
;
1499 LONG dst_red
, dst_green
, dst_blue
;
1501 srcpix
= *pixarray
++;
1503 src_red
= (srcpix
& 0x00FF0000) >> 16;
1504 src_green
= (srcpix
& 0x0000FF00) >> 8;
1505 src_blue
= (srcpix
& 0x000000FF);
1506 src_alpha
= (srcpix
& 0xFF000000) >> 24;
1508 src_red
= (srcpix
& 0x0000FF00) >> 8;
1509 src_green
= (srcpix
& 0x00FF0000) >> 16;
1510 src_blue
= (srcpix
& 0xFF000000) >> 24;
1511 src_alpha
= (srcpix
& 0x000000FF);
1515 * If alpha=0, do not change the destination pixel at all.
1516 * This saves us unnecessary reads and writes to VRAM.
1521 * Full opacity. Do not read the destination pixel, as
1522 * it's value does not matter anyway.
1524 if (src_alpha
== 0xff)
1527 dst_green
= src_green
;
1528 dst_blue
= src_blue
;
1533 * Alpha blending with source and destination pixels.
1539 dst_red
= (destpix
& 0x0000F800) >> 8;
1540 dst_green
= (destpix
& 0x000007e0) >> 3;
1541 dst_blue
= (destpix
& 0x0000001f) << 3;
1543 dst_red
+= do_alpha(src_alpha
, src_red
- dst_red
);
1544 dst_green
+= do_alpha(src_alpha
, src_green
- dst_green
);
1545 dst_blue
+= do_alpha(src_alpha
, src_blue
- dst_blue
);
1548 destpix
= (((dst_red
<< 8) & 0xf800) | ((dst_green
<< 3) & 0x07e0) | ((dst_blue
>> 3) & 0x001f));
1558 else if (bm
->depth
== 15)
1562 UWORD
*xbuf
= bm
->addresses
[y
];
1565 for (x
=0; x
< bw
; x
++)
1569 LONG src_red
, src_green
, src_blue
, src_alpha
;
1570 LONG dst_red
, dst_green
, dst_blue
;
1572 srcpix
= *pixarray
++;
1574 src_red
= (srcpix
& 0x00FF0000) >> 16;
1575 src_green
= (srcpix
& 0x0000FF00) >> 8;
1576 src_blue
= (srcpix
& 0x000000FF);
1577 src_alpha
= (srcpix
& 0xFF000000) >> 24;
1579 src_red
= (srcpix
& 0x0000FF00) >> 8;
1580 src_green
= (srcpix
& 0x00FF0000) >> 16;
1581 src_blue
= (srcpix
& 0xFF000000) >> 24;
1582 src_alpha
= (srcpix
& 0x000000FF);
1585 * If alpha=0, do not change the destination pixel at all.
1586 * This saves us unnecessary reads and writes to VRAM.
1591 * Full opacity. Do not read the destination pixel, as
1592 * it's value does not matter anyway.
1594 if (src_alpha
== 0xff)
1597 dst_green
= src_green
;
1598 dst_blue
= src_blue
;
1603 * Alpha blending with source and destination pixels.
1609 dst_red
= (destpix
& 0x00007c00) >> 7;
1610 dst_green
= (destpix
& 0x000003e0) >> 2;
1611 dst_blue
= (destpix
& 0x0000001f) << 3;
1613 dst_red
+= do_alpha(src_alpha
, src_red
- dst_red
);
1614 dst_green
+= do_alpha(src_alpha
, src_green
- dst_green
);
1615 dst_blue
+= do_alpha(src_alpha
, src_blue
- dst_blue
);
1617 destpix
= (ULONG
)(((dst_red
<< 7) & 0x7c00) | ((dst_green
<< 2) & 0x03e0) | ((dst_blue
>> 3) & 0x001f));
1629 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
1633 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
1636 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
1641 VOID
METHOD(ATIOffBM
, Hidd_BitMap
, PutImage
)
1642 __attribute__((alias(METHOD_NAME_S(ATIOnBM
, Hidd_BitMap
, PutImage
))));
1644 VOID
METHOD(ATIOnBM
, Hidd_BitMap
, PutImage
)
1646 atiBitMap
*bm
= OOP_INST_DATA(cl
, o
);
1651 IPTR VideoData
= bm
->framebuffer
;
1653 /* Try to PutImage with 2D engine first */
1656 UBYTE
*src
= msg
->pixels
;
1657 ULONG x_add
= msg
->modulo
;
1658 UWORD height
= msg
->height
;
1659 UWORD bw
= msg
->width
;
1671 sd
->Card
.Busy
= TRUE
;
1673 RADEONWaitForFifo(sd
, 1);
1674 OUTREG(RADEON_DST_PITCH_OFFSET
, bm
->pitch_offset
);
1676 bm
->dp_gui_master_cntl_clip
= (bm
->dp_gui_master_cntl
1677 | RADEON_GMC_WR_MSK_DIS
1678 | RADEON_GMC_BRUSH_NONE
1679 | RADEON_DP_SRC_SOURCE_HOST_DATA
1680 | RADEON_GMC_DST_CLIPPING
1681 | RADEON_GMC_SRC_DATATYPE_COLOR
1682 | RADEON_ROP
[vHidd_GC_DrawMode_Copy
].rop
);
1684 RADEONWaitForFifo(sd
, 5);
1685 OUTREG(RADEON_DP_GUI_MASTER_CNTL
, bm
->dp_gui_master_cntl_clip
);
1687 OUTREG(RADEON_SC_TOP_LEFT
, (msg
->y
<< 16) | (UWORD
)msg
->x
);
1688 OUTREG(RADEON_SC_BOTTOM_RIGHT
, ((msg
->y
+msg
->height
) << 16) | (UWORD
)(msg
->x
+msg
->width
));
1690 OUTREG(RADEON_DST_X_Y
, ((msg
->x
) << 16) | (UWORD
)msg
->y
);
1691 OUTREG(RADEON_DST_WIDTH_HEIGHT
, (bw
<< 16) | (UWORD
)msg
->height
);
1693 switch (msg
->pixFmt
)
1695 case vHidd_StdPixFmt_Native32
:
1696 case vHidd_StdPixFmt_Native
:
1700 RADEONWaitForFifo(sd
, 1);
1701 OUTREG(RADEON_RBBM_GUICNTL
, RADEON_HOST_DATA_SWAP_32BIT
);
1705 ULONG
*line
= (ULONG
*)src
;
1706 ULONG width
= msg
->width
;
1712 RADEONWaitForFifo(sd
, width
);
1715 case 8: OUTREGN(RADEON_HOST_DATA0
, *line
++);
1716 case 7: OUTREGN(RADEON_HOST_DATA1
, *line
++);
1717 case 6: OUTREGN(RADEON_HOST_DATA2
, *line
++);
1718 case 5: OUTREGN(RADEON_HOST_DATA3
, *line
++);
1719 case 4: OUTREGN(RADEON_HOST_DATA4
, *line
++);
1720 case 3: OUTREGN(RADEON_HOST_DATA5
, *line
++);
1721 case 2: OUTREGN(RADEON_HOST_DATA6
, *line
++);
1722 case 1: OUTREGN(RADEON_HOST_DATA7
, *line
++);
1728 RADEONWaitForFifo(sd
, 8);
1730 OUTREGN(RADEON_HOST_DATA0
, *line
++);
1731 OUTREGN(RADEON_HOST_DATA1
, *line
++);
1732 OUTREGN(RADEON_HOST_DATA2
, *line
++);
1733 OUTREGN(RADEON_HOST_DATA3
, *line
++);
1734 OUTREGN(RADEON_HOST_DATA4
, *line
++);
1735 OUTREGN(RADEON_HOST_DATA5
, *line
++);
1736 OUTREGN(RADEON_HOST_DATA6
, *line
++);
1737 OUTREGN(RADEON_HOST_DATA7
, *line
++);
1746 RADEONWaitForFifo(sd
, 1);
1747 OUTREG(RADEON_RBBM_GUICNTL
, RADEON_HOST_DATA_SWAP_NONE
);
1751 else if (bm
->bpp
== 2)
1754 RADEONWaitForFifo(sd
, 1);
1755 OUTREG(RADEON_RBBM_GUICNTL
, RADEON_HOST_DATA_SWAP_HDW
);
1757 if (msg
->pixFmt
== vHidd_StdPixFmt_Native
)
1761 ULONG
*line
= (ULONG
*)src
;
1762 ULONG width
= bw
>> 1;
1766 RADEONWaitForFifo(sd
, 1);
1767 OUTREG(RADEON_HOST_DATA0
, *line
++);
1777 ULONG
*line
= (ULONG
*)src
;
1778 ULONG width
= bw
>> 1;
1782 ULONG tmp
= (line
[0] << 16) | (line
[1] & 0x0000ffff);
1783 RADEONWaitForFifo(sd
, 1);
1784 OUTREG(RADEON_HOST_DATA0
, tmp
);
1794 RADEONWaitForFifo(sd
, 1);
1795 OUTREG(RADEON_RBBM_GUICNTL
, RADEON_HOST_DATA_SWAP_NONE
);
1802 HIDDT_PixelFormat
*dstpf
, *srcpf
;
1804 srcpf
= (HIDDT_PixelFormat
*)HIDD_Gfx_GetPixFmt(sd
->AtiObject
, msg
->pixFmt
);
1805 OOP_GetAttr(o
, aHidd_BitMap_PixFmt
, (APTR
)&dstpf
);
1810 RADEONWaitForFifo(sd
, 1);
1811 OUTREG(RADEON_RBBM_GUICNTL
, RADEON_HOST_DATA_SWAP_32BIT
);
1815 ULONG
*line
= (ULONG
*)sd
->cpuscratch
;
1819 HIDD_BM_ConvertPixels(o
, &_src
, srcpf
, msg
->modulo
, (void **)&line
, dstpf
, msg
->modulo
, msg
->width
, 1, NULL
);
1821 line
= (ULONG
*)sd
->cpuscratch
;
1827 RADEONWaitForFifo(sd
, width
);
1830 case 8: OUTREGN(RADEON_HOST_DATA0
, *line
++);
1831 case 7: OUTREGN(RADEON_HOST_DATA1
, *line
++);
1832 case 6: OUTREGN(RADEON_HOST_DATA2
, *line
++);
1833 case 5: OUTREGN(RADEON_HOST_DATA3
, *line
++);
1834 case 4: OUTREGN(RADEON_HOST_DATA4
, *line
++);
1835 case 3: OUTREGN(RADEON_HOST_DATA5
, *line
++);
1836 case 2: OUTREGN(RADEON_HOST_DATA6
, *line
++);
1837 case 1: OUTREGN(RADEON_HOST_DATA7
, *line
++);
1843 RADEONWaitForFifo(sd
, 8);
1845 OUTREGN(RADEON_HOST_DATA0
, *line
++);
1846 OUTREGN(RADEON_HOST_DATA1
, *line
++);
1847 OUTREGN(RADEON_HOST_DATA2
, *line
++);
1848 OUTREGN(RADEON_HOST_DATA3
, *line
++);
1849 OUTREGN(RADEON_HOST_DATA4
, *line
++);
1850 OUTREGN(RADEON_HOST_DATA5
, *line
++);
1851 OUTREGN(RADEON_HOST_DATA6
, *line
++);
1852 OUTREGN(RADEON_HOST_DATA7
, *line
++);
1861 RADEONWaitForFifo(sd
, 1);
1862 OUTREG(RADEON_RBBM_GUICNTL
, RADEON_HOST_DATA_SWAP_NONE
);
1866 else if (bm
->bpp
== 2)
1869 RADEONWaitForFifo(sd
, 1);
1870 OUTREG(RADEON_RBBM_GUICNTL
, RADEON_HOST_DATA_SWAP_HDW
);
1875 ULONG
*line
= (ULONG
*)sd
->cpuscratch
;
1879 HIDD_BM_ConvertPixels(o
, &_src
, srcpf
, msg
->modulo
, (void **)&line
, dstpf
, msg
->modulo
, msg
->width
, 1, NULL
);
1881 line
= (ULONG
*)sd
->cpuscratch
;
1887 RADEONWaitForFifo(sd
, width
>> 1);
1890 case 16: OUTREG(RADEON_HOST_DATA0
, *line
++);
1891 case 14: OUTREG(RADEON_HOST_DATA1
, *line
++);
1892 case 12: OUTREG(RADEON_HOST_DATA2
, *line
++);
1893 case 10: OUTREG(RADEON_HOST_DATA3
, *line
++);
1894 case 8: OUTREG(RADEON_HOST_DATA4
, *line
++);
1895 case 6: OUTREG(RADEON_HOST_DATA5
, *line
++);
1896 case 4: OUTREG(RADEON_HOST_DATA6
, *line
++);
1897 case 2: OUTREG(RADEON_HOST_DATA7
, *line
++);
1903 RADEONWaitForFifo(sd
, 8);
1905 OUTREG(RADEON_HOST_DATA0
, *line
++);
1906 OUTREG(RADEON_HOST_DATA1
, *line
++);
1907 OUTREG(RADEON_HOST_DATA2
, *line
++);
1908 OUTREG(RADEON_HOST_DATA3
, *line
++);
1909 OUTREG(RADEON_HOST_DATA4
, *line
++);
1910 OUTREG(RADEON_HOST_DATA5
, *line
++);
1911 OUTREG(RADEON_HOST_DATA6
, *line
++);
1912 OUTREG(RADEON_HOST_DATA7
, *line
++);
1922 RADEONWaitForFifo(sd
, 1);
1923 OUTREG(RADEON_RBBM_GUICNTL
, RADEON_HOST_DATA_SWAP_NONE
);
1937 VideoData
+= (IPTR
)sd
->Card
.FrameBuffer
;
1942 /* TODO: NVSync(sd) */
1943 RADEONWaitForIdleMMIO(sd
);
1950 case vHidd_StdPixFmt_Native
:
1955 struct pHidd_BitMap_CopyMemBox8 __m
= {
1956 sd
->mid_CopyMemBox8
,
1969 OOP_DoMethod(o
, (OOP_Msg
)m
);
1975 struct pHidd_BitMap_CopyMemBox16 __m
= {
1976 sd
->mid_CopyMemBox16
,
1989 OOP_DoMethod(o
, (OOP_Msg
)m
);
1995 struct pHidd_BitMap_CopyMemBox32 __m
= {
1996 sd
->mid_CopyMemBox32
,
2009 OOP_DoMethod(o
, (OOP_Msg
)m
);
2013 } /* switch(data->bytesperpix) */
2016 case vHidd_StdPixFmt_Native32
:
2021 struct pHidd_BitMap_PutMem32Image8 __m
= {
2022 sd
->mid_PutMem32Image8
,
2032 OOP_DoMethod(o
, (OOP_Msg
)m
);
2038 struct pHidd_BitMap_PutMem32Image16 __m
= {
2039 sd
->mid_PutMem32Image16
,
2049 OOP_DoMethod(o
, (OOP_Msg
)m
);
2055 struct pHidd_BitMap_CopyMemBox32 __m
= {
2056 sd
->mid_CopyMemBox32
,
2069 OOP_DoMethod(o
, (OOP_Msg
)m
);
2073 } /* switch(data->bytesperpix) */
2077 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
2079 } /* switch(msg->pixFmt) */
2085 VOID
METHOD(ATIOffBM
, Hidd_BitMap
, GetImage
)
2086 __attribute__((alias(METHOD_NAME_S(ATIOnBM
, Hidd_BitMap
, GetImage
))));
2088 VOID
METHOD(ATIOnBM
, Hidd_BitMap
, GetImage
)
2090 atiBitMap
*bm
= OOP_INST_DATA(cl
, o
);
2094 IPTR VideoData
= bm
->framebuffer
;
2098 VideoData
+= (IPTR
)sd
->Card
.FrameBuffer
;
2102 /* TODO: NVSync(sd) */
2103 RADEONWaitForIdleMMIO(sd
);
2110 case vHidd_StdPixFmt_Native
:
2115 struct pHidd_BitMap_CopyMemBox8 __m
= {
2116 sd
->mid_CopyMemBox8
,
2129 OOP_DoMethod(o
, (OOP_Msg
)m
);
2135 struct pHidd_BitMap_CopyMemBox16 __m
= {
2136 sd
->mid_CopyMemBox16
,
2149 OOP_DoMethod(o
, (OOP_Msg
)m
);
2155 struct pHidd_BitMap_CopyMemBox32 __m
= {
2156 sd
->mid_CopyMemBox32
,
2169 OOP_DoMethod(o
, (OOP_Msg
)m
);
2173 } /* switch(data->bytesperpix) */
2176 case vHidd_StdPixFmt_Native32
:
2181 struct pHidd_BitMap_GetMem32Image8 __m
= {
2182 sd
->mid_GetMem32Image8
,
2193 OOP_DoMethod(o
, (OOP_Msg
)m
);
2199 struct pHidd_BitMap_GetMem32Image16 __m
= {
2200 sd
->mid_GetMem32Image16
,
2211 OOP_DoMethod(o
, (OOP_Msg
)m
);
2217 struct pHidd_BitMap_CopyMemBox32 __m
= {
2218 sd
->mid_CopyMemBox32
,
2231 OOP_DoMethod(o
, (OOP_Msg
)m
);
2235 } /* switch(data->bytesperpix) */
2239 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
2242 } /* switch(msg->pixFmt) */
2248 VOID
METHOD(ATIOffBM
, Hidd_BitMap
, PutTemplate
)
2249 __attribute__((alias(METHOD_NAME_S(ATIOnBM
, Hidd_BitMap
, PutTemplate
))));
2251 VOID
METHOD(ATIOnBM
, Hidd_BitMap
, PutTemplate
)
2253 atiBitMap
*bm
= OOP_INST_DATA(cl
, o
);
2255 D(bug("[ATI] NO-ACCEL: BitMap::PutTemplate\n"));
2259 IPTR VideoData
= bm
->framebuffer
;
2263 VideoData
+= (IPTR
)sd
->Card
.FrameBuffer
;
2267 /* TODO: NVSync(sd) */
2268 RADEONWaitForIdleMMIO(sd
);
2278 struct pHidd_BitMap_PutMemTemplate8 __m
= {
2279 sd
->mid_PutMemTemplate8
,
2293 OOP_DoMethod(o
, (OOP_Msg
)m
);
2299 struct pHidd_BitMap_PutMemTemplate16 __m
= {
2300 sd
->mid_PutMemTemplate16
,
2314 OOP_DoMethod(o
, (OOP_Msg
)m
);
2320 struct pHidd_BitMap_PutMemTemplate32 __m
= {
2321 sd
->mid_PutMemTemplate32
,
2335 OOP_DoMethod(o
, (OOP_Msg
)m
);
2338 } /* switch(bm->bpp) */
2343 VOID
METHOD(ATIOffBM
, Hidd_BitMap
, PutPattern
)
2344 __attribute__((alias(METHOD_NAME_S(ATIOnBM
, Hidd_BitMap
, PutPattern
))));
2346 VOID
METHOD(ATIOnBM
, Hidd_BitMap
, PutPattern
)
2348 atiBitMap
*bm
= OOP_INST_DATA(cl
, o
);
2350 D(bug("[ATI] NO-ACCEL: BitMap::PutPattern\n"));
2354 IPTR VideoData
= bm
->framebuffer
;
2358 VideoData
+= (IPTR
)sd
->Card
.FrameBuffer
;
2362 /* TODO: NVSync(sd) */
2363 RADEONWaitForIdleMMIO(sd
);
2373 struct pHidd_BitMap_PutMemPattern8 __m
= {
2374 sd
->mid_PutMemPattern8
,
2394 OOP_DoMethod(o
, (OOP_Msg
)m
);
2400 struct pHidd_BitMap_PutMemPattern16 __m
= {
2401 sd
->mid_PutMemPattern16
,
2421 OOP_DoMethod(o
, (OOP_Msg
)m
);
2427 struct pHidd_BitMap_PutMemPattern32 __m
= {
2428 sd
->mid_PutMemPattern32
,
2448 OOP_DoMethod(o
, (OOP_Msg
)m
);
2451 } /* switch(bm->bpp) */