Fixed binary search: no more infinite loops when vendor is unknown.
[tangerine.git] / arch / common / hidd.radeon / ati_bitmap.c
blobcd8bdd4781015f26f857fcefe6ab420e99392153
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) | 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) | msg->dr.minX);
443 OUTREG(RADEON_DST_WIDTH_HEIGHT, ((msg->dr.maxX - msg->dr.minX + 1) << 16) | (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 UWORD 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 RADEONWaitForFifo(sd, 2);
504 OUTREG(RADEON_SC_TOP_LEFT, (y1 << 16) | x1);
505 OUTREG(RADEON_SC_BOTTOM_RIGHT, (y2 << 16) | x2);
508 RADEONWaitForFifo(sd, 3);
510 OUTREG(RADEON_DP_GUI_MASTER_CNTL, bm->dp_gui_master_cntl_clip);
511 OUTREG(RADEON_DP_BRUSH_FRGD_CLR, GC_FG(gc));
512 OUTREG(RADEON_DP_WRITE_MASK, ~0);
514 RADEONWaitForFifo(sd, 4);
516 OUTREG(RADEON_DST_LINE_START, (msg->y1 << 16) | msg->x1);
517 OUTREG(RADEON_DST_LINE_END, (msg->y2 << 16) | msg->x2);
518 OUTREG(RADEON_DST_LINE_START, (msg->y2 << 16) | msg->x2);
519 OUTREG(RADEON_DST_LINE_END, ((msg->y2+1) << 16) | (msg->x2+1));
521 UNLOCK_HW
524 UNLOCK_BITMAP
528 VOID METHOD(ATIOffBM, Hidd_BitMap, DrawRect)
529 __attribute__((alias(METHOD_NAME_S(ATIOnBM, Hidd_BitMap, DrawRect))));
531 VOID METHOD(ATIOnBM, Hidd_BitMap, DrawRect)
533 OOP_Object *gc = msg->gc;
534 atiBitMap *bm = OOP_INST_DATA(cl, o);
535 UWORD addX, addY;
537 D(bug("[ATI] DrawRect(%p, %d:%d - %d:%d)\n",
538 bm->framebuffer, msg->minX, msg->minY, msg->maxX, msg->maxY));
540 if (msg->minX == msg->maxX) addX = 1; else addX = 0;
541 if (msg->minY == msg->maxY) addY = 1; else addY = 0;
543 LOCK_BITMAP
545 if ((GC_LINEPAT(gc) =! (UWORD)~0) || !bm->fbgfx)
547 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
549 else
551 LOCK_HW
552 sd->Card.Busy = TRUE;
553 bm->usecount++;
555 RADEONWaitForFifo(sd, 1);
556 OUTREG(RADEON_DST_PITCH_OFFSET, bm->pitch_offset);
558 bm->dp_gui_master_cntl_clip = (bm->dp_gui_master_cntl
559 | RADEON_GMC_BRUSH_SOLID_COLOR
560 | RADEON_GMC_SRC_DATATYPE_COLOR
561 | RADEON_ROP[GC_DRMD(gc)].pattern);
563 if (sd->Card.Type >= RV200) {
564 RADEONWaitForFifo(sd, 1);
565 OUTREG(RADEON_DST_LINE_PATCOUNT,
566 0x55 << RADEON_BRES_CNTL_SHIFT);
569 if (GC_DOCLIP(gc))
571 bm->dp_gui_master_cntl_clip |= RADEON_GMC_DST_CLIPPING;
572 UWORD x1,y1,x2,y2;
573 x1 = GC_CLIPX1(gc);
574 y1 = GC_CLIPY1(gc);
575 x2 = GC_CLIPX2(gc) + 1;
576 y2 = GC_CLIPY2(gc) + 1;
578 RADEONWaitForFifo(sd, 2);
579 OUTREG(RADEON_SC_TOP_LEFT, (y1 << 16) | x1);
580 OUTREG(RADEON_SC_BOTTOM_RIGHT, (y2 << 16) | x2);
583 RADEONWaitForFifo(sd, 3);
585 OUTREG(RADEON_DP_GUI_MASTER_CNTL, bm->dp_gui_master_cntl_clip);
586 OUTREG(RADEON_DP_BRUSH_FRGD_CLR, GC_FG(gc));
587 OUTREG(RADEON_DP_WRITE_MASK, ~0);
589 RADEONWaitForFifo(sd, 8);
591 OUTREG(RADEON_DST_LINE_START, (msg->minY << 16) | (msg->minX & 0xffff));
592 OUTREG(RADEON_DST_LINE_END, (msg->minY << 16) | (msg->maxX & 0xffff));
594 OUTREG(RADEON_DST_LINE_START, ((msg->minY + addY) << 16) | (msg->maxX & 0xffff));
595 OUTREG(RADEON_DST_LINE_END, ((msg->maxY << 16)) | (msg->maxX & 0xffff));
597 OUTREG(RADEON_DST_LINE_START, ((msg->maxY << 16)) | ((msg->maxX - addX) & 0xffff));
598 OUTREG(RADEON_DST_LINE_END, ((msg->maxY << 16)) | ((msg->minX) & 0xffff));
600 OUTREG(RADEON_DST_LINE_START, ((msg->maxY - addY) << 16) | (msg->minX & 0xffff));
601 OUTREG(RADEON_DST_LINE_END, ((msg->minY + addY) << 16) | (msg->minX & 0xffff));
603 UNLOCK_HW
606 UNLOCK_BITMAP
610 VOID METHOD(ATIOffBM, Hidd_BitMap, DrawPolygon)
611 __attribute__((alias(METHOD_NAME_S(ATIOnBM, Hidd_BitMap, DrawPolygon))));
613 VOID METHOD(ATIOnBM, Hidd_BitMap, DrawPolygon)
615 OOP_Object *gc = msg->gc;
616 atiBitMap *bm = OOP_INST_DATA(cl, o);
617 ULONG i;
619 D(bug("[ATI] DrawPolygon(%p)\n",
620 bm->framebuffer));
622 LOCK_BITMAP
624 if ((GC_LINEPAT(gc) =! (UWORD)~0) || !bm->fbgfx)
626 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
628 else
630 LOCK_HW
631 sd->Card.Busy = TRUE;
632 bm->usecount++;
634 RADEONWaitForFifo(sd, 1);
635 OUTREG(RADEON_DST_PITCH_OFFSET, bm->pitch_offset);
637 bm->dp_gui_master_cntl_clip = (bm->dp_gui_master_cntl
638 | RADEON_GMC_BRUSH_SOLID_COLOR
639 | RADEON_GMC_SRC_DATATYPE_COLOR
640 | RADEON_ROP[GC_DRMD(gc)].pattern);
642 if (sd->Card.Type >= RV200) {
643 RADEONWaitForFifo(sd, 1);
644 OUTREG(RADEON_DST_LINE_PATCOUNT,
645 0x55 << RADEON_BRES_CNTL_SHIFT);
648 if (GC_DOCLIP(gc))
650 bm->dp_gui_master_cntl_clip |= RADEON_GMC_DST_CLIPPING;
651 UWORD x1,y1,x2,y2;
652 x1 = GC_CLIPX1(gc);
653 y1 = GC_CLIPY1(gc);
654 x2 = GC_CLIPX2(gc) + 1;
655 y2 = GC_CLIPY2(gc) + 1;
657 RADEONWaitForFifo(sd, 2);
658 OUTREG(RADEON_SC_TOP_LEFT, (y1 << 16) | x1);
659 OUTREG(RADEON_SC_BOTTOM_RIGHT, (y2 << 16) | x2);
662 RADEONWaitForFifo(sd, 3);
664 OUTREG(RADEON_DP_GUI_MASTER_CNTL, bm->dp_gui_master_cntl_clip);
665 OUTREG(RADEON_DP_BRUSH_FRGD_CLR, GC_FG(gc));
666 OUTREG(RADEON_DP_WRITE_MASK, ~0);
668 for (i = 2; i < (2 * msg->n); i+=2)
670 RADEONWaitForFifo(sd, 2);
671 OUTREG(RADEON_DST_LINE_START, (msg->coords[i-1] << 16) | msg->coords[i-2]);
672 OUTREG(RADEON_DST_LINE_END, (msg->coords[i+1] << 16) | msg->coords[i]);
675 UNLOCK_HW
678 UNLOCK_BITMAP
681 VOID METHOD(ATIOffBM, Hidd_BitMap, PutPixel)
682 __attribute__((alias(METHOD_NAME_S(ATIOnBM, Hidd_BitMap, PutPixel))));
684 VOID METHOD(ATIOnBM, Hidd_BitMap, PutPixel)
686 atiBitMap *bm = OOP_INST_DATA(cl, o);
687 void *ptr = bm->addresses[msg->y];
689 LOCK_BITMAP
691 if (bm->fbgfx)
693 if (sd->Card.Busy)
695 LOCK_HW
696 #warning TODO: NVSync(sd)
697 RADEONWaitForIdleMMIO(sd);
698 UNLOCK_HW
702 switch (bm->bpp)
704 case 1:
705 ((UBYTE *)ptr)[msg->x] = msg->pixel;
706 break;
707 case 2:
708 ((UWORD *)ptr)[msg->x] = msg->pixel;
709 break;
710 case 4:
711 ((ULONG *)ptr)[msg->x] = msg->pixel;
712 break;
715 UNLOCK_BITMAP
718 VOID METHOD(ATIOffBM, Hidd_BitMap, DrawPixel)
719 __attribute__((alias(METHOD_NAME_S(ATIOnBM, Hidd_BitMap, DrawPixel))));
721 VOID METHOD(ATIOnBM, Hidd_BitMap, DrawPixel)
723 atiBitMap *bm = OOP_INST_DATA(cl, o);
724 void *ptr = bm->addresses[msg->y];
725 OOP_Object *gc = msg->gc;
727 HIDDT_Pixel src, dest, val;
728 HIDDT_DrawMode mode;
729 HIDDT_Pixel writeMask;
731 src = GC_FG(gc);
732 mode = GC_DRMD(gc);
734 LOCK_BITMAP
736 if (bm->fbgfx)
738 if (sd->Card.Busy)
740 LOCK_HW
741 #warning TODO: NVSync(sd)
742 RADEONWaitForIdleMMIO(sd);
743 UNLOCK_HW
747 if (vHidd_GC_DrawMode_Copy == mode && GC_COLMASK(gc) == ~0)
749 val = src;
751 else
753 switch (bm->bpp)
755 case 1:
756 dest = ((UBYTE *)ptr)[msg->x];
757 break;
758 case 2:
759 dest = ((UWORD *)ptr)[msg->x];
760 break;
761 case 4:
762 dest = ((ULONG *)ptr)[msg->x];
763 break;
766 writeMask = ~GC_COLMASK(gc) & dest;
768 val = 0;
770 if(mode & 1) val = ( src & dest);
771 if(mode & 2) val = ( src & ~dest) | val;
772 if(mode & 4) val = (~src & dest) | val;
773 if(mode & 8) val = (~src & ~dest) | val;
775 val = (val & (writeMask | GC_COLMASK(gc) )) | writeMask;
778 switch (bm->bpp)
780 case 1:
781 ((UBYTE *)ptr)[msg->x] = val;
782 break;
783 case 2:
784 ((UWORD *)ptr)[msg->x] = val;
785 break;
786 case 4:
787 ((ULONG *)ptr)[msg->x] = val;
788 break;
791 UNLOCK_BITMAP
794 VOID METHOD(ATIOffBM, Hidd_BitMap, DrawEllipse)
795 __attribute__((alias(METHOD_NAME_S(ATIOnBM, Hidd_BitMap, DrawEllipse))));
797 VOID METHOD(ATIOnBM, Hidd_BitMap, DrawEllipse)
799 atiBitMap *bm = OOP_INST_DATA(cl, o);
800 OOP_Object *gc = msg->gc;
801 WORD x = msg->rx, y = 0; /* ellipse points */
802 HIDDT_Pixel src;
803 HIDDT_DrawMode mode;
804 HIDDT_Pixel writeMask;
806 /* intermediate terms to speed up loop */
807 LONG t1 = msg->rx * msg->rx, t2 = t1 << 1, t3 = t2 << 1;
808 LONG t4 = msg->ry * msg->ry, t5 = t4 << 1, t6 = t5 << 1;
809 LONG t7 = msg->rx * t5, t8 = t7 << 1, t9 = 0L;
810 LONG d1 = t2 - t7 + (t4 >> 1); /* error terms */
811 LONG d2 = (t1 >> 1) - t8 + t5;
813 BOOL doclip = GC_DOCLIP(gc);
815 src = GC_FG(gc);
816 mode = GC_DRMD(gc);
818 void _drawpixel(int x, int y)
820 void *ptr = bm->addresses[y];
821 HIDDT_Pixel val, dest;
823 if (vHidd_GC_DrawMode_Copy == mode && GC_COLMASK(gc) == ~0)
825 val = src;
827 else
829 switch (bm->bpp)
831 case 1:
832 dest = ((UBYTE *)ptr)[x];
833 break;
834 case 2:
835 dest = ((UWORD *)ptr)[x];
836 break;
837 case 4:
838 dest = ((ULONG *)ptr)[x];
839 break;
842 writeMask = ~GC_COLMASK(gc) & dest;
844 val = 0;
846 if(mode & 1) val = ( src & dest);
847 if(mode & 2) val = ( src & ~dest) | val;
848 if(mode & 4) val = (~src & dest) | val;
849 if(mode & 8) val = (~src & ~dest) | val;
851 val = (val & (writeMask | GC_COLMASK(gc) )) | writeMask;
854 switch (bm->bpp)
856 case 1:
857 ((UBYTE *)ptr)[x] = val;
858 break;
859 case 2:
860 ((UWORD *)ptr)[x] = val;
861 break;
862 case 4:
863 ((ULONG *)ptr)[x] = val;
864 break;
868 LOCK_BITMAP
870 UBYTE *ptr = (UBYTE*)((IPTR)bm->framebuffer);
871 if (bm->fbgfx)
873 ptr += (IPTR)sd->Card.FrameBuffer;
874 if (sd->Card.Busy)
876 LOCK_HW
877 #warning TODO: NVSync(sd)
878 RADEONWaitForIdleMMIO(sd);
879 UNLOCK_HW
883 while (d2 < 0) /* til slope = -1 */
885 /* draw 4 points using symmetry */
887 if (doclip)
889 if (!POINT_OUTSIDE_CLIP(gc, msg->x + x, msg->y + y))
890 _drawpixel(msg->x + x, msg->y + y);
892 if (!POINT_OUTSIDE_CLIP(gc, msg->x + x, msg->y - y))
893 _drawpixel(msg->x + x, msg->y - y);
895 if (!POINT_OUTSIDE_CLIP(gc, msg->x - x, msg->y + y))
896 _drawpixel(msg->x - x, msg->y + y);
898 if (!POINT_OUTSIDE_CLIP(gc, msg->x - x, msg->y - y))
899 _drawpixel(msg->x - x, msg->y - y);
901 else
903 _drawpixel(msg->x + x, msg->y + y);
904 _drawpixel(msg->x + x, msg->y - y);
905 _drawpixel(msg->x - x, msg->y + y);
906 _drawpixel(msg->x - x, msg->y - y);
909 y++; /* always move up here */
910 t9 = t9 + t3;
911 if (d1 < 0) /* move straight up */
913 d1 = d1 + t9 + t2;
914 d2 = d2 + t9;
916 else /* move up and left */
918 x--;
919 t8 = t8 - t6;
920 d1 = d1 + t9 + t2 - t8;
921 d2 = d2 + t9 + t5 - t8;
925 do /* rest of top right quadrant */
927 /* draw 4 points using symmetry */
928 if (doclip)
930 if (!POINT_OUTSIDE_CLIP(gc, msg->x + x, msg->y + y))
931 _drawpixel(msg->x + x, msg->y + y);
933 if (!POINT_OUTSIDE_CLIP(gc, msg->x + x, msg->y - y))
934 _drawpixel(msg->x + x, msg->y - y);
936 if (!POINT_OUTSIDE_CLIP(gc, msg->x - x, msg->y + y))
937 _drawpixel(msg->x - x, msg->y + y);
939 if (!POINT_OUTSIDE_CLIP(gc, msg->x - x, msg->y - y))
940 _drawpixel(msg->x - x, msg->y - y);
942 else
944 _drawpixel(msg->x + x, msg->y + y);
945 _drawpixel(msg->x + x, msg->y - y);
946 _drawpixel(msg->x - x, msg->y + y);
947 _drawpixel(msg->x - x, msg->y - y);
950 x--; /* always move left here */
951 t8 = t8 - t6;
952 if (d2 < 0) /* move up and left */
954 y++;
955 t9 = t9 + t3;
956 d2 = d2 + t9 + t5 - t8;
958 else /* move straight left */
960 d2 = d2 + t5 - t8;
963 } while (x >= 0);
966 UNLOCK_BITMAP
969 HIDDT_Pixel METHOD(ATIOffBM, Hidd_BitMap, GetPixel)
970 __attribute__((alias(METHOD_NAME_S(ATIOnBM, Hidd_BitMap, GetPixel))));
972 HIDDT_Pixel METHOD(ATIOnBM, Hidd_BitMap, GetPixel)
974 HIDDT_Pixel pixel=0;
975 atiBitMap *bm = OOP_INST_DATA(cl, o);
977 LOCK_BITMAP
979 void *ptr = bm->addresses[msg->y];
981 if (bm->fbgfx)
983 if (sd->Card.Busy)
985 LOCK_HW
986 #warning TODO: NVSync(sd)
987 RADEONWaitForIdleMMIO(sd);
988 UNLOCK_HW
992 switch (bm->bpp)
994 case 1:
995 pixel = ((UBYTE *)ptr)[msg->x];
996 break;
997 case 2:
998 pixel = ((UWORD *)ptr)[msg->x];
999 break;
1000 case 4:
1001 pixel = ((ULONG *)ptr)[msg->x];
1002 break;
1005 UNLOCK_BITMAP
1007 /* Get pen number from colortab */
1008 return pixel;
1012 void METHOD(ATIOffBM, Hidd_BitMap, BlitColorExpansion)
1013 __attribute__((alias(METHOD_NAME_S(ATIOnBM, Hidd_BitMap, BlitColorExpansion))));
1015 void METHOD(ATIOnBM, Hidd_BitMap, BlitColorExpansion)
1017 atiBitMap *bm = OOP_INST_DATA(cl, o);
1019 LOCK_BITMAP
1021 if ((OOP_OCLASS(msg->srcBitMap) == sd->PlanarBMClass) && bm->fbgfx)
1023 struct planarbm_data *planar = OOP_INST_DATA(OOP_OCLASS(msg->srcBitMap), msg->srcBitMap);
1024 HIDDT_Pixel bg, fg;
1025 ULONG cemd;
1026 ULONG skipleft = msg->srcX - (msg->srcX & ~31);
1027 ULONG mask = ~0 << bm->depth;
1029 cemd = GC_COLEXP(msg->gc);
1030 bg = GC_BG(msg->gc) | mask;
1031 fg = GC_FG(msg->gc) | mask;
1033 ULONG bw = (msg->width + 31 + skipleft) & ~31;
1034 LONG x = msg->destX, y = msg->destY, w = msg->width, h = msg->height;
1036 LOCK_HW
1038 bm->usecount++;
1039 sd->Card.Busy = TRUE;
1041 RADEONWaitForFifo(sd, 1);
1042 OUTREG(RADEON_DST_PITCH_OFFSET, bm->pitch_offset);
1044 bm->dp_gui_master_cntl_clip = (bm->dp_gui_master_cntl
1045 | RADEON_GMC_WR_MSK_DIS
1046 | RADEON_GMC_BRUSH_NONE
1047 | RADEON_DP_SRC_SOURCE_HOST_DATA
1048 | RADEON_GMC_DST_CLIPPING
1049 | RADEON_GMC_BYTE_MSB_TO_LSB
1050 | RADEON_ROP[vHidd_GC_DrawMode_Copy].rop);
1052 if (cemd & vHidd_GC_ColExp_Transparent)
1054 bm->dp_gui_master_cntl_clip |= RADEON_GMC_SRC_DATATYPE_MONO_FG_LA;
1056 RADEONWaitForFifo(sd, 6);
1057 OUTREG(RADEON_DP_GUI_MASTER_CNTL, bm->dp_gui_master_cntl_clip);
1058 OUTREG(RADEON_DP_SRC_FRGD_CLR, fg);
1060 else
1062 bm->dp_gui_master_cntl_clip |= RADEON_GMC_SRC_DATATYPE_MONO_FG_BG;
1064 RADEONWaitForFifo(sd, 7);
1065 OUTREG(RADEON_DP_GUI_MASTER_CNTL, bm->dp_gui_master_cntl_clip);
1066 OUTREG(RADEON_DP_SRC_FRGD_CLR, fg);
1067 OUTREG(RADEON_DP_SRC_BKGD_CLR, bg);
1070 OUTREG(RADEON_SC_TOP_LEFT, (y << 16) | x);
1071 OUTREG(RADEON_SC_BOTTOM_RIGHT, ((y+h) << 16) | (x+w));
1073 OUTREG(RADEON_DST_X_Y, ((x - skipleft) << 16) | y);
1074 OUTREG(RADEON_DST_WIDTH_HEIGHT, (bw << 16) | h);
1076 ULONG *ptr = (ULONG*)planar->planes[0];
1077 ptr += ((msg->srcY * planar->bytesperrow) >> 2) + (msg->srcX >> 5);
1079 #if AROS_BIG_ENDIAN
1080 RADEONWaitForFifo(sd, 1);
1081 OUTREG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_32BIT);
1082 #endif
1084 while(h--)
1086 int i;
1088 for (i=0; i < bw >> 5; i++)
1090 RADEONWaitForFifo(sd, 1);
1091 OUTREG(RADEON_HOST_DATA0, ptr[i]);
1094 ptr += planar->bytesperrow >> 2;
1097 #if AROS_BIG_ENDIAN
1098 RADEONWaitForFifo(sd, 1);
1099 OUTREG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_NONE);
1100 #endif
1102 UNLOCK_HW
1105 else
1106 OOP_DoSuperMethod(cl, o, msg);
1108 UNLOCK_BITMAP
1112 ULONG METHOD(ATIOffBM, Hidd_BitMap, BytesPerLine)
1113 __attribute__((alias(METHOD_NAME_S(ATIOnBM, Hidd_BitMap, BytesPerLine))));
1115 ULONG METHOD(ATIOnBM, Hidd_BitMap, BytesPerLine)
1117 atiBitMap *bm = OOP_INST_DATA(cl, o);
1119 return (bm->bpp * msg->width + 255) & ~255;
1123 BOOL METHOD(ATIOffBM, Hidd_BitMap, ObtainDirectAccess)
1124 __attribute__((alias(METHOD_NAME_S(ATIOnBM, Hidd_BitMap, ObtainDirectAccess))));
1126 BOOL METHOD(ATIOnBM, Hidd_BitMap, ObtainDirectAccess)
1128 atiBitMap *bm = OOP_INST_DATA(cl, o);
1129 LOCK_BITMAP
1131 IPTR VideoData = bm->framebuffer;
1133 if (bm->fbgfx)
1135 VideoData += (IPTR)sd->Card.FrameBuffer;
1136 if (sd->Card.Busy)
1138 LOCK_HW
1139 #warning TODO: NVSync(sd)
1140 RADEONWaitForIdleMMIO(sd);
1141 UNLOCK_HW
1145 *msg->addressReturn = (UBYTE*)VideoData;
1146 *msg->widthReturn = bm->pitch / bm->bpp;
1147 *msg->heightReturn = bm->height;
1148 *msg->bankSizeReturn = *msg->memSizeReturn = bm->pitch * bm->height;
1150 return TRUE;
1153 VOID METHOD(ATIOffBM, Hidd_BitMap, ReleaseDirectAccess)
1154 __attribute__((alias(METHOD_NAME_S(ATIOnBM, Hidd_BitMap, ReleaseDirectAccess))));
1156 VOID METHOD(ATIOnBM, Hidd_BitMap, ReleaseDirectAccess)
1158 atiBitMap *bm = OOP_INST_DATA(cl, o);
1160 UNLOCK_BITMAP
1165 * Unaccelerated methods
1168 VOID METHOD(ATIOffBM, Hidd_BitMap, PutImageLUT)
1169 __attribute__((alias(METHOD_NAME_S(ATIOnBM, Hidd_BitMap, PutImageLUT))));
1171 VOID METHOD(ATIOnBM, Hidd_BitMap, PutImageLUT)
1173 atiBitMap *bm = OOP_INST_DATA(cl, o);
1175 // bug("[ATI] PutImageLUT(%d, %d, %d, %d, %d, %p)\n", msg->x, msg->y, msg->width, msg->height, msg->modulo, msg->pixels);
1177 LOCK_BITMAP
1181 // IPTR VideoData = bm->framebuffer;
1183 if (bm->fbgfx)
1186 UBYTE *src = msg->pixels;
1187 ULONG x_add = msg->modulo;
1188 UWORD height = msg->height;
1189 UWORD bw = msg->width;
1190 HIDDT_Pixel *colmap = msg->pixlut->pixels;
1192 if (bm->bpp == 2)
1193 bw = (bw + 1) & ~1;
1195 LOCK_HW
1197 bm->usecount++;
1198 sd->Card.Busy = TRUE;
1200 RADEONWaitForFifo(sd, 1);
1201 OUTREG(RADEON_DST_PITCH_OFFSET, bm->pitch_offset);
1203 bm->dp_gui_master_cntl_clip = (bm->dp_gui_master_cntl
1204 | RADEON_GMC_WR_MSK_DIS
1205 | RADEON_GMC_BRUSH_NONE
1206 | RADEON_DP_SRC_SOURCE_HOST_DATA
1207 | RADEON_GMC_DST_CLIPPING
1208 | RADEON_GMC_SRC_DATATYPE_COLOR
1209 | RADEON_ROP[vHidd_GC_DrawMode_Copy].rop);
1211 RADEONWaitForFifo(sd, 5);
1212 OUTREG(RADEON_DP_GUI_MASTER_CNTL, bm->dp_gui_master_cntl_clip);
1214 OUTREG(RADEON_SC_TOP_LEFT, (msg->y << 16) | msg->x);
1215 OUTREG(RADEON_SC_BOTTOM_RIGHT, ((msg->y+msg->height) << 16) | (msg->x+msg->width));
1217 OUTREG(RADEON_DST_X_Y, ((msg->x) << 16) | msg->y);
1218 OUTREG(RADEON_DST_WIDTH_HEIGHT, (bw << 16) | msg->height);
1220 if (bm->bpp == 4)
1222 #if AROS_BIG_ENDIAN
1223 RADEONWaitForFifo(sd, 1);
1224 OUTREG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_32BIT);
1225 #endif
1226 while (height--)
1228 UBYTE *line = (UBYTE*)src;
1229 ULONG width = msg->width;
1231 while(width)
1233 if (width <= 8)
1235 RADEONWaitForFifo(sd, width);
1236 switch (width)
1238 case 8: OUTREGN(RADEON_HOST_DATA0, colmap[*line++]);
1239 case 7: OUTREGN(RADEON_HOST_DATA1, colmap[*line++]);
1240 case 6: OUTREGN(RADEON_HOST_DATA2, colmap[*line++]);
1241 case 5: OUTREGN(RADEON_HOST_DATA3, colmap[*line++]);
1242 case 4: OUTREGN(RADEON_HOST_DATA4, colmap[*line++]);
1243 case 3: OUTREGN(RADEON_HOST_DATA5, colmap[*line++]);
1244 case 2: OUTREGN(RADEON_HOST_DATA6, colmap[*line++]);
1245 case 1: OUTREGN(RADEON_HOST_DATA7, colmap[*line++]);
1247 width = 0;
1249 else
1251 RADEONWaitForFifo(sd, 8);
1253 OUTREGN(RADEON_HOST_DATA0, colmap[*line++]);
1254 OUTREGN(RADEON_HOST_DATA1, colmap[*line++]);
1255 OUTREGN(RADEON_HOST_DATA2, colmap[*line++]);
1256 OUTREGN(RADEON_HOST_DATA3, colmap[*line++]);
1257 OUTREGN(RADEON_HOST_DATA4, colmap[*line++]);
1258 OUTREGN(RADEON_HOST_DATA5, colmap[*line++]);
1259 OUTREGN(RADEON_HOST_DATA6, colmap[*line++]);
1260 OUTREGN(RADEON_HOST_DATA7, colmap[*line++]);
1262 width -= 8;
1266 src += x_add;
1269 else if (bm->bpp == 2)
1271 #if AROS_BIG_ENDIAN
1272 RADEONWaitForFifo(sd, 1);
1273 OUTREG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_HDW);
1274 #endif
1275 while (height--)
1277 UBYTE *line = (UBYTE*)src;
1278 ULONG width = bw >> 1;
1280 while(width--)
1282 ULONG tmp = (colmap[line[0]] << 16) | (colmap[line[1]] & 0x0000ffff);
1283 RADEONWaitForFifo(sd, 1);
1284 OUTREG(RADEON_HOST_DATA0, tmp);
1285 line+=2;
1288 src += x_add;
1293 #if AROS_BIG_ENDIAN
1294 RADEONWaitForFifo(sd, 1);
1295 OUTREG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_NONE);
1296 #endif
1298 UNLOCK_HW
1300 // VideoData += (IPTR)sd->Card.FrameBuffer;
1302 // if (sd->Card.Busy)
1303 // {
1304 // LOCK_HW
1305 //#warning TODO: NVSync(sd)
1306 // RADEONWaitForIdleMMIO(sd);
1307 // UNLOCK_HW
1308 // }
1309 // }
1311 // switch(bm->bpp)
1312 // {
1313 // case 2:
1314 // {
1315 // struct pHidd_BitMap_CopyLUTMemBox16 __m = {
1316 // sd->mid_CopyLUTMemBox16,
1317 // msg->pixels,
1318 // 0,
1319 // 0,
1320 // (APTR)VideoData,
1321 // msg->x,
1322 // msg->y,
1323 // msg->width,
1324 // msg->height,
1325 // msg->modulo,
1326 // bm->pitch,
1327 // msg->pixlut
1328 // }, *m = &__m;
1330 // OOP_DoMethod(o, (OOP_Msg)m);
1331 // }
1332 // break;
1334 // case 4:
1335 // {
1336 // struct pHidd_BitMap_CopyLUTMemBox32 __m = {
1337 // sd->mid_CopyLUTMemBox32,
1338 // msg->pixels,
1339 // 0,
1340 // 0,
1341 // (APTR)VideoData,
1342 // msg->x,
1343 // msg->y,
1344 // msg->width,
1345 // msg->height,
1346 // msg->modulo,
1347 // bm->pitch,
1348 // msg->pixlut
1349 // }, *m = &__m;
1351 // OOP_DoMethod(o, (OOP_Msg)m);
1352 // }
1353 // break;
1355 // default:
1356 // OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
1357 // break;
1360 else
1361 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
1363 UNLOCK_BITMAP
1367 VOID METHOD(ATIOffBM, Hidd_BitMap, PutImage)
1368 __attribute__((alias(METHOD_NAME_S(ATIOnBM, Hidd_BitMap, PutImage))));
1370 VOID METHOD(ATIOnBM, Hidd_BitMap, PutImage)
1372 atiBitMap *bm = OOP_INST_DATA(cl, o);
1373 BOOL done = FALSE;
1375 LOCK_BITMAP
1377 IPTR VideoData = bm->framebuffer;
1379 /* Try to PutImage with 2D engine first */
1380 if (bm->fbgfx)
1382 UBYTE *src = msg->pixels;
1383 ULONG x_add = msg->modulo;
1384 UWORD height = msg->height;
1385 UWORD bw = msg->width;
1387 if (bm->bpp == 2)
1388 bw = (bw + 1) & ~1;
1390 done = TRUE;
1392 if (done)
1394 LOCK_HW
1396 bm->usecount++;
1397 sd->Card.Busy = TRUE;
1399 RADEONWaitForFifo(sd, 1);
1400 OUTREG(RADEON_DST_PITCH_OFFSET, bm->pitch_offset);
1402 bm->dp_gui_master_cntl_clip = (bm->dp_gui_master_cntl
1403 | RADEON_GMC_WR_MSK_DIS
1404 | RADEON_GMC_BRUSH_NONE
1405 | RADEON_DP_SRC_SOURCE_HOST_DATA
1406 | RADEON_GMC_DST_CLIPPING
1407 | RADEON_GMC_SRC_DATATYPE_COLOR
1408 | RADEON_ROP[vHidd_GC_DrawMode_Copy].rop);
1410 RADEONWaitForFifo(sd, 5);
1411 OUTREG(RADEON_DP_GUI_MASTER_CNTL, bm->dp_gui_master_cntl_clip);
1413 OUTREG(RADEON_SC_TOP_LEFT, (msg->y << 16) | msg->x);
1414 OUTREG(RADEON_SC_BOTTOM_RIGHT, ((msg->y+msg->height) << 16) | (msg->x+msg->width));
1416 OUTREG(RADEON_DST_X_Y, ((msg->x) << 16) | msg->y);
1417 OUTREG(RADEON_DST_WIDTH_HEIGHT, (bw << 16) | msg->height);
1419 switch (msg->pixFmt)
1421 case vHidd_StdPixFmt_Native32:
1422 case vHidd_StdPixFmt_Native:
1423 if (bm->bpp == 4)
1425 #if AROS_BIG_ENDIAN
1426 RADEONWaitForFifo(sd, 1);
1427 OUTREG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_32BIT);
1428 #endif
1429 while (height--)
1431 ULONG *line = (ULONG*)src;
1432 ULONG width = msg->width;
1434 while(width)
1436 if (width <= 8)
1438 RADEONWaitForFifo(sd, width);
1439 switch (width)
1441 case 8: OUTREGN(RADEON_HOST_DATA0, *line++);
1442 case 7: OUTREGN(RADEON_HOST_DATA1, *line++);
1443 case 6: OUTREGN(RADEON_HOST_DATA2, *line++);
1444 case 5: OUTREGN(RADEON_HOST_DATA3, *line++);
1445 case 4: OUTREGN(RADEON_HOST_DATA4, *line++);
1446 case 3: OUTREGN(RADEON_HOST_DATA5, *line++);
1447 case 2: OUTREGN(RADEON_HOST_DATA6, *line++);
1448 case 1: OUTREGN(RADEON_HOST_DATA7, *line++);
1450 width = 0;
1452 else
1454 RADEONWaitForFifo(sd, 8);
1456 OUTREGN(RADEON_HOST_DATA0, *line++);
1457 OUTREGN(RADEON_HOST_DATA1, *line++);
1458 OUTREGN(RADEON_HOST_DATA2, *line++);
1459 OUTREGN(RADEON_HOST_DATA3, *line++);
1460 OUTREGN(RADEON_HOST_DATA4, *line++);
1461 OUTREGN(RADEON_HOST_DATA5, *line++);
1462 OUTREGN(RADEON_HOST_DATA6, *line++);
1463 OUTREGN(RADEON_HOST_DATA7, *line++);
1465 width -= 8;
1469 src += x_add;
1471 #if AROS_BIG_ENDIAN
1472 RADEONWaitForFifo(sd, 1);
1473 OUTREG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_NONE);
1474 #endif
1477 else if (bm->bpp == 2)
1479 #if AROS_BIG_ENDIAN
1480 RADEONWaitForFifo(sd, 1);
1481 OUTREG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_HDW);
1482 #endif
1483 if (msg->pixFmt == vHidd_StdPixFmt_Native)
1485 while (height--)
1487 ULONG *line = (ULONG*)src;
1488 ULONG width = bw >> 1;
1490 while(width--)
1492 RADEONWaitForFifo(sd, 1);
1493 OUTREG(RADEON_HOST_DATA0, *line++);
1496 src += x_add;
1499 else
1501 while (height--)
1503 ULONG *line = (ULONG*)src;
1504 ULONG width = bw >> 1;
1506 while(width--)
1508 ULONG tmp = (line[0] << 16) | (line[1] & 0x0000ffff);
1509 RADEONWaitForFifo(sd, 1);
1510 OUTREG(RADEON_HOST_DATA0, tmp);
1511 line+=2;
1514 src += x_add;
1519 #if AROS_BIG_ENDIAN
1520 RADEONWaitForFifo(sd, 1);
1521 OUTREG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_NONE);
1522 #endif
1524 break;
1526 default:
1528 OOP_Object *dstpf;
1529 OOP_Object *srcpf;
1531 srcpf = HIDD_Gfx_GetPixFmt(sd->AtiObject, msg->pixFmt);
1532 OOP_GetAttr(o, aHidd_BitMap_PixFmt, (APTR)&dstpf);
1534 if (bm->bpp == 4)
1536 #if AROS_BIG_ENDIAN
1537 RADEONWaitForFifo(sd, 1);
1538 OUTREG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_32BIT);
1539 #endif
1540 while(height--)
1542 ULONG *line = (ULONG*)sd->cpuscratch;
1543 ULONG width = bw;
1544 APTR _src = src;
1546 HIDD_BM_ConvertPixels(o, &_src, srcpf, msg->modulo, &line, dstpf, msg->modulo, msg->width, 1, NULL);
1548 line = (ULONG*)sd->cpuscratch;
1550 while(width)
1552 if (width <= 8)
1554 RADEONWaitForFifo(sd, width);
1555 switch (width)
1557 case 8: OUTREGN(RADEON_HOST_DATA0, *line++);
1558 case 7: OUTREGN(RADEON_HOST_DATA1, *line++);
1559 case 6: OUTREGN(RADEON_HOST_DATA2, *line++);
1560 case 5: OUTREGN(RADEON_HOST_DATA3, *line++);
1561 case 4: OUTREGN(RADEON_HOST_DATA4, *line++);
1562 case 3: OUTREGN(RADEON_HOST_DATA5, *line++);
1563 case 2: OUTREGN(RADEON_HOST_DATA6, *line++);
1564 case 1: OUTREGN(RADEON_HOST_DATA7, *line++);
1566 width = 0;
1568 else
1570 RADEONWaitForFifo(sd, 8);
1572 OUTREGN(RADEON_HOST_DATA0, *line++);
1573 OUTREGN(RADEON_HOST_DATA1, *line++);
1574 OUTREGN(RADEON_HOST_DATA2, *line++);
1575 OUTREGN(RADEON_HOST_DATA3, *line++);
1576 OUTREGN(RADEON_HOST_DATA4, *line++);
1577 OUTREGN(RADEON_HOST_DATA5, *line++);
1578 OUTREGN(RADEON_HOST_DATA6, *line++);
1579 OUTREGN(RADEON_HOST_DATA7, *line++);
1581 width -= 8;
1585 src += x_add;
1587 #if AROS_BIG_ENDIAN
1588 RADEONWaitForFifo(sd, 1);
1589 OUTREG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_NONE);
1590 #endif
1593 else if (bm->bpp == 2)
1595 #if AROS_BIG_ENDIAN
1596 RADEONWaitForFifo(sd, 1);
1597 OUTREG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_HDW);
1598 #endif
1600 while(height--)
1602 ULONG *line = (ULONG*)sd->cpuscratch;
1603 ULONG width = bw;
1604 APTR _src = src;
1606 HIDD_BM_ConvertPixels(o, &_src, srcpf, msg->modulo, &line, dstpf, msg->modulo, msg->width, 1, NULL);
1608 line = (ULONG*)sd->cpuscratch;
1610 while(width)
1612 if (width <= 16)
1614 RADEONWaitForFifo(sd, width >> 1);
1615 switch (width)
1617 case 16: OUTREG(RADEON_HOST_DATA0, *line++);
1618 case 14: OUTREG(RADEON_HOST_DATA1, *line++);
1619 case 12: OUTREG(RADEON_HOST_DATA2, *line++);
1620 case 10: OUTREG(RADEON_HOST_DATA3, *line++);
1621 case 8: OUTREG(RADEON_HOST_DATA4, *line++);
1622 case 6: OUTREG(RADEON_HOST_DATA5, *line++);
1623 case 4: OUTREG(RADEON_HOST_DATA6, *line++);
1624 case 2: OUTREG(RADEON_HOST_DATA7, *line++);
1626 width = 0;
1628 else
1630 RADEONWaitForFifo(sd, 8);
1632 OUTREG(RADEON_HOST_DATA0, *line++);
1633 OUTREG(RADEON_HOST_DATA1, *line++);
1634 OUTREG(RADEON_HOST_DATA2, *line++);
1635 OUTREG(RADEON_HOST_DATA3, *line++);
1636 OUTREG(RADEON_HOST_DATA4, *line++);
1637 OUTREG(RADEON_HOST_DATA5, *line++);
1638 OUTREG(RADEON_HOST_DATA6, *line++);
1639 OUTREG(RADEON_HOST_DATA7, *line++);
1641 width -= 16;
1645 src += x_add;
1648 #if AROS_BIG_ENDIAN
1649 RADEONWaitForFifo(sd, 1);
1650 OUTREG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_NONE);
1651 #endif
1656 UNLOCK_HW
1660 if (!done)
1662 // bug("[ATI] PutImage x=%d y=%d w=%d h=%d bpp=%d fmt=%d\n", msg->x, msg->y, msg->width, msg->height, bm->bpp, msg->pixFmt);
1665 if (bm->fbgfx)
1667 VideoData += (IPTR)sd->Card.FrameBuffer;
1669 if (sd->Card.Busy)
1671 LOCK_HW
1672 #warning TODO: NVSync(sd)
1673 RADEONWaitForIdleMMIO(sd);
1674 UNLOCK_HW
1678 switch(msg->pixFmt)
1680 case vHidd_StdPixFmt_Native:
1681 switch(bm->bpp)
1683 case 1:
1685 struct pHidd_BitMap_CopyMemBox8 __m = {
1686 sd->mid_CopyMemBox8,
1687 msg->pixels,
1690 (APTR)VideoData,
1691 msg->x,
1692 msg->y,
1693 msg->width,
1694 msg->height,
1695 msg->modulo,
1696 bm->pitch
1697 }, *m = &__m;
1699 OOP_DoMethod(o, (OOP_Msg)m);
1701 break;
1703 case 2:
1705 struct pHidd_BitMap_CopyMemBox16 __m = {
1706 sd->mid_CopyMemBox16,
1707 msg->pixels,
1710 (APTR)VideoData,
1711 msg->x,
1712 msg->y,
1713 msg->width,
1714 msg->height,
1715 msg->modulo,
1716 bm->pitch
1717 }, *m = &__m;
1719 OOP_DoMethod(o, (OOP_Msg)m);
1721 break;
1723 case 4:
1725 struct pHidd_BitMap_CopyMemBox32 __m = {
1726 sd->mid_CopyMemBox32,
1727 msg->pixels,
1730 (APTR)VideoData,
1731 msg->x,
1732 msg->y,
1733 msg->width,
1734 msg->height,
1735 msg->modulo,
1736 bm->pitch
1737 }, *m = &__m;
1739 OOP_DoMethod(o, (OOP_Msg)m);
1741 break;
1743 } /* switch(data->bytesperpix) */
1744 break;
1746 case vHidd_StdPixFmt_Native32:
1747 switch(bm->bpp)
1749 case 1:
1751 struct pHidd_BitMap_PutMem32Image8 __m = {
1752 sd->mid_PutMem32Image8,
1753 msg->pixels,
1754 (APTR)VideoData,
1755 msg->x,
1756 msg->y,
1757 msg->width,
1758 msg->height,
1759 msg->modulo,
1760 bm->pitch
1761 }, *m = &__m;
1762 OOP_DoMethod(o, (OOP_Msg)m);
1764 break;
1766 case 2:
1768 struct pHidd_BitMap_PutMem32Image16 __m = {
1769 sd->mid_PutMem32Image16,
1770 msg->pixels,
1771 (APTR)VideoData,
1772 msg->x,
1773 msg->y,
1774 msg->width,
1775 msg->height,
1776 msg->modulo,
1777 bm->pitch
1778 }, *m = &__m;
1779 OOP_DoMethod(o, (OOP_Msg)m);
1781 break;
1783 case 4:
1785 struct pHidd_BitMap_CopyMemBox32 __m = {
1786 sd->mid_CopyMemBox32,
1787 msg->pixels,
1790 (APTR)VideoData,
1791 msg->x,
1792 msg->y,
1793 msg->width,
1794 msg->height,
1795 msg->modulo,
1796 bm->pitch
1797 }, *m = &__m;
1799 OOP_DoMethod(o, (OOP_Msg)m);
1801 break;
1803 } /* switch(data->bytesperpix) */
1804 break;
1806 default:
1807 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
1808 break;
1809 } /* switch(msg->pixFmt) */
1812 UNLOCK_BITMAP
1815 VOID METHOD(ATIOffBM, Hidd_BitMap, GetImage)
1816 __attribute__((alias(METHOD_NAME_S(ATIOnBM, Hidd_BitMap, GetImage))));
1818 VOID METHOD(ATIOnBM, Hidd_BitMap, GetImage)
1820 atiBitMap *bm = OOP_INST_DATA(cl, o);
1822 LOCK_BITMAP
1824 IPTR VideoData = bm->framebuffer;
1826 if (bm->fbgfx)
1828 VideoData += (IPTR)sd->Card.FrameBuffer;
1829 if (sd->Card.Busy)
1831 LOCK_HW
1832 #warning TODO: NVSync(sd)
1833 RADEONWaitForIdleMMIO(sd);
1834 UNLOCK_HW
1838 switch(msg->pixFmt)
1840 case vHidd_StdPixFmt_Native:
1841 switch(bm->bpp)
1843 case 1:
1845 struct pHidd_BitMap_CopyMemBox8 __m = {
1846 sd->mid_CopyMemBox8,
1847 (APTR)VideoData,
1848 msg->x,
1849 msg->y,
1850 msg->pixels,
1853 msg->width,
1854 msg->height,
1855 bm->pitch,
1856 msg->modulo
1857 }, *m = &__m;
1859 OOP_DoMethod(o, (OOP_Msg)m);
1861 break;
1863 case 2:
1865 struct pHidd_BitMap_CopyMemBox16 __m = {
1866 sd->mid_CopyMemBox16,
1867 (APTR)VideoData,
1868 msg->x,
1869 msg->y,
1870 msg->pixels,
1873 msg->width,
1874 msg->height,
1875 bm->pitch,
1876 msg->modulo
1877 }, *m = &__m;
1879 OOP_DoMethod(o, (OOP_Msg)m);
1881 break;
1883 case 4:
1885 struct pHidd_BitMap_CopyMemBox32 __m = {
1886 sd->mid_CopyMemBox32,
1887 (APTR)VideoData,
1888 msg->x,
1889 msg->y,
1890 msg->pixels,
1893 msg->width,
1894 msg->height,
1895 bm->pitch,
1896 msg->modulo
1897 }, *m = &__m;
1899 OOP_DoMethod(o, (OOP_Msg)m);
1901 break;
1903 } /* switch(data->bytesperpix) */
1904 break;
1906 case vHidd_StdPixFmt_Native32:
1907 switch(bm->bpp)
1909 case 1:
1911 struct pHidd_BitMap_GetMem32Image8 __m = {
1912 sd->mid_GetMem32Image8,
1913 (APTR)VideoData,
1914 msg->x,
1915 msg->y,
1916 msg->pixels,
1917 msg->width,
1918 msg->height,
1919 bm->pitch,
1920 msg->modulo
1921 }, *m = &__m;
1923 OOP_DoMethod(o, (OOP_Msg)m);
1925 break;
1927 case 2:
1929 struct pHidd_BitMap_GetMem32Image16 __m = {
1930 sd->mid_GetMem32Image16,
1931 (APTR)VideoData,
1932 msg->x,
1933 msg->y,
1934 msg->pixels,
1935 msg->width,
1936 msg->height,
1937 bm->pitch,
1938 msg->modulo
1939 }, *m = &__m;
1941 OOP_DoMethod(o, (OOP_Msg)m);
1943 break;
1945 case 4:
1947 struct pHidd_BitMap_CopyMemBox32 __m = {
1948 sd->mid_CopyMemBox32,
1949 (APTR)VideoData,
1950 msg->x,
1951 msg->y,
1952 msg->pixels,
1955 msg->width,
1956 msg->height,
1957 bm->pitch,
1958 msg->modulo
1959 }, *m = &__m;
1961 OOP_DoMethod(o, (OOP_Msg)m);
1963 break;
1965 } /* switch(data->bytesperpix) */
1966 break;
1968 default:
1969 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
1970 break;
1972 } /* switch(msg->pixFmt) */
1974 UNLOCK_BITMAP
1978 VOID METHOD(ATIOffBM, Hidd_BitMap, PutTemplate)
1979 __attribute__((alias(METHOD_NAME_S(ATIOnBM, Hidd_BitMap, PutTemplate))));
1981 VOID METHOD(ATIOnBM, Hidd_BitMap, PutTemplate)
1983 atiBitMap *bm = OOP_INST_DATA(cl, o);
1985 LOCK_BITMAP
1987 IPTR VideoData = bm->framebuffer;
1989 if (bm->fbgfx)
1991 VideoData += (IPTR)sd->Card.FrameBuffer;
1992 if (sd->Card.Busy)
1994 LOCK_HW
1995 #warning TODO: NVSync(sd)
1996 RADEONWaitForIdleMMIO(sd);
1997 UNLOCK_HW
2002 switch(bm->bpp)
2004 case 1:
2006 struct pHidd_BitMap_PutMemTemplate8 __m = {
2007 sd->mid_PutMemTemplate8,
2008 msg->gc,
2009 msg->template,
2010 msg->modulo,
2011 msg->srcx,
2012 (APTR)VideoData,
2013 bm->pitch,
2014 msg->x,
2015 msg->y,
2016 msg->width,
2017 msg->height,
2018 msg->inverttemplate
2019 }, *m = &__m;
2021 OOP_DoMethod(o, (OOP_Msg)m);
2023 break;
2025 case 2:
2027 struct pHidd_BitMap_PutMemTemplate16 __m = {
2028 sd->mid_PutMemTemplate16,
2029 msg->gc,
2030 msg->template,
2031 msg->modulo,
2032 msg->srcx,
2033 (APTR)VideoData,
2034 bm->pitch,
2035 msg->x,
2036 msg->y,
2037 msg->width,
2038 msg->height,
2039 msg->inverttemplate
2040 }, *m = &__m;
2042 OOP_DoMethod(o, (OOP_Msg)m);
2044 break;
2046 case 4:
2048 struct pHidd_BitMap_PutMemTemplate32 __m = {
2049 sd->mid_PutMemTemplate32,
2050 msg->gc,
2051 msg->template,
2052 msg->modulo,
2053 msg->srcx,
2054 (APTR)VideoData,
2055 bm->pitch,
2056 msg->x,
2057 msg->y,
2058 msg->width,
2059 msg->height,
2060 msg->inverttemplate
2061 }, *m = &__m;
2063 OOP_DoMethod(o, (OOP_Msg)m);
2065 break;
2066 } /* switch(bm->bpp) */
2068 UNLOCK_BITMAP
2071 VOID METHOD(ATIOffBM, Hidd_BitMap, PutPattern)
2072 __attribute__((alias(METHOD_NAME_S(ATIOnBM, Hidd_BitMap, PutPattern))));
2074 VOID METHOD(ATIOnBM, Hidd_BitMap, PutPattern)
2076 atiBitMap *bm = OOP_INST_DATA(cl, o);
2078 LOCK_BITMAP
2080 IPTR VideoData = bm->framebuffer;
2082 if (bm->fbgfx)
2084 VideoData += (IPTR)sd->Card.FrameBuffer;
2085 if (sd->Card.Busy)
2087 LOCK_HW
2088 #warning TODO: NVSync(sd)
2089 RADEONWaitForIdleMMIO(sd);
2090 UNLOCK_HW
2095 switch(bm->bpp)
2097 case 1:
2099 struct pHidd_BitMap_PutMemPattern8 __m = {
2100 sd->mid_PutMemPattern8,
2101 msg->gc,
2102 msg->pattern,
2103 msg->patternsrcx,
2104 msg->patternsrcy,
2105 msg->patternheight,
2106 msg->patterndepth,
2107 msg->patternlut,
2108 msg->invertpattern,
2109 msg->mask,
2110 msg->maskmodulo,
2111 msg->masksrcx,
2112 (APTR)VideoData,
2113 bm->pitch,
2114 msg->x,
2115 msg->y,
2116 msg->width,
2117 msg->height
2118 }, *m = &__m;
2120 OOP_DoMethod(o, (OOP_Msg)m);
2122 break;
2124 case 2:
2126 struct pHidd_BitMap_PutMemPattern16 __m = {
2127 sd->mid_PutMemPattern16,
2128 msg->gc,
2129 msg->pattern,
2130 msg->patternsrcx,
2131 msg->patternsrcy,
2132 msg->patternheight,
2133 msg->patterndepth,
2134 msg->patternlut,
2135 msg->invertpattern,
2136 msg->mask,
2137 msg->maskmodulo,
2138 msg->masksrcx,
2139 (APTR)VideoData,
2140 bm->pitch,
2141 msg->x,
2142 msg->y,
2143 msg->width,
2144 msg->height
2145 }, *m = &__m;
2147 OOP_DoMethod(o, (OOP_Msg)m);
2149 break;
2151 case 4:
2153 struct pHidd_BitMap_PutMemPattern32 __m = {
2154 sd->mid_PutMemPattern32,
2155 msg->gc,
2156 msg->pattern,
2157 msg->patternsrcx,
2158 msg->patternsrcy,
2159 msg->patternheight,
2160 msg->patterndepth,
2161 msg->patternlut,
2162 msg->invertpattern,
2163 msg->mask,
2164 msg->maskmodulo,
2165 msg->masksrcx,
2166 (APTR)VideoData,
2167 bm->pitch,
2168 msg->x,
2169 msg->y,
2170 msg->width,
2171 msg->height
2172 }, *m = &__m;
2174 OOP_DoMethod(o, (OOP_Msg)m);
2176 break;
2177 } /* switch(bm->bpp) */
2179 UNLOCK_BITMAP