Fixed out-by-one error in previous commit.
[AROS.git] / workbench / hidds / hidd.radeon / ati_bitmap.c
blobf39ff488358abf08c9b780438b8e5b6aa938ecd4
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 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"));
50 else
51 EnterFunc(bug("[ATIBitMap] OffBitmap::New()\n"));
53 o = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
54 if (o)
56 atiBitMap *bm = OOP_INST_DATA(cl, o);
58 IPTR width, height, depth;
59 UBYTE bytesPerPixel;
60 ULONG fb;
62 OOP_Object *pf;
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");
83 if (depth == 24)
84 depth = 32;
86 if (depth <= 8)
87 bytesPerPixel = 1;
88 else if (depth <= 16)
89 bytesPerPixel = 2;
90 else
91 bytesPerPixel = 4;
93 if (fb)
95 width = 640;
96 height = 480;
97 bytesPerPixel = 4;
98 depth = 32;
101 bm->width = width;
102 bm->height = height;
103 bm->pitch = (width * bytesPerPixel + 63) & ~63;
104 bm->depth = depth;
105 bm->bpp = bytesPerPixel;
106 bm->framebuffer = AllocBitmapArea(sd, bm->width, bm->height, bm->bpp, TRUE);
107 bm->fbgfx = TRUE;
108 bm->state = NULL;
109 bm->BitMap = o;
110 bm->usecount = 0;
111 bm->addresses = AllocVecPooled(sd->memPool, height * sizeof(void*));
113 if (bm->framebuffer != -1)
115 int __tmp;
116 for (__tmp=0; __tmp < height; __tmp++)
117 bm->addresses[__tmp] = (void*)(bm->framebuffer + sd->Card.FrameBuffer + __tmp*bm->pitch);
119 switch(depth)
121 case 15:
122 bm->datatype = 3;
123 break;
125 case 16:
126 bm->datatype = 4;
127 break;
129 case 32:
130 bm->datatype = 6;
131 break;
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);
153 if (bm->state)
155 LOCK_HW
157 InitMode(sd, bm->state, 640, 480, 16, 25200, bm->framebuffer,
158 640, 480,
159 656, 752, 800,
160 490, 492, 525);
162 LoadState(sd, bm->state);
163 //LoadState(sd, sd->poweron_state);
164 DPMS(sd, sd->dpms);
166 RADEONEngineReset(sd);
167 RADEONEngineRestore(sd);
169 UNLOCK_HW
171 return o;
174 else if (bm->framebuffer != -1)
176 HIDDT_ModeID modeid;
177 OOP_Object *sync;
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)
186 IPTR pixel;
187 IPTR hdisp, vdisp, hstart, hend, htotal, vstart, vend, vtotal;
189 /* Get Sync and PixelFormat properties */
190 struct pHidd_Gfx_GetMode __getmodemsg = {
191 modeID: modeid,
192 syncPtr: &sync,
193 pixFmtPtr: &pf,
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));
212 pixel /= 1000;
214 if (bm->state)
216 LOCK_HW
218 InitMode(sd, bm->state, width, height, depth, pixel, bm->framebuffer,
219 hdisp, vdisp,
220 hstart, hend, htotal,
221 vstart, vend, vtotal);
223 LoadState(sd, bm->state);
224 DPMS(sd, sd->dpms);
226 RADEONEngineReset(sd);
227 RADEONEngineRestore(sd);
229 UNLOCK_HW
231 return o;
236 else
238 if (bm->framebuffer == -1)
240 int __tmp;
241 bm->framebuffer = (IPTR)AllocMem(bm->pitch * bm->height,
242 MEMF_PUBLIC | MEMF_CLEAR);
243 bm->fbgfx = FALSE;
245 for (__tmp=0; __tmp < height; __tmp++)
246 bm->addresses[__tmp] = (void*)(bm->framebuffer + __tmp*bm->pitch);
248 else
249 bm->fbgfx = TRUE;
251 if ((bm->framebuffer != 0xffffffff) && (bm->framebuffer != 0))
253 return o;
257 OOP_MethodID disp_mid = OOP_GetMethodID((STRPTR)IID_Root, moRoot_Dispose);
258 OOP_CoerceMethod(cl, o, (OOP_Msg) &disp_mid);
261 return NULL;
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);
272 LOCK_BITMAP
273 LOCK_HW
274 // NVDmaKickoff(&sd->Card);
275 RADEONWaitForIdleMMIO(sd);
277 if (bm->fbgfx)
279 FreeBitmapArea(sd, bm->framebuffer, bm->width, bm->height, bm->bpp);
281 bm->framebuffer = -1;
282 bm->fbgfx = 0;
284 else
285 FreeMem((APTR)bm->framebuffer, bm->pitch * bm->height);
287 FreeVecPooled(sd->memPool, bm->addresses);
289 if (bm->state)
290 FreePooled(sd->memPool, bm->state, sizeof(struct CardState));
292 bm->state = NULL;
294 UNLOCK_HW
295 UNLOCK_BITMAP
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);
307 ULONG idx;
309 if (IS_ATIBM_ATTR(msg->attrID, idx))
311 switch (idx)
313 case aoHidd_ATIBitMap_Drawable:
314 if (bm->fbgfx)
315 *msg->storage = bm->framebuffer + (IPTR)sd->Card.FrameBuffer;
316 else
317 *msg->storage = bm->framebuffer;
318 break;
320 default:
321 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
324 else
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",
339 bm->framebuffer));
341 LOCK_BITMAP
343 if (bm->fbgfx)
345 LOCK_HW
346 sd->Card.Busy = TRUE;
347 bm->usecount++;
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);
370 UNLOCK_HW
372 else
374 ULONG *ptr = (ULONG*)bm->framebuffer;
375 ULONG val = 0;
376 int i = (bm->pitch * bm->height) >> 2;
378 switch (bm->bpp)
380 case 2:
381 val = GC_BG(msg->gc) << 16 | (GC_BG(msg->gc) & 0xffff);
382 break;
384 default:
385 val = GC_BG(msg->gc) << 16 | (GC_BG(msg->gc) & 0xffff);
386 break;
389 do { *ptr++ = val; } while(--i);
392 UNLOCK_BITMAP
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));
406 LOCK_BITMAP
408 if (bm->fbgfx)
410 LOCK_HW
411 sd->Card.Busy = TRUE;
412 bm->usecount++;
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));
435 UNLOCK_HW
437 else
439 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
442 UNLOCK_BITMAP
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)));
458 LOCK_BITMAP
460 if ((GC_LINEPAT(gc) =! (UWORD)~0) || !bm->fbgfx)
462 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
464 else
466 LOCK_HW
467 sd->Card.Busy = TRUE;
468 bm->usecount++;
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);
484 if (GC_DOCLIP(gc))
486 bm->dp_gui_master_cntl_clip |= RADEON_GMC_DST_CLIPPING;
487 WORD x1,y1,x2,y2;
488 x1 = GC_CLIPX1(gc);
489 y1 = GC_CLIPY1(gc);
490 x2 = GC_CLIPX2(gc) + 1;
491 y2 = GC_CLIPY2(gc) + 1;
493 if (x1 < 0)
495 x1 = (-x1) & 0x3fff;
496 x1 |= RADEON_SC_SIGN_MASK_LO;
498 if (x2 < 0)
500 x2 = (-x2) & 0x3fff;
501 x2 |= RADEON_SC_SIGN_MASK_LO;
503 if (y1 < 0)
505 y1 = (-y1) & 0x3fff;
506 y1 |= RADEON_SC_SIGN_MASK_LO;
508 if (y2 < 0)
510 y2 = (-y2) & 0x3fff;
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);
519 else
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));
534 UNLOCK_HW
537 UNLOCK_BITMAP
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);
548 UWORD addX, addY;
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;
556 LOCK_BITMAP
558 if ((GC_LINEPAT(gc) =! (UWORD)~0) || !bm->fbgfx)
560 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
562 else
564 LOCK_HW
565 sd->Card.Busy = TRUE;
566 bm->usecount++;
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);
582 if (GC_DOCLIP(gc))
584 bm->dp_gui_master_cntl_clip |= RADEON_GMC_DST_CLIPPING;
585 UWORD x1,y1,x2,y2;
586 x1 = GC_CLIPX1(gc);
587 y1 = GC_CLIPY1(gc);
588 x2 = GC_CLIPX2(gc) + 1;
589 y2 = GC_CLIPY2(gc) + 1;
591 if (x1 < 0)
593 x1 = (-x1) & 0x3fff;
594 x1 |= RADEON_SC_SIGN_MASK_LO;
596 if (x2 < 0)
598 x2 = (-x2) & 0x3fff;
599 x2 |= RADEON_SC_SIGN_MASK_LO;
601 if (y1 < 0)
603 y1 = (-y1) & 0x3fff;
604 y1 |= RADEON_SC_SIGN_MASK_LO;
606 if (y2 < 0)
608 y2 = (-y2) & 0x3fff;
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);
617 else
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));
639 UNLOCK_HW
642 UNLOCK_BITMAP
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);
653 ULONG i;
655 D(bug("[ATI] DrawPolygon(%p)\n",
656 bm->framebuffer));
658 LOCK_BITMAP
660 if ((GC_LINEPAT(gc) =! (UWORD)~0) || !bm->fbgfx)
662 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
664 else
666 LOCK_HW
667 sd->Card.Busy = TRUE;
668 bm->usecount++;
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);
684 if (GC_DOCLIP(gc))
686 bm->dp_gui_master_cntl_clip |= RADEON_GMC_DST_CLIPPING;
687 UWORD x1,y1,x2,y2;
688 x1 = GC_CLIPX1(gc);
689 y1 = GC_CLIPY1(gc);
690 x2 = GC_CLIPX2(gc) + 1;
691 y2 = GC_CLIPY2(gc) + 1;
693 if (x1 < 0)
695 x1 = (-x1) & 0x3fff;
696 x1 |= RADEON_SC_SIGN_MASK_LO;
698 if (x2 < 0)
700 x2 = (-x2) & 0x3fff;
701 x2 |= RADEON_SC_SIGN_MASK_LO;
703 if (y1 < 0)
705 y1 = (-y1) & 0x3fff;
706 y1 |= RADEON_SC_SIGN_MASK_LO;
708 if (y2 < 0)
710 y2 = (-y2) & 0x3fff;
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);
719 else
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]);
734 UNLOCK_HW
737 UNLOCK_BITMAP
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];
748 LOCK_BITMAP
750 if (bm->fbgfx)
752 if (sd->Card.Busy)
754 LOCK_HW
755 /* TODO: NVSync(sd) */
756 RADEONWaitForIdleMMIO(sd);
757 UNLOCK_HW
762 switch (bm->bpp)
764 case 1:
765 ((UBYTE *)ptr)[msg->x] = msg->pixel;
766 break;
767 case 2:
768 ((UWORD *)ptr)[msg->x] = msg->pixel;
769 break;
770 case 4:
771 ((ULONG *)ptr)[msg->x] = msg->pixel;
772 break;
775 UNLOCK_BITMAP
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;
788 HIDDT_DrawMode mode;
789 HIDDT_Pixel writeMask;
791 src = GC_FG(gc);
792 mode = GC_DRMD(gc);
794 LOCK_BITMAP
796 if (bm->fbgfx)
798 if (sd->Card.Busy)
800 LOCK_HW
801 /* TODO: NVSync(sd) */
802 RADEONWaitForIdleMMIO(sd);
803 UNLOCK_HW
807 if (vHidd_GC_DrawMode_Copy == mode && GC_COLMASK(gc) == ~0)
809 val = src;
811 else
813 switch (bm->bpp)
815 case 1:
816 dest = ((UBYTE *)ptr)[msg->x];
817 break;
818 case 2:
819 dest = ((UWORD *)ptr)[msg->x];
820 break;
821 case 4:
822 dest = ((ULONG *)ptr)[msg->x];
823 break;
826 writeMask = ~GC_COLMASK(gc) & dest;
828 val = 0;
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;
838 switch (bm->bpp)
840 case 1:
841 ((UBYTE *)ptr)[msg->x] = val;
842 break;
843 case 2:
844 ((UWORD *)ptr)[msg->x] = val;
845 break;
846 case 4:
847 ((ULONG *)ptr)[msg->x] = val;
848 break;
851 UNLOCK_BITMAP
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 */
862 HIDDT_Pixel src;
863 HIDDT_DrawMode mode;
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);
875 src = GC_FG(gc);
876 mode = GC_DRMD(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)
885 val = src;
887 else
889 switch (bm->bpp)
891 case 1:
892 dest = ((UBYTE *)ptr)[x];
893 break;
894 case 2:
895 dest = ((UWORD *)ptr)[x];
896 break;
897 case 4:
898 dest = ((ULONG *)ptr)[x];
899 break;
902 writeMask = ~GC_COLMASK(gc) & dest;
904 val = 0;
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;
914 switch (bm->bpp)
916 case 1:
917 ((UBYTE *)ptr)[x] = val;
918 break;
919 case 2:
920 ((UWORD *)ptr)[x] = val;
921 break;
922 case 4:
923 ((ULONG *)ptr)[x] = val;
924 break;
928 LOCK_BITMAP
930 UBYTE *ptr = (UBYTE*)((IPTR)bm->framebuffer);
931 if (bm->fbgfx)
933 ptr += (IPTR)sd->Card.FrameBuffer;
934 if (sd->Card.Busy)
936 LOCK_HW
937 /* TODO: NVSync(sd) */
938 RADEONWaitForIdleMMIO(sd);
939 UNLOCK_HW
943 while (d2 < 0) /* til slope = -1 */
945 /* draw 4 points using symmetry */
947 if (doclip)
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);
961 else
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 */
970 t9 = t9 + t3;
971 if (d1 < 0) /* move straight up */
973 d1 = d1 + t9 + t2;
974 d2 = d2 + t9;
976 else /* move up and left */
978 x--;
979 t8 = t8 - t6;
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 */
988 if (doclip)
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);
1002 else
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 */
1011 t8 = t8 - t6;
1012 if (d2 < 0) /* move up and left */
1014 y++;
1015 t9 = t9 + t3;
1016 d2 = d2 + t9 + t5 - t8;
1018 else /* move straight left */
1020 d2 = d2 + t5 - t8;
1023 } while (x >= 0);
1026 UNLOCK_BITMAP
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);
1037 LOCK_BITMAP
1039 void *ptr = bm->addresses[msg->y];
1041 if (bm->fbgfx)
1043 if (sd->Card.Busy)
1045 LOCK_HW
1046 /* TODO: NVSync(sd) */
1047 RADEONWaitForIdleMMIO(sd);
1048 UNLOCK_HW
1052 switch (bm->bpp)
1054 case 1:
1055 pixel = ((UBYTE *)ptr)[msg->x];
1056 break;
1057 case 2:
1058 pixel = ((UWORD *)ptr)[msg->x];
1059 break;
1060 case 4:
1061 pixel = ((ULONG *)ptr)[msg->x];
1062 break;
1065 UNLOCK_BITMAP
1067 /* Get pen number from colortab */
1068 return pixel;
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);
1079 LOCK_BITMAP
1081 if ((OOP_OCLASS(msg->srcBitMap) == sd->PlanarBMClass) && bm->fbgfx)
1083 struct planarbm_data *planar = OOP_INST_DATA(OOP_OCLASS(msg->srcBitMap), msg->srcBitMap);
1084 HIDDT_Pixel bg, fg;
1085 ULONG cemd;
1086 ULONG skipleft = msg->srcX - (msg->srcX & ~31);
1087 ULONG mask = ~0 << bm->depth;
1089 if (bm->depth == 32)
1090 mask = 0xff000000;
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;
1099 LOCK_HW
1101 bm->usecount++;
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);
1123 else
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);
1142 #if AROS_BIG_ENDIAN
1143 RADEONWaitForFifo(sd, 1);
1144 OUTREG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_32BIT);
1145 #endif
1147 while(h--)
1149 int i;
1151 for (i=0; i < bw >> 5; i++)
1153 RADEONWaitForFifo(sd, 1);
1154 OUTREG(RADEON_HOST_DATA0, ptr[i]);
1157 ptr += planar->bytesperrow >> 2;
1160 #if AROS_BIG_ENDIAN
1161 RADEONWaitForFifo(sd, 1);
1162 OUTREG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_NONE);
1163 #endif
1165 UNLOCK_HW
1168 else
1169 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
1171 UNLOCK_BITMAP
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);
1192 LOCK_BITMAP
1194 IPTR VideoData = bm->framebuffer;
1196 if (bm->fbgfx)
1198 VideoData += (IPTR)sd->Card.FrameBuffer;
1199 if (sd->Card.Busy)
1201 LOCK_HW
1202 /* TODO: NVSync(sd) */
1203 RADEONWaitForIdleMMIO(sd);
1204 UNLOCK_HW
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;
1213 return TRUE;
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);
1223 UNLOCK_BITMAP
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);
1238 LOCK_BITMAP
1240 if (bm->fbgfx)
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;
1249 if (bm->bpp == 2)
1250 bw = (bw + 1) & ~1;
1252 LOCK_HW
1254 bm->usecount++;
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);
1277 if (bm->bpp == 4)
1279 #if AROS_BIG_ENDIAN
1280 RADEONWaitForFifo(sd, 1);
1281 OUTREG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_32BIT);
1282 #endif
1283 while (height--)
1285 UBYTE *line = (UBYTE*)src;
1286 ULONG width = msg->width;
1288 while(width)
1290 if (width <= 8)
1292 RADEONWaitForFifo(sd, width);
1293 switch (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++]);
1304 width = 0;
1306 else
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++]);
1319 width -= 8;
1323 src += x_add;
1326 else if (bm->bpp == 2)
1328 #if AROS_BIG_ENDIAN
1329 RADEONWaitForFifo(sd, 1);
1330 OUTREG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_HDW);
1331 #endif
1332 while (height--)
1334 UBYTE *line = (UBYTE*)src;
1335 ULONG width = bw >> 1;
1337 while(width--)
1339 ULONG tmp = (colmap[line[0]] << 16) | (colmap[line[1]] & 0x0000ffff);
1340 RADEONWaitForFifo(sd, 1);
1341 OUTREG(RADEON_HOST_DATA0, tmp);
1342 line+=2;
1345 src += x_add;
1350 #if AROS_BIG_ENDIAN
1351 RADEONWaitForFifo(sd, 1);
1352 OUTREG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_NONE);
1353 #endif
1355 UNLOCK_HW
1357 else
1358 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
1360 UNLOCK_BITMAP
1363 static inline int do_alpha(int a, int v)
1365 int tmp = a*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);
1376 LOCK_BITMAP
1378 /* Try to PutAlphaImage with 2D engine first */
1379 if (bm->fbgfx)
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;
1385 ULONG y = msg->y;
1386 ULONG x;
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 */
1391 if (sd->Card.Busy)
1393 LOCK_HW
1394 RADEONWaitForIdleMMIO(sd);
1395 UNLOCK_HW
1399 * Treat each depth case separately
1401 if (bm->bpp == 4)
1403 while(height--)
1405 ULONG *xbuf = bm->addresses[y];
1406 xbuf += msg->x;
1408 for (x=0; x < bw; x++)
1410 ULONG destpix;
1411 ULONG srcpix;
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++;
1417 #if AROS_BIG_ENDIAN
1418 src_red = (srcpix & 0x00FF0000) >> 16;
1419 src_green = (srcpix & 0x0000FF00) >> 8;
1420 src_blue = (srcpix & 0x000000FF);
1421 src_alpha = (srcpix & 0xFF000000) >> 24;
1422 #else
1423 src_red = (srcpix & 0x0000FF00) >> 8;
1424 src_green = (srcpix & 0x00FF0000) >> 16;
1425 src_blue = (srcpix & 0xFF000000) >> 24;
1426 src_alpha = (srcpix & 0x000000FF);
1427 #endif
1430 * If alpha=0, do not change the destination pixel at all.
1431 * This saves us unnecessary reads and writes to VRAM.
1433 if (src_alpha != 0)
1436 * Full opacity. Do not read the destination pixel, as
1437 * it's value does not matter anyway.
1439 if (src_alpha == 0xff)
1441 dst_red = src_red;
1442 dst_green = src_green;
1443 dst_blue = src_blue;
1445 else
1448 * Alpha blending with source and destination pixels.
1449 * Get destination.
1451 destpix = xbuf[x];
1453 // #if AROS_BIG_ENDIAN
1454 // dst_red = (destpix & 0x0000FF00) >> 8;
1455 // dst_green = (destpix & 0x00FF0000) >> 16;
1456 // dst_blue = (destpix & 0xFF000000) >> 24;
1457 // #else
1458 dst_red = (destpix & 0x00FF0000) >> 16;
1459 dst_green = (destpix & 0x0000FF00) >> 8;
1460 dst_blue = (destpix & 0x000000FF);
1461 // #endif
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);
1471 // #else
1472 destpix = (dst_red << 16) + (dst_green << 8) + (dst_blue);
1473 // #endif
1475 /* Store the new pixel */
1476 xbuf[x] = destpix;
1480 y++;
1481 pixarray += x_add;
1484 /* 2bpp cases... */
1485 else if (bm->bpp == 2)
1487 if (bm->depth == 16)
1489 while(height--)
1491 UWORD *xbuf = bm->addresses[y];
1492 xbuf += msg->x;
1494 for (x=0; x < bw; x++)
1496 UWORD destpix;
1497 ULONG srcpix;
1498 LONG src_red, src_green, src_blue, src_alpha;
1499 LONG dst_red, dst_green, dst_blue;
1501 srcpix = *pixarray++;
1502 #if AROS_BIG_ENDIAN
1503 src_red = (srcpix & 0x00FF0000) >> 16;
1504 src_green = (srcpix & 0x0000FF00) >> 8;
1505 src_blue = (srcpix & 0x000000FF);
1506 src_alpha = (srcpix & 0xFF000000) >> 24;
1507 #else
1508 src_red = (srcpix & 0x0000FF00) >> 8;
1509 src_green = (srcpix & 0x00FF0000) >> 16;
1510 src_blue = (srcpix & 0xFF000000) >> 24;
1511 src_alpha = (srcpix & 0x000000FF);
1512 #endif
1515 * If alpha=0, do not change the destination pixel at all.
1516 * This saves us unnecessary reads and writes to VRAM.
1518 if (src_alpha != 0)
1521 * Full opacity. Do not read the destination pixel, as
1522 * it's value does not matter anyway.
1524 if (src_alpha == 0xff)
1526 dst_red = src_red;
1527 dst_green = src_green;
1528 dst_blue = src_blue;
1530 else
1533 * Alpha blending with source and destination pixels.
1534 * Get destination.
1537 destpix = xbuf[x];
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));
1550 xbuf[x] = destpix;
1554 y++;
1555 pixarray += x_add;
1558 else if (bm->depth == 15)
1560 while(height--)
1562 UWORD *xbuf = bm->addresses[y];
1563 xbuf += msg->x;
1565 for (x=0; x < bw; x++)
1567 UWORD destpix = 0;
1568 ULONG srcpix;
1569 LONG src_red, src_green, src_blue, src_alpha;
1570 LONG dst_red, dst_green, dst_blue;
1572 srcpix = *pixarray++;
1573 #if AROS_BIG_ENDIAN
1574 src_red = (srcpix & 0x00FF0000) >> 16;
1575 src_green = (srcpix & 0x0000FF00) >> 8;
1576 src_blue = (srcpix & 0x000000FF);
1577 src_alpha = (srcpix & 0xFF000000) >> 24;
1578 #else
1579 src_red = (srcpix & 0x0000FF00) >> 8;
1580 src_green = (srcpix & 0x00FF0000) >> 16;
1581 src_blue = (srcpix & 0xFF000000) >> 24;
1582 src_alpha = (srcpix & 0x000000FF);
1583 #endif
1585 * If alpha=0, do not change the destination pixel at all.
1586 * This saves us unnecessary reads and writes to VRAM.
1588 if (src_alpha != 0)
1591 * Full opacity. Do not read the destination pixel, as
1592 * it's value does not matter anyway.
1594 if (src_alpha == 0xff)
1596 dst_red = src_red;
1597 dst_green = src_green;
1598 dst_blue = src_blue;
1600 else
1603 * Alpha blending with source and destination pixels.
1604 * Get destination.
1607 destpix = xbuf[x];
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));
1620 xbuf[x] = destpix;
1624 y++;
1625 pixarray += x_add;
1628 else
1629 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
1632 else
1633 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
1635 else
1636 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
1638 UNLOCK_BITMAP
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);
1647 BOOL done = FALSE;
1649 LOCK_BITMAP
1651 IPTR VideoData = bm->framebuffer;
1653 /* Try to PutImage with 2D engine first */
1654 if (bm->fbgfx)
1656 UBYTE *src = msg->pixels;
1657 ULONG x_add = msg->modulo;
1658 UWORD height = msg->height;
1659 UWORD bw = msg->width;
1661 if (bm->bpp == 2)
1662 bw = (bw + 1) & ~1;
1664 done = TRUE;
1666 if (done)
1668 LOCK_HW
1670 bm->usecount++;
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:
1697 if (bm->bpp == 4)
1699 #if AROS_BIG_ENDIAN
1700 RADEONWaitForFifo(sd, 1);
1701 OUTREG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_32BIT);
1702 #endif
1703 while (height--)
1705 ULONG *line = (ULONG*)src;
1706 ULONG width = msg->width;
1708 while(width)
1710 if (width <= 8)
1712 RADEONWaitForFifo(sd, width);
1713 switch (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++);
1724 width = 0;
1726 else
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++);
1739 width -= 8;
1743 src += x_add;
1745 #if AROS_BIG_ENDIAN
1746 RADEONWaitForFifo(sd, 1);
1747 OUTREG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_NONE);
1748 #endif
1751 else if (bm->bpp == 2)
1753 #if AROS_BIG_ENDIAN
1754 RADEONWaitForFifo(sd, 1);
1755 OUTREG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_HDW);
1756 #endif
1757 if (msg->pixFmt == vHidd_StdPixFmt_Native)
1759 while (height--)
1761 ULONG *line = (ULONG*)src;
1762 ULONG width = bw >> 1;
1764 while(width--)
1766 RADEONWaitForFifo(sd, 1);
1767 OUTREG(RADEON_HOST_DATA0, *line++);
1770 src += x_add;
1773 else
1775 while (height--)
1777 ULONG *line = (ULONG*)src;
1778 ULONG width = bw >> 1;
1780 while(width--)
1782 ULONG tmp = (line[0] << 16) | (line[1] & 0x0000ffff);
1783 RADEONWaitForFifo(sd, 1);
1784 OUTREG(RADEON_HOST_DATA0, tmp);
1785 line+=2;
1788 src += x_add;
1793 #if AROS_BIG_ENDIAN
1794 RADEONWaitForFifo(sd, 1);
1795 OUTREG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_NONE);
1796 #endif
1798 break;
1800 default:
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);
1807 if (bm->bpp == 4)
1809 #if AROS_BIG_ENDIAN
1810 RADEONWaitForFifo(sd, 1);
1811 OUTREG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_32BIT);
1812 #endif
1813 while(height--)
1815 ULONG *line = (ULONG*)sd->cpuscratch;
1816 ULONG width = bw;
1817 APTR _src = src;
1819 HIDD_BM_ConvertPixels(o, &_src, srcpf, msg->modulo, (void **)&line, dstpf, msg->modulo, msg->width, 1, NULL);
1821 line = (ULONG*)sd->cpuscratch;
1823 while(width)
1825 if (width <= 8)
1827 RADEONWaitForFifo(sd, width);
1828 switch (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++);
1839 width = 0;
1841 else
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++);
1854 width -= 8;
1858 src += x_add;
1860 #if AROS_BIG_ENDIAN
1861 RADEONWaitForFifo(sd, 1);
1862 OUTREG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_NONE);
1863 #endif
1866 else if (bm->bpp == 2)
1868 #if AROS_BIG_ENDIAN
1869 RADEONWaitForFifo(sd, 1);
1870 OUTREG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_HDW);
1871 #endif
1873 while(height--)
1875 ULONG *line = (ULONG*)sd->cpuscratch;
1876 ULONG width = bw;
1877 APTR _src = src;
1879 HIDD_BM_ConvertPixels(o, &_src, srcpf, msg->modulo, (void **)&line, dstpf, msg->modulo, msg->width, 1, NULL);
1881 line = (ULONG*)sd->cpuscratch;
1883 while(width)
1885 if (width <= 16)
1887 RADEONWaitForFifo(sd, width >> 1);
1888 switch (width)
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++);
1899 width = 0;
1901 else
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++);
1914 width -= 16;
1918 src += x_add;
1921 #if AROS_BIG_ENDIAN
1922 RADEONWaitForFifo(sd, 1);
1923 OUTREG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_NONE);
1924 #endif
1929 UNLOCK_HW
1933 if (!done)
1935 if (bm->fbgfx)
1937 VideoData += (IPTR)sd->Card.FrameBuffer;
1939 if (sd->Card.Busy)
1941 LOCK_HW
1942 /* TODO: NVSync(sd) */
1943 RADEONWaitForIdleMMIO(sd);
1944 UNLOCK_HW
1948 switch(msg->pixFmt)
1950 case vHidd_StdPixFmt_Native:
1951 switch(bm->bpp)
1953 case 1:
1955 struct pHidd_BitMap_CopyMemBox8 __m = {
1956 sd->mid_CopyMemBox8,
1957 msg->pixels,
1960 (APTR)VideoData,
1961 msg->x,
1962 msg->y,
1963 msg->width,
1964 msg->height,
1965 msg->modulo,
1966 bm->pitch
1967 }, *m = &__m;
1969 OOP_DoMethod(o, (OOP_Msg)m);
1971 break;
1973 case 2:
1975 struct pHidd_BitMap_CopyMemBox16 __m = {
1976 sd->mid_CopyMemBox16,
1977 msg->pixels,
1980 (APTR)VideoData,
1981 msg->x,
1982 msg->y,
1983 msg->width,
1984 msg->height,
1985 msg->modulo,
1986 bm->pitch
1987 }, *m = &__m;
1989 OOP_DoMethod(o, (OOP_Msg)m);
1991 break;
1993 case 4:
1995 struct pHidd_BitMap_CopyMemBox32 __m = {
1996 sd->mid_CopyMemBox32,
1997 msg->pixels,
2000 (APTR)VideoData,
2001 msg->x,
2002 msg->y,
2003 msg->width,
2004 msg->height,
2005 msg->modulo,
2006 bm->pitch
2007 }, *m = &__m;
2009 OOP_DoMethod(o, (OOP_Msg)m);
2011 break;
2013 } /* switch(data->bytesperpix) */
2014 break;
2016 case vHidd_StdPixFmt_Native32:
2017 switch(bm->bpp)
2019 case 1:
2021 struct pHidd_BitMap_PutMem32Image8 __m = {
2022 sd->mid_PutMem32Image8,
2023 msg->pixels,
2024 (APTR)VideoData,
2025 msg->x,
2026 msg->y,
2027 msg->width,
2028 msg->height,
2029 msg->modulo,
2030 bm->pitch
2031 }, *m = &__m;
2032 OOP_DoMethod(o, (OOP_Msg)m);
2034 break;
2036 case 2:
2038 struct pHidd_BitMap_PutMem32Image16 __m = {
2039 sd->mid_PutMem32Image16,
2040 msg->pixels,
2041 (APTR)VideoData,
2042 msg->x,
2043 msg->y,
2044 msg->width,
2045 msg->height,
2046 msg->modulo,
2047 bm->pitch
2048 }, *m = &__m;
2049 OOP_DoMethod(o, (OOP_Msg)m);
2051 break;
2053 case 4:
2055 struct pHidd_BitMap_CopyMemBox32 __m = {
2056 sd->mid_CopyMemBox32,
2057 msg->pixels,
2060 (APTR)VideoData,
2061 msg->x,
2062 msg->y,
2063 msg->width,
2064 msg->height,
2065 msg->modulo,
2066 bm->pitch
2067 }, *m = &__m;
2069 OOP_DoMethod(o, (OOP_Msg)m);
2071 break;
2073 } /* switch(data->bytesperpix) */
2074 break;
2076 default:
2077 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
2078 break;
2079 } /* switch(msg->pixFmt) */
2082 UNLOCK_BITMAP
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);
2092 LOCK_BITMAP
2094 IPTR VideoData = bm->framebuffer;
2096 if (bm->fbgfx)
2098 VideoData += (IPTR)sd->Card.FrameBuffer;
2099 if (sd->Card.Busy)
2101 LOCK_HW
2102 /* TODO: NVSync(sd) */
2103 RADEONWaitForIdleMMIO(sd);
2104 UNLOCK_HW
2108 switch(msg->pixFmt)
2110 case vHidd_StdPixFmt_Native:
2111 switch(bm->bpp)
2113 case 1:
2115 struct pHidd_BitMap_CopyMemBox8 __m = {
2116 sd->mid_CopyMemBox8,
2117 (APTR)VideoData,
2118 msg->x,
2119 msg->y,
2120 msg->pixels,
2123 msg->width,
2124 msg->height,
2125 bm->pitch,
2126 msg->modulo
2127 }, *m = &__m;
2129 OOP_DoMethod(o, (OOP_Msg)m);
2131 break;
2133 case 2:
2135 struct pHidd_BitMap_CopyMemBox16 __m = {
2136 sd->mid_CopyMemBox16,
2137 (APTR)VideoData,
2138 msg->x,
2139 msg->y,
2140 msg->pixels,
2143 msg->width,
2144 msg->height,
2145 bm->pitch,
2146 msg->modulo
2147 }, *m = &__m;
2149 OOP_DoMethod(o, (OOP_Msg)m);
2151 break;
2153 case 4:
2155 struct pHidd_BitMap_CopyMemBox32 __m = {
2156 sd->mid_CopyMemBox32,
2157 (APTR)VideoData,
2158 msg->x,
2159 msg->y,
2160 msg->pixels,
2163 msg->width,
2164 msg->height,
2165 bm->pitch,
2166 msg->modulo
2167 }, *m = &__m;
2169 OOP_DoMethod(o, (OOP_Msg)m);
2171 break;
2173 } /* switch(data->bytesperpix) */
2174 break;
2176 case vHidd_StdPixFmt_Native32:
2177 switch(bm->bpp)
2179 case 1:
2181 struct pHidd_BitMap_GetMem32Image8 __m = {
2182 sd->mid_GetMem32Image8,
2183 (APTR)VideoData,
2184 msg->x,
2185 msg->y,
2186 msg->pixels,
2187 msg->width,
2188 msg->height,
2189 bm->pitch,
2190 msg->modulo
2191 }, *m = &__m;
2193 OOP_DoMethod(o, (OOP_Msg)m);
2195 break;
2197 case 2:
2199 struct pHidd_BitMap_GetMem32Image16 __m = {
2200 sd->mid_GetMem32Image16,
2201 (APTR)VideoData,
2202 msg->x,
2203 msg->y,
2204 msg->pixels,
2205 msg->width,
2206 msg->height,
2207 bm->pitch,
2208 msg->modulo
2209 }, *m = &__m;
2211 OOP_DoMethod(o, (OOP_Msg)m);
2213 break;
2215 case 4:
2217 struct pHidd_BitMap_CopyMemBox32 __m = {
2218 sd->mid_CopyMemBox32,
2219 (APTR)VideoData,
2220 msg->x,
2221 msg->y,
2222 msg->pixels,
2225 msg->width,
2226 msg->height,
2227 bm->pitch,
2228 msg->modulo
2229 }, *m = &__m;
2231 OOP_DoMethod(o, (OOP_Msg)m);
2233 break;
2235 } /* switch(data->bytesperpix) */
2236 break;
2238 default:
2239 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
2240 break;
2242 } /* switch(msg->pixFmt) */
2244 UNLOCK_BITMAP
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"));
2257 LOCK_BITMAP
2259 IPTR VideoData = bm->framebuffer;
2261 if (bm->fbgfx)
2263 VideoData += (IPTR)sd->Card.FrameBuffer;
2264 if (sd->Card.Busy)
2266 LOCK_HW
2267 /* TODO: NVSync(sd) */
2268 RADEONWaitForIdleMMIO(sd);
2269 UNLOCK_HW
2274 switch(bm->bpp)
2276 case 1:
2278 struct pHidd_BitMap_PutMemTemplate8 __m = {
2279 sd->mid_PutMemTemplate8,
2280 msg->gc,
2281 msg->masktemplate,
2282 msg->modulo,
2283 msg->srcx,
2284 (APTR)VideoData,
2285 bm->pitch,
2286 msg->x,
2287 msg->y,
2288 msg->width,
2289 msg->height,
2290 msg->inverttemplate
2291 }, *m = &__m;
2293 OOP_DoMethod(o, (OOP_Msg)m);
2295 break;
2297 case 2:
2299 struct pHidd_BitMap_PutMemTemplate16 __m = {
2300 sd->mid_PutMemTemplate16,
2301 msg->gc,
2302 msg->masktemplate,
2303 msg->modulo,
2304 msg->srcx,
2305 (APTR)VideoData,
2306 bm->pitch,
2307 msg->x,
2308 msg->y,
2309 msg->width,
2310 msg->height,
2311 msg->inverttemplate
2312 }, *m = &__m;
2314 OOP_DoMethod(o, (OOP_Msg)m);
2316 break;
2318 case 4:
2320 struct pHidd_BitMap_PutMemTemplate32 __m = {
2321 sd->mid_PutMemTemplate32,
2322 msg->gc,
2323 msg->masktemplate,
2324 msg->modulo,
2325 msg->srcx,
2326 (APTR)VideoData,
2327 bm->pitch,
2328 msg->x,
2329 msg->y,
2330 msg->width,
2331 msg->height,
2332 msg->inverttemplate
2333 }, *m = &__m;
2335 OOP_DoMethod(o, (OOP_Msg)m);
2337 break;
2338 } /* switch(bm->bpp) */
2340 UNLOCK_BITMAP
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"));
2352 LOCK_BITMAP
2354 IPTR VideoData = bm->framebuffer;
2356 if (bm->fbgfx)
2358 VideoData += (IPTR)sd->Card.FrameBuffer;
2359 if (sd->Card.Busy)
2361 LOCK_HW
2362 /* TODO: NVSync(sd) */
2363 RADEONWaitForIdleMMIO(sd);
2364 UNLOCK_HW
2369 switch(bm->bpp)
2371 case 1:
2373 struct pHidd_BitMap_PutMemPattern8 __m = {
2374 sd->mid_PutMemPattern8,
2375 msg->gc,
2376 msg->pattern,
2377 msg->patternsrcx,
2378 msg->patternsrcy,
2379 msg->patternheight,
2380 msg->patterndepth,
2381 msg->patternlut,
2382 msg->invertpattern,
2383 msg->mask,
2384 msg->maskmodulo,
2385 msg->masksrcx,
2386 (APTR)VideoData,
2387 bm->pitch,
2388 msg->x,
2389 msg->y,
2390 msg->width,
2391 msg->height
2392 }, *m = &__m;
2394 OOP_DoMethod(o, (OOP_Msg)m);
2396 break;
2398 case 2:
2400 struct pHidd_BitMap_PutMemPattern16 __m = {
2401 sd->mid_PutMemPattern16,
2402 msg->gc,
2403 msg->pattern,
2404 msg->patternsrcx,
2405 msg->patternsrcy,
2406 msg->patternheight,
2407 msg->patterndepth,
2408 msg->patternlut,
2409 msg->invertpattern,
2410 msg->mask,
2411 msg->maskmodulo,
2412 msg->masksrcx,
2413 (APTR)VideoData,
2414 bm->pitch,
2415 msg->x,
2416 msg->y,
2417 msg->width,
2418 msg->height
2419 }, *m = &__m;
2421 OOP_DoMethod(o, (OOP_Msg)m);
2423 break;
2425 case 4:
2427 struct pHidd_BitMap_PutMemPattern32 __m = {
2428 sd->mid_PutMemPattern32,
2429 msg->gc,
2430 msg->pattern,
2431 msg->patternsrcx,
2432 msg->patternsrcy,
2433 msg->patternheight,
2434 msg->patterndepth,
2435 msg->patternlut,
2436 msg->invertpattern,
2437 msg->mask,
2438 msg->maskmodulo,
2439 msg->masksrcx,
2440 (APTR)VideoData,
2441 bm->pitch,
2442 msg->x,
2443 msg->y,
2444 msg->width,
2445 msg->height
2446 }, *m = &__m;
2448 OOP_DoMethod(o, (OOP_Msg)m);
2450 break;
2451 } /* switch(bm->bpp) */
2453 UNLOCK_BITMAP