Fix in CopyBox. Thanks, Georg :)
[cake.git] / arch / common / hidd.radeon / ati_bitmap.c
blobb5a1f8debeb860bd802a8053954ce0b44a693cd0
1 /*
2 Copyright © 2004, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include "ati.h"
7 #include "radeon.h"
8 #include "radeon_reg.h"
9 #include "radeon_bios.h"
10 #include "radeon_accel.h"
11 #include "radeon_macros.h"
13 #include <oop/oop.h>
14 #include <hidd/graphics.h>
15 #include <hidd/hidd.h>
17 #include <proto/oop.h>
18 #include <proto/utility.h>
20 #define DEBUG 0
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 {
44 OOP_MethodID mID;
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"));
54 else
55 EnterFunc(bug("[ATIBitMap] OffBitmap::New()\n"));
57 o = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
58 if (o)
60 atiBitMap *bm = OOP_INST_DATA(cl, o);
62 ULONG width, height, depth;
63 UBYTE bytesPerPixel;
64 ULONG fb;
66 OOP_Object *pf;
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");
87 if (depth == 24)
88 depth = 32;
90 if (depth <= 8)
91 bytesPerPixel = 1;
92 else if (depth <= 16)
93 bytesPerPixel = 2;
94 else
95 bytesPerPixel = 4;
97 if (fb)
99 width = 640;
100 height = 480;
101 bytesPerPixel = 4;
102 depth = 32;
105 bm->width = width;
106 bm->height = height;
107 bm->pitch = (width * bytesPerPixel + 63) & ~63;
108 bm->depth = depth;
109 bm->bpp = bytesPerPixel;
110 bm->framebuffer = AllocBitmapArea(sd, bm->width, bm->height, bm->bpp, TRUE);
111 bm->fbgfx = TRUE;
112 bm->state = NULL;
113 bm->BitMap = o;
114 bm->usecount = 0;
115 bm->addresses = AllocVecPooled(sd->memPool, height * sizeof(void*));
117 if (bm->framebuffer != -1)
119 int __tmp;
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;
125 switch(depth)
127 case 15:
128 bm->datatype = 3;
129 break;
131 case 16:
132 bm->datatype = 4;
133 break;
135 case 32:
136 bm->datatype = 6;
137 break;
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);
159 if (bm->state)
161 LOCK_HW
163 InitMode(sd, bm->state, 640, 480, 16, 25200, bm->framebuffer,
164 640, 480,
165 656, 752, 800,
166 490, 492, 525);
168 LoadState(sd, bm->state);
169 //LoadState(sd, sd->poweron_state);
170 DPMS(sd, sd->dpms);
172 RADEONEngineReset(sd);
173 RADEONEngineRestore(sd);
175 UNLOCK_HW
177 return o;
180 else if (bm->framebuffer != -1)
182 HIDDT_ModeID modeid;
183 OOP_Object *sync;
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)
192 ULONG pixel;
193 ULONG hdisp, vdisp, hstart, hend, htotal, vstart, vend, vtotal;
195 /* Get Sync and PixelFormat properties */
196 struct pHidd_Gfx_GetMode __getmodemsg = {
197 modeID: modeid,
198 syncPtr: &sync,
199 pixFmtPtr: &pf,
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));
218 pixel /= 1000;
220 if (bm->state)
222 LOCK_HW
224 InitMode(sd, bm->state, width, height, depth, pixel, bm->framebuffer,
225 hdisp, vdisp,
226 hstart, hend, htotal,
227 vstart, vend, vtotal);
229 LoadState(sd, bm->state);
230 DPMS(sd, sd->dpms);
232 RADEONEngineReset(sd);
233 RADEONEngineRestore(sd);
235 UNLOCK_HW
237 return o;
242 else
244 if (bm->framebuffer == -1)
246 int __tmp;
247 bm->framebuffer = (IPTR)AllocMem(bm->pitch * bm->height,
248 MEMF_PUBLIC | MEMF_CLEAR);
249 bm->fbgfx = FALSE;
251 for (__tmp=0; __tmp < height; __tmp++)
252 bm->addresses[__tmp] = (void*)(bm->framebuffer + __tmp*bm->pitch);
254 else
255 bm->fbgfx = TRUE;
257 if ((bm->framebuffer != 0xffffffff) && (bm->framebuffer != 0))
259 return o;
263 OOP_MethodID disp_mid = OOP_GetMethodID((STRPTR)IID_Root, moRoot_Dispose);
264 OOP_CoerceMethod(cl, o, (OOP_Msg) &disp_mid);
267 return NULL;
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);
278 LOCK_BITMAP
279 LOCK_HW
280 // NVDmaKickoff(&sd->Card);
281 RADEONWaitForIdleMMIO(sd);
283 if (bm->fbgfx)
285 FreeBitmapArea(sd, bm->framebuffer, bm->width, bm->height, bm->bpp);
287 bm->framebuffer = -1;
288 bm->fbgfx = 0;
290 else
291 FreeMem((APTR)bm->framebuffer, bm->pitch * bm->height);
293 FreeVecPooled(sd->memPool, bm->addresses);
295 if (bm->state)
296 FreePooled(sd->memPool, bm->state, sizeof(struct CardState));
298 bm->state = NULL;
300 UNLOCK_HW
301 UNLOCK_BITMAP
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);
313 ULONG idx;
315 if (IS_ATIBM_ATTR(msg->attrID, idx))
317 switch (idx)
319 case aoHidd_ATIBitMap_Drawable:
320 if (bm->fbgfx)
321 *msg->storage = bm->framebuffer + (IPTR)sd->Card.FrameBuffer;
322 else
323 *msg->storage = bm->framebuffer;
324 break;
326 default:
327 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
330 else
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",
345 bm->framebuffer));
347 LOCK_BITMAP
349 if (bm->fbgfx)
351 LOCK_HW
352 sd->Card.Busy = TRUE;
353 bm->usecount++;
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);
376 UNLOCK_HW
378 else
380 ULONG *ptr = (ULONG*)bm->framebuffer;
381 ULONG val = 0;
382 int i = (bm->pitch * bm->height) >> 2;
384 switch (bm->bpp)
386 case 2:
387 val = GC_BG(msg->gc) << 16 | (GC_BG(msg->gc) & 0xffff);
388 break;
390 default:
391 val = GC_BG(msg->gc) << 16 | (GC_BG(msg->gc) & 0xffff);
392 break;
395 do { *ptr++ = val; } while(--i);
398 UNLOCK_BITMAP
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));
416 LOCK_BITMAP
418 if (bm->fbgfx)
420 LOCK_HW
421 sd->Card.Busy = TRUE;
422 bm->usecount++;
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));
445 UNLOCK_HW
447 else
449 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
452 UNLOCK_BITMAP
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)));
468 LOCK_BITMAP
470 if ((GC_LINEPAT(gc) =! (UWORD)~0) || !bm->fbgfx)
472 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
474 else
476 LOCK_HW
477 sd->Card.Busy = TRUE;
478 bm->usecount++;
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);
494 if (GC_DOCLIP(gc))
496 bm->dp_gui_master_cntl_clip |= RADEON_GMC_DST_CLIPPING;
497 WORD x1,y1,x2,y2;
498 x1 = GC_CLIPX1(gc);
499 y1 = GC_CLIPY1(gc);
500 x2 = GC_CLIPX2(gc) + 1;
501 y2 = GC_CLIPY2(gc) + 1;
503 if (x1 < 0)
505 x1 = (-x1) & 0x3fff;
506 x1 |= RADEON_SC_SIGN_MASK_LO;
508 if (x2 < 0)
510 x2 = (-x2) & 0x3fff;
511 x2 |= RADEON_SC_SIGN_MASK_LO;
513 if (y1 < 0)
515 y1 = (-y1) & 0x3fff;
516 y1 |= RADEON_SC_SIGN_MASK_LO;
518 if (y2 < 0)
520 y2 = (-y2) & 0x3fff;
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);
529 else
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));
544 UNLOCK_HW
547 UNLOCK_BITMAP
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);
558 UWORD addX, addY;
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;
566 LOCK_BITMAP
568 if ((GC_LINEPAT(gc) =! (UWORD)~0) || !bm->fbgfx)
570 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
572 else
574 LOCK_HW
575 sd->Card.Busy = TRUE;
576 bm->usecount++;
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);
592 if (GC_DOCLIP(gc))
594 bm->dp_gui_master_cntl_clip |= RADEON_GMC_DST_CLIPPING;
595 UWORD x1,y1,x2,y2;
596 x1 = GC_CLIPX1(gc);
597 y1 = GC_CLIPY1(gc);
598 x2 = GC_CLIPX2(gc) + 1;
599 y2 = GC_CLIPY2(gc) + 1;
601 if (x1 < 0)
603 x1 = (-x1) & 0x3fff;
604 x1 |= RADEON_SC_SIGN_MASK_LO;
606 if (x2 < 0)
608 x2 = (-x2) & 0x3fff;
609 x2 |= RADEON_SC_SIGN_MASK_LO;
611 if (y1 < 0)
613 y1 = (-y1) & 0x3fff;
614 y1 |= RADEON_SC_SIGN_MASK_LO;
616 if (y2 < 0)
618 y2 = (-y2) & 0x3fff;
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);
627 else
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));
649 UNLOCK_HW
652 UNLOCK_BITMAP
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);
663 ULONG i;
665 D(bug("[ATI] DrawPolygon(%p)\n",
666 bm->framebuffer));
668 LOCK_BITMAP
670 if ((GC_LINEPAT(gc) =! (UWORD)~0) || !bm->fbgfx)
672 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
674 else
676 LOCK_HW
677 sd->Card.Busy = TRUE;
678 bm->usecount++;
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);
694 if (GC_DOCLIP(gc))
696 bm->dp_gui_master_cntl_clip |= RADEON_GMC_DST_CLIPPING;
697 UWORD x1,y1,x2,y2;
698 x1 = GC_CLIPX1(gc);
699 y1 = GC_CLIPY1(gc);
700 x2 = GC_CLIPX2(gc) + 1;
701 y2 = GC_CLIPY2(gc) + 1;
703 if (x1 < 0)
705 x1 = (-x1) & 0x3fff;
706 x1 |= RADEON_SC_SIGN_MASK_LO;
708 if (x2 < 0)
710 x2 = (-x2) & 0x3fff;
711 x2 |= RADEON_SC_SIGN_MASK_LO;
713 if (y1 < 0)
715 y1 = (-y1) & 0x3fff;
716 y1 |= RADEON_SC_SIGN_MASK_LO;
718 if (y2 < 0)
720 y2 = (-y2) & 0x3fff;
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);
729 else
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]);
744 UNLOCK_HW
747 UNLOCK_BITMAP
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];
758 LOCK_BITMAP
760 if (bm->fbgfx)
762 if (sd->Card.Busy)
764 LOCK_HW
765 #warning TODO: NVSync(sd)
766 RADEONWaitForIdleMMIO(sd);
767 UNLOCK_HW
772 switch (bm->bpp)
774 case 1:
775 ((UBYTE *)ptr)[msg->x] = msg->pixel;
776 break;
777 case 2:
778 ((UWORD *)ptr)[msg->x] = msg->pixel;
779 break;
780 case 4:
781 ((ULONG *)ptr)[msg->x] = msg->pixel;
782 break;
785 UNLOCK_BITMAP
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;
798 HIDDT_DrawMode mode;
799 HIDDT_Pixel writeMask;
801 src = GC_FG(gc);
802 mode = GC_DRMD(gc);
804 LOCK_BITMAP
806 if (bm->fbgfx)
808 if (sd->Card.Busy)
810 LOCK_HW
811 #warning TODO: NVSync(sd)
812 RADEONWaitForIdleMMIO(sd);
813 UNLOCK_HW
817 if (vHidd_GC_DrawMode_Copy == mode && GC_COLMASK(gc) == ~0)
819 val = src;
821 else
823 switch (bm->bpp)
825 case 1:
826 dest = ((UBYTE *)ptr)[msg->x];
827 break;
828 case 2:
829 dest = ((UWORD *)ptr)[msg->x];
830 break;
831 case 4:
832 dest = ((ULONG *)ptr)[msg->x];
833 break;
836 writeMask = ~GC_COLMASK(gc) & dest;
838 val = 0;
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;
848 switch (bm->bpp)
850 case 1:
851 ((UBYTE *)ptr)[msg->x] = val;
852 break;
853 case 2:
854 ((UWORD *)ptr)[msg->x] = val;
855 break;
856 case 4:
857 ((ULONG *)ptr)[msg->x] = val;
858 break;
861 UNLOCK_BITMAP
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 */
872 HIDDT_Pixel src;
873 HIDDT_DrawMode mode;
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);
885 src = GC_FG(gc);
886 mode = GC_DRMD(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)
895 val = src;
897 else
899 switch (bm->bpp)
901 case 1:
902 dest = ((UBYTE *)ptr)[x];
903 break;
904 case 2:
905 dest = ((UWORD *)ptr)[x];
906 break;
907 case 4:
908 dest = ((ULONG *)ptr)[x];
909 break;
912 writeMask = ~GC_COLMASK(gc) & dest;
914 val = 0;
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;
924 switch (bm->bpp)
926 case 1:
927 ((UBYTE *)ptr)[x] = val;
928 break;
929 case 2:
930 ((UWORD *)ptr)[x] = val;
931 break;
932 case 4:
933 ((ULONG *)ptr)[x] = val;
934 break;
938 LOCK_BITMAP
940 UBYTE *ptr = (UBYTE*)((IPTR)bm->framebuffer);
941 if (bm->fbgfx)
943 ptr += (IPTR)sd->Card.FrameBuffer;
944 if (sd->Card.Busy)
946 LOCK_HW
947 #warning TODO: NVSync(sd)
948 RADEONWaitForIdleMMIO(sd);
949 UNLOCK_HW
953 while (d2 < 0) /* til slope = -1 */
955 /* draw 4 points using symmetry */
957 if (doclip)
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);
971 else
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 */
980 t9 = t9 + t3;
981 if (d1 < 0) /* move straight up */
983 d1 = d1 + t9 + t2;
984 d2 = d2 + t9;
986 else /* move up and left */
988 x--;
989 t8 = t8 - t6;
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 */
998 if (doclip)
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);
1012 else
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 */
1021 t8 = t8 - t6;
1022 if (d2 < 0) /* move up and left */
1024 y++;
1025 t9 = t9 + t3;
1026 d2 = d2 + t9 + t5 - t8;
1028 else /* move straight left */
1030 d2 = d2 + t5 - t8;
1033 } while (x >= 0);
1036 UNLOCK_BITMAP
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);
1047 LOCK_BITMAP
1049 void *ptr = bm->addresses[msg->y];
1051 if (bm->fbgfx)
1053 if (sd->Card.Busy)
1055 LOCK_HW
1056 #warning TODO: NVSync(sd)
1057 RADEONWaitForIdleMMIO(sd);
1058 UNLOCK_HW
1062 switch (bm->bpp)
1064 case 1:
1065 pixel = ((UBYTE *)ptr)[msg->x];
1066 break;
1067 case 2:
1068 pixel = ((UWORD *)ptr)[msg->x];
1069 break;
1070 case 4:
1071 pixel = ((ULONG *)ptr)[msg->x];
1072 break;
1075 UNLOCK_BITMAP
1077 /* Get pen number from colortab */
1078 return pixel;
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);
1089 LOCK_BITMAP
1091 if ((OOP_OCLASS(msg->srcBitMap) == sd->PlanarBMClass) && bm->fbgfx)
1093 struct planarbm_data *planar = OOP_INST_DATA(OOP_OCLASS(msg->srcBitMap), msg->srcBitMap);
1094 HIDDT_Pixel bg, fg;
1095 ULONG cemd;
1096 ULONG skipleft = msg->srcX - (msg->srcX & ~31);
1097 ULONG mask = ~0 << bm->depth;
1099 if (bm->depth == 32)
1100 mask = 0xff000000;
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;
1109 LOCK_HW
1111 bm->usecount++;
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);
1133 else
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);
1152 #if AROS_BIG_ENDIAN
1153 RADEONWaitForFifo(sd, 1);
1154 OUTREG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_32BIT);
1155 #endif
1157 while(h--)
1159 int i;
1161 for (i=0; i < bw >> 5; i++)
1163 RADEONWaitForFifo(sd, 1);
1164 OUTREG(RADEON_HOST_DATA0, ptr[i]);
1167 ptr += planar->bytesperrow >> 2;
1170 #if AROS_BIG_ENDIAN
1171 RADEONWaitForFifo(sd, 1);
1172 OUTREG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_NONE);
1173 #endif
1175 UNLOCK_HW
1178 else
1179 OOP_DoSuperMethod(cl, o, msg);
1181 UNLOCK_BITMAP
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);
1202 LOCK_BITMAP
1204 IPTR VideoData = bm->framebuffer;
1206 if (bm->fbgfx)
1208 VideoData += (IPTR)sd->Card.FrameBuffer;
1209 if (sd->Card.Busy)
1211 LOCK_HW
1212 #warning TODO: NVSync(sd)
1213 RADEONWaitForIdleMMIO(sd);
1214 UNLOCK_HW
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;
1223 return TRUE;
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);
1233 UNLOCK_BITMAP
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);
1248 LOCK_BITMAP
1250 if (bm->fbgfx)
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;
1259 if (bm->bpp == 2)
1260 bw = (bw + 1) & ~1;
1262 LOCK_HW
1264 bm->usecount++;
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);
1287 if (bm->bpp == 4)
1289 #if AROS_BIG_ENDIAN
1290 RADEONWaitForFifo(sd, 1);
1291 OUTREG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_32BIT);
1292 #endif
1293 while (height--)
1295 UBYTE *line = (UBYTE*)src;
1296 ULONG width = msg->width;
1298 while(width)
1300 if (width <= 8)
1302 RADEONWaitForFifo(sd, width);
1303 switch (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++]);
1314 width = 0;
1316 else
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++]);
1329 width -= 8;
1333 src += x_add;
1336 else if (bm->bpp == 2)
1338 #if AROS_BIG_ENDIAN
1339 RADEONWaitForFifo(sd, 1);
1340 OUTREG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_HDW);
1341 #endif
1342 while (height--)
1344 UBYTE *line = (UBYTE*)src;
1345 ULONG width = bw >> 1;
1347 while(width--)
1349 ULONG tmp = (colmap[line[0]] << 16) | (colmap[line[1]] & 0x0000ffff);
1350 RADEONWaitForFifo(sd, 1);
1351 OUTREG(RADEON_HOST_DATA0, tmp);
1352 line+=2;
1355 src += x_add;
1360 #if AROS_BIG_ENDIAN
1361 RADEONWaitForFifo(sd, 1);
1362 OUTREG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_NONE);
1363 #endif
1365 UNLOCK_HW
1367 else
1368 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
1370 UNLOCK_BITMAP
1373 static inline int do_alpha(int a, int v)
1375 int tmp = a*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);
1385 BOOL done = FALSE;
1387 LOCK_BITMAP
1389 IPTR VideoData = bm->framebuffer;
1391 /* Try to PutAlphaImage with 2D engine first */
1392 if (bm->fbgfx)
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;
1398 ULONG y = msg->y;
1399 ULONG x;
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 */
1404 if (sd->Card.Busy)
1406 LOCK_HW
1407 RADEONWaitForIdleMMIO(sd);
1408 UNLOCK_HW
1412 * Treat each depth case separately
1414 if (bm->bpp == 4)
1416 while(height--)
1418 ULONG *xbuf = bm->addresses[y];
1419 xbuf += msg->x;
1421 for (x=0; x < bw; x++)
1423 ULONG destpix;
1424 ULONG srcpix;
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++;
1430 #if AROS_BIG_ENDIAN
1431 src_red = (srcpix & 0x00FF0000) >> 16;
1432 src_green = (srcpix & 0x0000FF00) >> 8;
1433 src_blue = (srcpix & 0x000000FF);
1434 src_alpha = (srcpix & 0xFF000000) >> 24;
1435 #else
1436 src_red = (srcpix & 0x0000FF00) >> 8;
1437 src_green = (srcpix & 0x00FF0000) >> 16;
1438 src_blue = (srcpix & 0xFF000000) >> 24;
1439 src_alpha = (srcpix & 0x000000FF);
1440 #endif
1443 * If alpha=0, do not change the destination pixel at all.
1444 * This saves us unnecessary reads and writes to VRAM.
1446 if (src_alpha != 0)
1449 * Full opacity. Do not read the destination pixel, as
1450 * it's value does not matter anyway.
1452 if (src_alpha == 0xff)
1454 dst_red = src_red;
1455 dst_green = src_green;
1456 dst_blue = src_blue;
1458 else
1461 * Alpha blending with source and destination pixels.
1462 * Get destination.
1464 destpix = xbuf[x];
1466 // #if AROS_BIG_ENDIAN
1467 // dst_red = (destpix & 0x0000FF00) >> 8;
1468 // dst_green = (destpix & 0x00FF0000) >> 16;
1469 // dst_blue = (destpix & 0xFF000000) >> 24;
1470 // #else
1471 dst_red = (destpix & 0x00FF0000) >> 16;
1472 dst_green = (destpix & 0x0000FF00) >> 8;
1473 dst_blue = (destpix & 0x000000FF);
1474 // #endif
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);
1484 // #else
1485 destpix = (dst_red << 16) + (dst_green << 8) + (dst_blue);
1486 // #endif
1488 /* Store the new pixel */
1489 xbuf[x] = destpix;
1493 y++;
1494 pixarray += x_add;
1497 /* 2bpp cases... */
1498 else if (bm->bpp == 2)
1500 if (bm->depth == 16)
1502 while(height--)
1504 UWORD *xbuf = bm->addresses[y];
1505 xbuf += msg->x;
1507 for (x=0; x < bw; x++)
1509 UWORD destpix;
1510 ULONG srcpix;
1511 LONG src_red, src_green, src_blue, src_alpha;
1512 LONG dst_red, dst_green, dst_blue;
1514 srcpix = *pixarray++;
1515 #if AROS_BIG_ENDIAN
1516 src_red = (srcpix & 0x00FF0000) >> 16;
1517 src_green = (srcpix & 0x0000FF00) >> 8;
1518 src_blue = (srcpix & 0x000000FF);
1519 src_alpha = (srcpix & 0xFF000000) >> 24;
1520 #else
1521 src_red = (srcpix & 0x0000FF00) >> 8;
1522 src_green = (srcpix & 0x00FF0000) >> 16;
1523 src_blue = (srcpix & 0xFF000000) >> 24;
1524 src_alpha = (srcpix & 0x000000FF);
1525 #endif
1528 * If alpha=0, do not change the destination pixel at all.
1529 * This saves us unnecessary reads and writes to VRAM.
1531 if (src_alpha != 0)
1534 * Full opacity. Do not read the destination pixel, as
1535 * it's value does not matter anyway.
1537 if (src_alpha == 0xff)
1539 dst_red = src_red;
1540 dst_green = src_green;
1541 dst_blue = src_blue;
1543 else
1546 * Alpha blending with source and destination pixels.
1547 * Get destination.
1550 destpix = xbuf[x];
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));
1563 xbuf[x] = destpix;
1567 y++;
1568 pixarray += x_add;
1571 else if (bm->depth == 15)
1573 while(height--)
1575 UWORD *xbuf = bm->addresses[y];
1576 xbuf += msg->x;
1578 for (x=0; x < bw; x++)
1580 UWORD destpix;
1581 ULONG srcpix;
1582 LONG src_red, src_green, src_blue, src_alpha;
1583 LONG dst_red, dst_green, dst_blue;
1585 srcpix = *pixarray++;
1586 #if AROS_BIG_ENDIAN
1587 src_red = (srcpix & 0x00FF0000) >> 16;
1588 src_green = (srcpix & 0x0000FF00) >> 8;
1589 src_blue = (srcpix & 0x000000FF);
1590 src_alpha = (srcpix & 0xFF000000) >> 24;
1591 #else
1592 src_red = (srcpix & 0x0000FF00) >> 8;
1593 src_green = (srcpix & 0x00FF0000) >> 16;
1594 src_blue = (srcpix & 0xFF000000) >> 24;
1595 src_alpha = (srcpix & 0x000000FF);
1596 #endif
1598 * If alpha=0, do not change the destination pixel at all.
1599 * This saves us unnecessary reads and writes to VRAM.
1601 if (src_alpha != 0)
1604 * Full opacity. Do not read the destination pixel, as
1605 * it's value does not matter anyway.
1607 if (src_alpha == 0xff)
1609 dst_red = src_red;
1610 dst_green = src_green;
1611 dst_blue = src_blue;
1613 else
1616 * Alpha blending with source and destination pixels.
1617 * Get destination.
1620 destpix = xbuf[x];
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));
1633 xbuf[x] = destpix;
1637 y++;
1638 pixarray += x_add;
1641 else
1642 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
1645 else
1646 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
1648 else
1649 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
1651 UNLOCK_BITMAP
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);
1660 BOOL done = FALSE;
1662 LOCK_BITMAP
1664 IPTR VideoData = bm->framebuffer;
1666 /* Try to PutImage with 2D engine first */
1667 if (bm->fbgfx)
1669 UBYTE *src = msg->pixels;
1670 ULONG x_add = msg->modulo;
1671 UWORD height = msg->height;
1672 UWORD bw = msg->width;
1674 if (bm->bpp == 2)
1675 bw = (bw + 1) & ~1;
1677 done = TRUE;
1679 if (done)
1681 LOCK_HW
1683 bm->usecount++;
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:
1710 if (bm->bpp == 4)
1712 #if AROS_BIG_ENDIAN
1713 RADEONWaitForFifo(sd, 1);
1714 OUTREG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_32BIT);
1715 #endif
1716 while (height--)
1718 ULONG *line = (ULONG*)src;
1719 ULONG width = msg->width;
1721 while(width)
1723 if (width <= 8)
1725 RADEONWaitForFifo(sd, width);
1726 switch (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++);
1737 width = 0;
1739 else
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++);
1752 width -= 8;
1756 src += x_add;
1758 #if AROS_BIG_ENDIAN
1759 RADEONWaitForFifo(sd, 1);
1760 OUTREG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_NONE);
1761 #endif
1764 else if (bm->bpp == 2)
1766 #if AROS_BIG_ENDIAN
1767 RADEONWaitForFifo(sd, 1);
1768 OUTREG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_HDW);
1769 #endif
1770 if (msg->pixFmt == vHidd_StdPixFmt_Native)
1772 while (height--)
1774 ULONG *line = (ULONG*)src;
1775 ULONG width = bw >> 1;
1777 while(width--)
1779 RADEONWaitForFifo(sd, 1);
1780 OUTREG(RADEON_HOST_DATA0, *line++);
1783 src += x_add;
1786 else
1788 while (height--)
1790 ULONG *line = (ULONG*)src;
1791 ULONG width = bw >> 1;
1793 while(width--)
1795 ULONG tmp = (line[0] << 16) | (line[1] & 0x0000ffff);
1796 RADEONWaitForFifo(sd, 1);
1797 OUTREG(RADEON_HOST_DATA0, tmp);
1798 line+=2;
1801 src += x_add;
1806 #if AROS_BIG_ENDIAN
1807 RADEONWaitForFifo(sd, 1);
1808 OUTREG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_NONE);
1809 #endif
1811 break;
1813 default:
1815 OOP_Object *dstpf;
1816 OOP_Object *srcpf;
1818 srcpf = HIDD_Gfx_GetPixFmt(sd->AtiObject, msg->pixFmt);
1819 OOP_GetAttr(o, aHidd_BitMap_PixFmt, (APTR)&dstpf);
1821 if (bm->bpp == 4)
1823 #if AROS_BIG_ENDIAN
1824 RADEONWaitForFifo(sd, 1);
1825 OUTREG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_32BIT);
1826 #endif
1827 while(height--)
1829 ULONG *line = (ULONG*)sd->cpuscratch;
1830 ULONG width = bw;
1831 APTR _src = src;
1833 HIDD_BM_ConvertPixels(o, &_src, srcpf, msg->modulo, &line, dstpf, msg->modulo, msg->width, 1, NULL);
1835 line = (ULONG*)sd->cpuscratch;
1837 while(width)
1839 if (width <= 8)
1841 RADEONWaitForFifo(sd, width);
1842 switch (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++);
1853 width = 0;
1855 else
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++);
1868 width -= 8;
1872 src += x_add;
1874 #if AROS_BIG_ENDIAN
1875 RADEONWaitForFifo(sd, 1);
1876 OUTREG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_NONE);
1877 #endif
1880 else if (bm->bpp == 2)
1882 #if AROS_BIG_ENDIAN
1883 RADEONWaitForFifo(sd, 1);
1884 OUTREG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_HDW);
1885 #endif
1887 while(height--)
1889 ULONG *line = (ULONG*)sd->cpuscratch;
1890 ULONG width = bw;
1891 APTR _src = src;
1893 HIDD_BM_ConvertPixels(o, &_src, srcpf, msg->modulo, &line, dstpf, msg->modulo, msg->width, 1, NULL);
1895 line = (ULONG*)sd->cpuscratch;
1897 while(width)
1899 if (width <= 16)
1901 RADEONWaitForFifo(sd, width >> 1);
1902 switch (width)
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++);
1913 width = 0;
1915 else
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++);
1928 width -= 16;
1932 src += x_add;
1935 #if AROS_BIG_ENDIAN
1936 RADEONWaitForFifo(sd, 1);
1937 OUTREG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_NONE);
1938 #endif
1943 UNLOCK_HW
1947 if (!done)
1949 if (bm->fbgfx)
1951 VideoData += (IPTR)sd->Card.FrameBuffer;
1953 if (sd->Card.Busy)
1955 LOCK_HW
1956 #warning TODO: NVSync(sd)
1957 RADEONWaitForIdleMMIO(sd);
1958 UNLOCK_HW
1962 switch(msg->pixFmt)
1964 case vHidd_StdPixFmt_Native:
1965 switch(bm->bpp)
1967 case 1:
1969 struct pHidd_BitMap_CopyMemBox8 __m = {
1970 sd->mid_CopyMemBox8,
1971 msg->pixels,
1974 (APTR)VideoData,
1975 msg->x,
1976 msg->y,
1977 msg->width,
1978 msg->height,
1979 msg->modulo,
1980 bm->pitch
1981 }, *m = &__m;
1983 OOP_DoMethod(o, (OOP_Msg)m);
1985 break;
1987 case 2:
1989 struct pHidd_BitMap_CopyMemBox16 __m = {
1990 sd->mid_CopyMemBox16,
1991 msg->pixels,
1994 (APTR)VideoData,
1995 msg->x,
1996 msg->y,
1997 msg->width,
1998 msg->height,
1999 msg->modulo,
2000 bm->pitch
2001 }, *m = &__m;
2003 OOP_DoMethod(o, (OOP_Msg)m);
2005 break;
2007 case 4:
2009 struct pHidd_BitMap_CopyMemBox32 __m = {
2010 sd->mid_CopyMemBox32,
2011 msg->pixels,
2014 (APTR)VideoData,
2015 msg->x,
2016 msg->y,
2017 msg->width,
2018 msg->height,
2019 msg->modulo,
2020 bm->pitch
2021 }, *m = &__m;
2023 OOP_DoMethod(o, (OOP_Msg)m);
2025 break;
2027 } /* switch(data->bytesperpix) */
2028 break;
2030 case vHidd_StdPixFmt_Native32:
2031 switch(bm->bpp)
2033 case 1:
2035 struct pHidd_BitMap_PutMem32Image8 __m = {
2036 sd->mid_PutMem32Image8,
2037 msg->pixels,
2038 (APTR)VideoData,
2039 msg->x,
2040 msg->y,
2041 msg->width,
2042 msg->height,
2043 msg->modulo,
2044 bm->pitch
2045 }, *m = &__m;
2046 OOP_DoMethod(o, (OOP_Msg)m);
2048 break;
2050 case 2:
2052 struct pHidd_BitMap_PutMem32Image16 __m = {
2053 sd->mid_PutMem32Image16,
2054 msg->pixels,
2055 (APTR)VideoData,
2056 msg->x,
2057 msg->y,
2058 msg->width,
2059 msg->height,
2060 msg->modulo,
2061 bm->pitch
2062 }, *m = &__m;
2063 OOP_DoMethod(o, (OOP_Msg)m);
2065 break;
2067 case 4:
2069 struct pHidd_BitMap_CopyMemBox32 __m = {
2070 sd->mid_CopyMemBox32,
2071 msg->pixels,
2074 (APTR)VideoData,
2075 msg->x,
2076 msg->y,
2077 msg->width,
2078 msg->height,
2079 msg->modulo,
2080 bm->pitch
2081 }, *m = &__m;
2083 OOP_DoMethod(o, (OOP_Msg)m);
2085 break;
2087 } /* switch(data->bytesperpix) */
2088 break;
2090 default:
2091 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
2092 break;
2093 } /* switch(msg->pixFmt) */
2096 UNLOCK_BITMAP
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);
2106 LOCK_BITMAP
2108 IPTR VideoData = bm->framebuffer;
2110 if (bm->fbgfx)
2112 VideoData += (IPTR)sd->Card.FrameBuffer;
2113 if (sd->Card.Busy)
2115 LOCK_HW
2116 #warning TODO: NVSync(sd)
2117 RADEONWaitForIdleMMIO(sd);
2118 UNLOCK_HW
2122 switch(msg->pixFmt)
2124 case vHidd_StdPixFmt_Native:
2125 switch(bm->bpp)
2127 case 1:
2129 struct pHidd_BitMap_CopyMemBox8 __m = {
2130 sd->mid_CopyMemBox8,
2131 (APTR)VideoData,
2132 msg->x,
2133 msg->y,
2134 msg->pixels,
2137 msg->width,
2138 msg->height,
2139 bm->pitch,
2140 msg->modulo
2141 }, *m = &__m;
2143 OOP_DoMethod(o, (OOP_Msg)m);
2145 break;
2147 case 2:
2149 struct pHidd_BitMap_CopyMemBox16 __m = {
2150 sd->mid_CopyMemBox16,
2151 (APTR)VideoData,
2152 msg->x,
2153 msg->y,
2154 msg->pixels,
2157 msg->width,
2158 msg->height,
2159 bm->pitch,
2160 msg->modulo
2161 }, *m = &__m;
2163 OOP_DoMethod(o, (OOP_Msg)m);
2165 break;
2167 case 4:
2169 struct pHidd_BitMap_CopyMemBox32 __m = {
2170 sd->mid_CopyMemBox32,
2171 (APTR)VideoData,
2172 msg->x,
2173 msg->y,
2174 msg->pixels,
2177 msg->width,
2178 msg->height,
2179 bm->pitch,
2180 msg->modulo
2181 }, *m = &__m;
2183 OOP_DoMethod(o, (OOP_Msg)m);
2185 break;
2187 } /* switch(data->bytesperpix) */
2188 break;
2190 case vHidd_StdPixFmt_Native32:
2191 switch(bm->bpp)
2193 case 1:
2195 struct pHidd_BitMap_GetMem32Image8 __m = {
2196 sd->mid_GetMem32Image8,
2197 (APTR)VideoData,
2198 msg->x,
2199 msg->y,
2200 msg->pixels,
2201 msg->width,
2202 msg->height,
2203 bm->pitch,
2204 msg->modulo
2205 }, *m = &__m;
2207 OOP_DoMethod(o, (OOP_Msg)m);
2209 break;
2211 case 2:
2213 struct pHidd_BitMap_GetMem32Image16 __m = {
2214 sd->mid_GetMem32Image16,
2215 (APTR)VideoData,
2216 msg->x,
2217 msg->y,
2218 msg->pixels,
2219 msg->width,
2220 msg->height,
2221 bm->pitch,
2222 msg->modulo
2223 }, *m = &__m;
2225 OOP_DoMethod(o, (OOP_Msg)m);
2227 break;
2229 case 4:
2231 struct pHidd_BitMap_CopyMemBox32 __m = {
2232 sd->mid_CopyMemBox32,
2233 (APTR)VideoData,
2234 msg->x,
2235 msg->y,
2236 msg->pixels,
2239 msg->width,
2240 msg->height,
2241 bm->pitch,
2242 msg->modulo
2243 }, *m = &__m;
2245 OOP_DoMethod(o, (OOP_Msg)m);
2247 break;
2249 } /* switch(data->bytesperpix) */
2250 break;
2252 default:
2253 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
2254 break;
2256 } /* switch(msg->pixFmt) */
2258 UNLOCK_BITMAP
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"));
2271 LOCK_BITMAP
2273 IPTR VideoData = bm->framebuffer;
2275 if (bm->fbgfx)
2277 VideoData += (IPTR)sd->Card.FrameBuffer;
2278 if (sd->Card.Busy)
2280 LOCK_HW
2281 #warning TODO: NVSync(sd)
2282 RADEONWaitForIdleMMIO(sd);
2283 UNLOCK_HW
2288 switch(bm->bpp)
2290 case 1:
2292 struct pHidd_BitMap_PutMemTemplate8 __m = {
2293 sd->mid_PutMemTemplate8,
2294 msg->gc,
2295 msg->template,
2296 msg->modulo,
2297 msg->srcx,
2298 (APTR)VideoData,
2299 bm->pitch,
2300 msg->x,
2301 msg->y,
2302 msg->width,
2303 msg->height,
2304 msg->inverttemplate
2305 }, *m = &__m;
2307 OOP_DoMethod(o, (OOP_Msg)m);
2309 break;
2311 case 2:
2313 struct pHidd_BitMap_PutMemTemplate16 __m = {
2314 sd->mid_PutMemTemplate16,
2315 msg->gc,
2316 msg->template,
2317 msg->modulo,
2318 msg->srcx,
2319 (APTR)VideoData,
2320 bm->pitch,
2321 msg->x,
2322 msg->y,
2323 msg->width,
2324 msg->height,
2325 msg->inverttemplate
2326 }, *m = &__m;
2328 OOP_DoMethod(o, (OOP_Msg)m);
2330 break;
2332 case 4:
2334 struct pHidd_BitMap_PutMemTemplate32 __m = {
2335 sd->mid_PutMemTemplate32,
2336 msg->gc,
2337 msg->template,
2338 msg->modulo,
2339 msg->srcx,
2340 (APTR)VideoData,
2341 bm->pitch,
2342 msg->x,
2343 msg->y,
2344 msg->width,
2345 msg->height,
2346 msg->inverttemplate
2347 }, *m = &__m;
2349 OOP_DoMethod(o, (OOP_Msg)m);
2351 break;
2352 } /* switch(bm->bpp) */
2354 UNLOCK_BITMAP
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"));
2366 LOCK_BITMAP
2368 IPTR VideoData = bm->framebuffer;
2370 if (bm->fbgfx)
2372 VideoData += (IPTR)sd->Card.FrameBuffer;
2373 if (sd->Card.Busy)
2375 LOCK_HW
2376 #warning TODO: NVSync(sd)
2377 RADEONWaitForIdleMMIO(sd);
2378 UNLOCK_HW
2383 switch(bm->bpp)
2385 case 1:
2387 struct pHidd_BitMap_PutMemPattern8 __m = {
2388 sd->mid_PutMemPattern8,
2389 msg->gc,
2390 msg->pattern,
2391 msg->patternsrcx,
2392 msg->patternsrcy,
2393 msg->patternheight,
2394 msg->patterndepth,
2395 msg->patternlut,
2396 msg->invertpattern,
2397 msg->mask,
2398 msg->maskmodulo,
2399 msg->masksrcx,
2400 (APTR)VideoData,
2401 bm->pitch,
2402 msg->x,
2403 msg->y,
2404 msg->width,
2405 msg->height
2406 }, *m = &__m;
2408 OOP_DoMethod(o, (OOP_Msg)m);
2410 break;
2412 case 2:
2414 struct pHidd_BitMap_PutMemPattern16 __m = {
2415 sd->mid_PutMemPattern16,
2416 msg->gc,
2417 msg->pattern,
2418 msg->patternsrcx,
2419 msg->patternsrcy,
2420 msg->patternheight,
2421 msg->patterndepth,
2422 msg->patternlut,
2423 msg->invertpattern,
2424 msg->mask,
2425 msg->maskmodulo,
2426 msg->masksrcx,
2427 (APTR)VideoData,
2428 bm->pitch,
2429 msg->x,
2430 msg->y,
2431 msg->width,
2432 msg->height
2433 }, *m = &__m;
2435 OOP_DoMethod(o, (OOP_Msg)m);
2437 break;
2439 case 4:
2441 struct pHidd_BitMap_PutMemPattern32 __m = {
2442 sd->mid_PutMemPattern32,
2443 msg->gc,
2444 msg->pattern,
2445 msg->patternsrcx,
2446 msg->patternsrcy,
2447 msg->patternheight,
2448 msg->patterndepth,
2449 msg->patternlut,
2450 msg->invertpattern,
2451 msg->mask,
2452 msg->maskmodulo,
2453 msg->masksrcx,
2454 (APTR)VideoData,
2455 bm->pitch,
2456 msg->x,
2457 msg->y,
2458 msg->width,
2459 msg->height
2460 }, *m = &__m;
2462 OOP_DoMethod(o, (OOP_Msg)m);
2464 break;
2465 } /* switch(bm->bpp) */
2467 UNLOCK_BITMAP