2 Copyright © 2004, The AROS Development Team. All rights reserved.
6 #include <utility/tagitem.h>
8 #include <proto/exec.h>
10 #include <proto/utility.h>
14 #include "radeon_reg.h"
15 #include "radeon_bios.h"
16 #include "radeon_accel.h"
17 #include "radeon_macros.h"
20 #include <aros/debug.h>
22 #define sd ((struct ati_staticdata*)SD(cl))
24 #undef HiddPCIDeviceAttrBase
25 #undef HiddGfxAttrBase
26 #undef HiddPixFmtAttrBase
27 #undef HiddSyncAttrBase
28 #undef HiddBitMapAttrBase
29 #define HiddPCIDeviceAttrBase (sd->pciAttrBase)
30 #define HiddATIBitMapAttrBase (sd->atiBitMapAttrBase)
31 #define HiddBitMapAttrBase (sd->bitMapAttrBase)
32 #define HiddPixFmtAttrBase (sd->pixFmtAttrBase)
33 #define HiddGfxAttrBase (sd->gfxAttrBase)
34 #define HiddSyncAttrBase (sd->syncAttrBase)
36 #define ToRGB8888(alp,c) ((c) | ((alp) << 24))
40 #define CURSOR_SWAPPING_DECL_MMIO ULONG __temp_surface_cntl = INREG(RADEON_SURFACE_CNTL)
41 #define CURSOR_SWAPPING_START() \
42 OUTREG(RADEON_SURFACE_CNTL, \
43 (__temp_surface_cntl | \
44 RADEON_NONSURF_AP0_SWP_32BPP) & \
45 ~RADEON_NONSURF_AP0_SWP_16BPP)
46 #define CURSOR_SWAPPING_END() (OUTREG(RADEON_SURFACE_CNTL, \
51 #define CURSOR_SWAPPING_DECL_MMIO
52 #define CURSOR_SWAPPING_START()
53 #define CURSOR_SWAPPING_END()
57 #define MAKE_SYNC(name,clock,hdisp,hstart,hend,htotal,vdisp,vstart,vend,vtotal,descr) \
58 struct TagItem sync_ ## name[]={ \
59 { aHidd_Sync_PixelClock, clock*1000 }, \
60 { aHidd_Sync_HDisp, hdisp }, \
61 { aHidd_Sync_HSyncStart, hstart }, \
62 { aHidd_Sync_HSyncEnd, hend }, \
63 { aHidd_Sync_HTotal, htotal }, \
64 { aHidd_Sync_VDisp, vdisp }, \
65 { aHidd_Sync_VSyncStart, vstart }, \
66 { aHidd_Sync_VSyncEnd, vend }, \
67 { aHidd_Sync_VTotal, vtotal }, \
68 { aHidd_Sync_Description, (IPTR)descr}, \
72 OOP_Object
*METHOD(ATI
, Hidd_Gfx
, Show
)
74 OOP_Object
*fb
= NULL
;
77 atiBitMap
*bm
= OOP_INST_DATA(OOP_OCLASS(msg
->bitMap
), msg
->bitMap
);
80 /* Suppose bm has properly allocated state structure */
87 LoadState(sd
, bm
->state
);
91 ShowHideCursor(sd
, sd
->Card
.cursorVisible
);
93 RADEONEngineReset(sd
);
94 RADEONEngineRestore(sd
);
102 fb
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
107 OOP_Object
*METHOD(ATI
, Hidd_Gfx
, NewBitMap
)
109 BOOL displayable
, framebuffer
;
110 OOP_Class
*classptr
= NULL
;
111 struct TagItem mytags
[2];
112 struct pHidd_Gfx_NewBitMap mymsg
;
114 /* Displayable bitmap ? */
115 displayable
= GetTagData(aHidd_BitMap_Displayable
, FALSE
, msg
->attrList
);
116 framebuffer
= GetTagData(aHidd_BitMap_FrameBuffer
, FALSE
, msg
->attrList
);
120 /* If the user asks for a framebuffer map we must ALLWAYS supply a class */
121 classptr
= sd
->OnBMClass
;
123 else if (displayable
)
125 classptr
= sd
->OnBMClass
; //offbmclass;
131 For the non-displayable case we can either supply a class ourselves
132 if we can optimize a certain type of non-displayable bitmaps. Or we
133 can let the superclass create on for us.
135 The attributes that might come from the user deciding the bitmap
137 - aHidd_BitMap_ModeID: a modeid. create a nondisplayable
138 bitmap with the size and pixelformat of a gfxmode.
139 - aHidd_BitMap_StdPixFmt: a standard pixelformat as described in
141 - aHidd_BitMap_Friend: if this is supplied and none of the two above
142 are supplied, then the pixel format of the created bitmap
143 will be the same as the one of the friend bitmap.
145 These tags are listed in prioritized order, so if
146 the user supplied a ModeID tag, then you should not care about StdPixFmt
147 or Friend. If there is no ModeID, but a StdPixFmt tag supplied,
148 then you should not care about Friend because you have to
149 create the correct pixelformat. And as said above, if only Friend
150 is supplied, you can create a bitmap with same pixelformat as Frien
153 modeid
= (HIDDT_ModeID
)GetTagData(aHidd_BitMap_ModeID
, vHidd_ModeID_Invalid
, msg
->attrList
);
155 if (vHidd_ModeID_Invalid
!= modeid
)
157 /* User supplied a valid modeid. We can use our offscreen class */
158 classptr
= sd
->OnBMClass
;
163 We may create an offscreen bitmap if the user supplied a friend
164 bitmap. But we need to check that he did not supplied a StdPixFmt
166 HIDDT_StdPixFmt stdpf
= (HIDDT_StdPixFmt
)GetTagData(aHidd_BitMap_StdPixFmt
, vHidd_StdPixFmt_Unknown
, msg
->attrList
);
168 if (vHidd_StdPixFmt_Plane
== stdpf
)
170 classptr
= sd
->PlanarBMClass
;
172 else if (vHidd_StdPixFmt_Unknown
== stdpf
)
174 /* No std pixfmt supplied */
177 /* Did the user supply a friend bitmap ? */
178 friend = (OOP_Object
*)GetTagData(aHidd_BitMap_Friend
, 0, msg
->attrList
);
181 OOP_Object
* gfxhidd
;
182 /* User supplied friend bitmap. Is the friend bitmap a Ati Gfx hidd bitmap ? */
183 OOP_GetAttr(friend, aHidd_BitMap_GfxHidd
, (APTR
)&gfxhidd
);
186 /* Friend was NVidia hidd bitmap. Now we can supply our own class */
187 classptr
= sd
->OffBMClass
;
194 D(bug("[ATI] classptr = %p\n", classptr
));
196 /* Do we supply our own class ? */
197 if (NULL
!= classptr
)
199 /* Yes. We must let the superclass not that we do this. This is
200 done through adding a tag in the frot of the taglist */
201 mytags
[0].ti_Tag
= aHidd_BitMap_ClassPtr
;
202 mytags
[0].ti_Data
= (IPTR
)classptr
;
203 mytags
[1].ti_Tag
= TAG_MORE
;
204 mytags
[1].ti_Data
= (IPTR
)msg
->attrList
;
206 /* Like in Gfx::New() we init a new message struct */
207 mymsg
.mID
= msg
->mID
;
208 mymsg
.attrList
= mytags
;
210 /* Pass the new message to the superclass */
214 return (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
217 void METHOD(ATI
, Hidd_Gfx
, CopyBox
)
219 ULONG mode
= GC_DRMD(msg
->gc
);
222 /* Check whether we can get Drawable attribute of our nVidia class */
223 OOP_GetAttr(msg
->src
, aHidd_ATIBitMap_Drawable
, &src
);
224 OOP_GetAttr(msg
->dest
, aHidd_ATIBitMap_Drawable
, &dst
);
228 /* No. One of the bitmaps is not nVidia bitmap */
229 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
234 /* Yes. Get the instance data of both bitmaps */
235 atiBitMap
*bm_src
= OOP_INST_DATA(OOP_OCLASS(msg
->src
), msg
->src
);
236 atiBitMap
*bm_dst
= OOP_INST_DATA(OOP_OCLASS(msg
->dest
), msg
->dest
);
238 D(bug("[ATI] CopyBox(src(%p,%d:%d@%d),dst(%p,%d:%d@%d),%d:%d\n",
239 bm_src
->framebuffer
,msg
->srcX
,msg
->srcY
,bm_src
->depth
,
240 bm_dst
->framebuffer
,msg
->destX
,msg
->destY
,bm_dst
->depth
,
241 msg
->width
, msg
->height
));
243 /* Case -1: (To be fixed) one of the bitmaps have chunky outside GFX mem */
244 if (!bm_src
->fbgfx
|| !bm_dst
->fbgfx
)
246 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
248 /* Case 0: one of bitmaps is 8bpp, whereas the other is TrueColor one */
249 else if ((bm_src
->depth
<= 8 || bm_dst
->depth
<= 8) &&
250 (bm_src
->depth
!= bm_dst
->depth
))
252 /* Unsupported case */
253 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
256 /* Case 1: both bitmaps have the same depth - use Blit engine */
257 else if (bm_src
->depth
== bm_dst
->depth
)
259 int xdir
= 0, ydir
= 0;
262 WORD xb
= msg
->destX
;
263 WORD yb
= msg
->destY
;
265 WORD h
= msg
->height
;
267 if (bm_src
->pitch_offset
== bm_dst
->pitch_offset
)
272 if (xdir
< 0) xa
+= w
- 1, xb
+= w
- 1;
273 if (ydir
< 0) ya
+= h
- 1, yb
+= h
- 1;
277 LOCK_BITMAP_BM(bm_src
)
278 LOCK_BITMAP_BM(bm_dst
)
283 RADEONWaitForFifo(sd
, 2);
284 OUTREG(RADEON_DST_PITCH_OFFSET
, bm_dst
->pitch_offset
);
285 OUTREG(RADEON_SRC_PITCH_OFFSET
, bm_src
->pitch_offset
);
287 bm_dst
->dp_gui_master_cntl_clip
= (bm_dst
->dp_gui_master_cntl
288 | RADEON_GMC_BRUSH_NONE
289 | RADEON_GMC_SRC_DATATYPE_COLOR
290 | RADEON_GMC_SRC_PITCH_OFFSET_CNTL
291 | RADEON_ROP
[mode
].rop
292 | RADEON_DP_SRC_SOURCE_MEMORY
);
294 RADEONWaitForFifo(sd
, 6);
295 OUTREG(RADEON_DP_GUI_MASTER_CNTL
, bm_dst
->dp_gui_master_cntl_clip
);
296 OUTREG(RADEON_DP_WRITE_MASK
, ~0);
297 OUTREG(RADEON_DP_CNTL
,
298 ((xdir
>= 0 ? RADEON_DST_X_LEFT_TO_RIGHT
: 0) |
299 (ydir
>= 0 ? RADEON_DST_Y_TOP_TO_BOTTOM
: 0)));
301 OUTREG(RADEON_SRC_Y_X
, (ya
<< 16) | xa
);
302 OUTREG(RADEON_DST_Y_X
, (yb
<< 16) | xb
);
303 OUTREG(RADEON_DST_HEIGHT_WIDTH
, (h
<< 16) | w
);
307 UNLOCK_BITMAP_BM(bm_src
)
308 UNLOCK_BITMAP_BM(bm_dst
)
310 else /* Case 2: different bitmaps. HELP? */
312 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
322 BOOL
METHOD(ATI
, Hidd_Gfx
, SetCursorShape
)
324 D(bug("[ATI] Set cursor shape %08x\n", msg
->shape
));
326 if (msg
->shape
== NULL
)
328 ShowHideCursor(sd
, 0);
329 sd
->Card
.cursorVisible
= 0;
334 OOP_Object
*colormap
;
335 HIDDT_StdPixFmt pixfmt
;
338 ULONG width
, height
, x
, y
;
340 ULONG save1
=0, save2
=0;
342 ULONG
*curimg
= (ULONG
*)((IPTR
)sd
->Card
.CursorStart
+ (IPTR
)sd
->Card
.FrameBuffer
);
344 CURSOR_SWAPPING_DECL_MMIO
;
346 struct pHidd_BitMap_GetPixel __gp
= {
347 mID
: OOP_GetMethodID((STRPTR
)CLID_Hidd_BitMap
, moHidd_BitMap_GetPixel
)
348 }, *getpixel
= &__gp
;
350 struct pHidd_ColorMap_GetColor __gc
= {
351 mID
: OOP_GetMethodID((STRPTR
)CLID_Hidd_ColorMap
, moHidd_ColorMap_GetColor
),
353 }, *getcolor
= &__gc
;
355 OOP_GetAttr(msg
->shape
, aHidd_BitMap_Width
, &width
);
356 OOP_GetAttr(msg
->shape
, aHidd_BitMap_Height
, &height
);
357 OOP_GetAttr(msg
->shape
, aHidd_BitMap_PixFmt
, (APTR
)&pfmt
);
358 OOP_GetAttr(pfmt
, aHidd_PixFmt_StdPixFmt
, &pixfmt
);
359 OOP_GetAttr(msg
->shape
, aHidd_BitMap_ColorMap
, (APTR
)&colormap
);
361 if (width
> 64) width
= 64;
362 if (height
> 64) height
= 64;
369 if (!sd
->Card
.IsSecondary
) {
370 save1
= INREG(RADEON_CRTC_GEN_CNTL
) & ~(ULONG
)(RADEON_CRTC_ARGB_EN
|RADEON_CRTC_ARGB_EN
);
371 save1
|= RADEON_CRTC_ARGB_EN
;
372 OUTREG(RADEON_CRTC_GEN_CNTL
, save1
& (ULONG
)~RADEON_CRTC_CUR_EN
);
375 if (sd
->Card
.IsSecondary
) {
376 save2
= INREG(RADEON_CRTC_GEN_CNTL
) & ~(ULONG
)(RADEON_CRTC_ARGB_EN
|RADEON_CRTC_ARGB_EN
);
377 save2
|= RADEON_CRTC_ARGB_EN
;
378 OUTREG(RADEON_CRTC2_GEN_CNTL
, save2
& (ULONG
)~RADEON_CRTC2_CUR_EN
);
381 CURSOR_SWAPPING_START();
383 for (x
= 0; x
< maxw
*maxh
; x
++)
386 for (y
= 0; y
< height
; y
++)
388 for (x
= 0; x
< width
; x
++)
393 pixel
= OOP_DoMethod(msg
->shape
, (OOP_Msg
)getpixel
);
395 if (pixfmt
== vHidd_StdPixFmt_LUT8
)
397 getcolor
->colorNo
= pixel
;
398 OOP_DoMethod(colormap
, (OOP_Msg
)getcolor
);
399 pixel
= ((color
.red
<< 8) & 0xff0000) |
400 ((color
.green
) & 0x00ff00) |
401 ((color
.blue
>> 8) & 0x0000ff);
404 *curimg
++ = ToRGB8888(0xe0, pixel
);
408 for (x
=width
; x
< maxw
; x
++, curimg
++)
412 for (y
=height
; y
< maxh
; y
++)
413 for (x
=0; x
< maxw
; x
++)
414 { if (*curimg
!=0x50000000) *curimg
= 0; curimg
++; }
416 CURSOR_SWAPPING_END();
418 if (!sd
->Card
.IsSecondary
)
419 OUTREG(RADEON_CRTC_GEN_CNTL
, save1
);
421 if (sd
->Card
.IsSecondary
)
422 OUTREG(RADEON_CRTC2_GEN_CNTL
, save2
);
430 void METHOD(ATI
, Hidd_Gfx
, SetCursorVisible
)
432 ShowHideCursor(sd
, msg
->visible
);
433 sd
->Card
.cursorVisible
= msg
->visible
;
436 void METHOD(ATI
, Hidd_Gfx
, SetCursorPos
)
438 D(bug("[ATI] Set cursor pos %d:%d\n", msg
->x
, msg
->y
));
440 if (!sd
->Card
.IsSecondary
) {
441 OUTREG(RADEON_CUR_HORZ_VERT_OFF
, RADEON_CUR_LOCK
);
442 OUTREG(RADEON_CUR_HORZ_VERT_POSN
, (RADEON_CUR_LOCK
444 | (msg
->y
& 0xffff)));
445 OUTREG(RADEON_CUR_OFFSET
, sd
->Card
.CursorStart
);
447 D(bug("[ATI] OFF=%08x, HV_OFF=%08x, HV_POSN=%08x\n",
448 INREG(RADEON_CUR_OFFSET
),
449 INREG(RADEON_CUR_HORZ_VERT_OFF
),
450 INREG(RADEON_CUR_HORZ_VERT_POSN
)));
453 OUTREG(RADEON_CUR2_HORZ_VERT_OFF
, RADEON_CUR2_LOCK
);
454 OUTREG(RADEON_CUR2_HORZ_VERT_POSN
, (RADEON_CUR2_LOCK
456 | (msg
->y
& 0xffff)));
457 OUTREG(RADEON_CUR2_OFFSET
, sd
->Card
.CursorStart
/* + addend???? */);
461 OOP_Object
*METHOD(ATI
, Root
, New
)
463 struct TagItem pftags_24bpp
[] = {
464 { aHidd_PixFmt_RedShift
, 8 }, /* 0 */
465 { aHidd_PixFmt_GreenShift
, 16 }, /* 1 */
466 { aHidd_PixFmt_BlueShift
, 24 }, /* 2 */
467 { aHidd_PixFmt_AlphaShift
, 0 }, /* 3 */
468 { aHidd_PixFmt_RedMask
, 0x00ff0000 }, /* 4 */
469 { aHidd_PixFmt_GreenMask
, 0x0000ff00 }, /* 5 */
470 { aHidd_PixFmt_BlueMask
, 0x000000ff }, /* 6 */
471 { aHidd_PixFmt_AlphaMask
, 0x00000000 }, /* 7 */
472 { aHidd_PixFmt_ColorModel
, vHidd_ColorModel_TrueColor
}, /* 8 */
473 { aHidd_PixFmt_Depth
, 32 }, /* 9 */
474 { aHidd_PixFmt_BytesPerPixel
, 4 }, /* 10 */
475 { aHidd_PixFmt_BitsPerPixel
, 24 }, /* 11 */
476 { aHidd_PixFmt_StdPixFmt
, vHidd_StdPixFmt_BGR032
}, /* 12 Native */
477 { aHidd_PixFmt_BitMapType
, vHidd_BitMapType_Chunky
}, /* 15 */
481 struct TagItem pftags_16bpp
[] = {
482 { aHidd_PixFmt_RedShift
, 16 }, /* 0 */
483 { aHidd_PixFmt_GreenShift
, 21 }, /* 1 */
484 { aHidd_PixFmt_BlueShift
, 27 }, /* 2 */
485 { aHidd_PixFmt_AlphaShift
, 0 }, /* 3 */
486 { aHidd_PixFmt_RedMask
, 0x0000f800 }, /* 4 */
487 { aHidd_PixFmt_GreenMask
, 0x000007e0 }, /* 5 */
488 { aHidd_PixFmt_BlueMask
, 0x0000001f }, /* 6 */
489 { aHidd_PixFmt_AlphaMask
, 0x00000000 }, /* 7 */
490 { aHidd_PixFmt_ColorModel
, vHidd_ColorModel_TrueColor
}, /* 8 */
491 { aHidd_PixFmt_Depth
, 16 }, /* 9 */
492 { aHidd_PixFmt_BytesPerPixel
, 2 }, /* 10 */
493 { aHidd_PixFmt_BitsPerPixel
, 16 }, /* 11 */
494 { aHidd_PixFmt_StdPixFmt
, vHidd_StdPixFmt_RGB16_LE
}, /* 12 */
495 { aHidd_PixFmt_BitMapType
, vHidd_BitMapType_Chunky
}, /* 15 */
499 struct TagItem pftags_15bpp
[] = {
500 { aHidd_PixFmt_RedShift
, 17 }, /* 0 */
501 { aHidd_PixFmt_GreenShift
, 22 }, /* 1 */
502 { aHidd_PixFmt_BlueShift
, 27 }, /* 2 */
503 { aHidd_PixFmt_AlphaShift
, 0 }, /* 3 */
504 { aHidd_PixFmt_RedMask
, 0x00007c00 }, /* 4 */
505 { aHidd_PixFmt_GreenMask
, 0x000003e0 }, /* 5 */
506 { aHidd_PixFmt_BlueMask
, 0x0000001f }, /* 6 */
507 { aHidd_PixFmt_AlphaMask
, 0x00000000 }, /* 7 */
508 { aHidd_PixFmt_ColorModel
, vHidd_ColorModel_TrueColor
}, /* 8 */
509 { aHidd_PixFmt_Depth
, 15 }, /* 9 */
510 { aHidd_PixFmt_BytesPerPixel
, 2 }, /* 10 */
511 { aHidd_PixFmt_BitsPerPixel
, 15 }, /* 11 */
512 { aHidd_PixFmt_StdPixFmt
, vHidd_StdPixFmt_RGB15_LE
}, /* 12 */
513 { aHidd_PixFmt_BitMapType
, vHidd_BitMapType_Chunky
}, /* 15 */
517 MAKE_SYNC(640x480_60
, 25174,
522 MAKE_SYNC(800x600_56
, 36000, // 36000
527 MAKE_SYNC(1024x768_60
, 65000, //78654=60kHz, 75Hz. 65000=50kHz,62Hz
528 1024, 1048, 1184, 1344,
532 MAKE_SYNC(1152x864_60
, 80000,
533 1152, 1216, 1328, 1456,
537 MAKE_SYNC(1280x1024_60
, 107991,
538 1280, 1328, 1440, 1688,
539 1024, 1025, 1028, 1066,
542 MAKE_SYNC(1600x1200_60
, 155982,
543 1600, 1632, 1792, 2048,
544 1200, 1210, 1218, 1270,
547 struct TagItem modetags
[] = {
548 { aHidd_Gfx_PixFmtTags
, (IPTR
)pftags_24bpp
},
549 { aHidd_Gfx_PixFmtTags
, (IPTR
)pftags_16bpp
},
550 { aHidd_Gfx_PixFmtTags
, (IPTR
)pftags_15bpp
},
551 { aHidd_Gfx_SyncTags
, (IPTR
)sync_1280x1024_60
},
552 { aHidd_Gfx_SyncTags
, (IPTR
)sync_640x480_60
},
553 { aHidd_Gfx_SyncTags
, (IPTR
)sync_800x600_56
},
554 { aHidd_Gfx_SyncTags
, (IPTR
)sync_1024x768_60
},
555 { aHidd_Gfx_SyncTags
, (IPTR
)sync_1152x864_60
},
556 { aHidd_Gfx_SyncTags
, (IPTR
)sync_1600x1200_60
},
560 struct TagItem mytags
[] = {
561 { aHidd_Gfx_ModeTags
, (IPTR
)modetags
},
562 { TAG_MORE
, (IPTR
)msg
->attrList
}
565 struct pRoot_New mymsg
;
567 mymsg
.mID
= msg
->mID
;
568 mymsg
.attrList
= mytags
;
572 o
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
578 EnterFunc(bug("[ATI] RadeonDriver::New()=%08x\n",o
));
583 void METHOD(ATI
, Root
, Get
)
588 if (IS_GFX_ATTR(msg
->attrID
, idx
))
592 case aoHidd_Gfx_SupportsHWCursor
:
593 *msg
->storage
= (IPTR
)TRUE
;
597 case aoHidd_Gfx_DPMSLevel
:
598 *msg
->storage
= sd
->dpms
;
605 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
610 void METHOD(ATI
, Root
, Set
)
614 const struct TagItem
*tags
= msg
->attrList
;
616 while ((tag
= NextTagItem(&tags
)))
618 if (IS_GFX_ATTR(tag
->ti_Tag
, idx
))
622 case aoHidd_Gfx_DPMSLevel
:
625 DPMS(sd
, tag
->ti_Data
);
626 sd
->dpms
= tag
->ti_Data
;
634 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);