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
)
399 getcolor
->colorNo
= pixel
;
400 OOP_DoMethod(colormap
, (OOP_Msg
)getcolor
);
401 pixel
= ((color
.red
<< 8) & 0xff0000) |
402 ((color
.green
) & 0x00ff00) |
403 ((color
.blue
>> 8) & 0x0000ff);
404 *curimg
++ = ToRGB8888(0xe0, pixel
);
406 else *curimg
++ = ToRGB8888(0,0);
409 for (x
=width
; x
< maxw
; x
++, curimg
++)
413 for (y
=height
; y
< maxh
; y
++)
414 for (x
=0; x
< maxw
; x
++)
415 { if (*curimg
!=0x50000000) *curimg
= 0; curimg
++; }
417 CURSOR_SWAPPING_END();
419 if (!sd
->Card
.IsSecondary
)
420 OUTREG(RADEON_CRTC_GEN_CNTL
, save1
);
422 if (sd
->Card
.IsSecondary
)
423 OUTREG(RADEON_CRTC2_GEN_CNTL
, save2
);
431 void METHOD(ATI
, Hidd_Gfx
, SetCursorVisible
)
433 ShowHideCursor(sd
, msg
->visible
);
434 sd
->Card
.cursorVisible
= msg
->visible
;
437 void METHOD(ATI
, Hidd_Gfx
, SetCursorPos
)
439 D(bug("[ATI] Set cursor pos %d:%d\n", msg
->x
, msg
->y
));
441 if (!sd
->Card
.IsSecondary
) {
442 OUTREG(RADEON_CUR_HORZ_VERT_OFF
, RADEON_CUR_LOCK
);
443 OUTREG(RADEON_CUR_HORZ_VERT_POSN
, (RADEON_CUR_LOCK
445 | (msg
->y
& 0xffff)));
446 OUTREG(RADEON_CUR_OFFSET
, sd
->Card
.CursorStart
);
448 D(bug("[ATI] OFF=%08x, HV_OFF=%08x, HV_POSN=%08x\n",
449 INREG(RADEON_CUR_OFFSET
),
450 INREG(RADEON_CUR_HORZ_VERT_OFF
),
451 INREG(RADEON_CUR_HORZ_VERT_POSN
)));
454 OUTREG(RADEON_CUR2_HORZ_VERT_OFF
, RADEON_CUR2_LOCK
);
455 OUTREG(RADEON_CUR2_HORZ_VERT_POSN
, (RADEON_CUR2_LOCK
457 | (msg
->y
& 0xffff)));
458 OUTREG(RADEON_CUR2_OFFSET
, sd
->Card
.CursorStart
/* + addend???? */);
462 OOP_Object
*METHOD(ATI
, Root
, New
)
464 struct TagItem pftags_24bpp
[] = {
465 { aHidd_PixFmt_RedShift
, 8 }, /* 0 */
466 { aHidd_PixFmt_GreenShift
, 16 }, /* 1 */
467 { aHidd_PixFmt_BlueShift
, 24 }, /* 2 */
468 { aHidd_PixFmt_AlphaShift
, 0 }, /* 3 */
469 { aHidd_PixFmt_RedMask
, 0x00ff0000 }, /* 4 */
470 { aHidd_PixFmt_GreenMask
, 0x0000ff00 }, /* 5 */
471 { aHidd_PixFmt_BlueMask
, 0x000000ff }, /* 6 */
472 { aHidd_PixFmt_AlphaMask
, 0x00000000 }, /* 7 */
473 { aHidd_PixFmt_ColorModel
, vHidd_ColorModel_TrueColor
}, /* 8 */
474 { aHidd_PixFmt_Depth
, 32 }, /* 9 */
475 { aHidd_PixFmt_BytesPerPixel
, 4 }, /* 10 */
476 { aHidd_PixFmt_BitsPerPixel
, 24 }, /* 11 */
477 { aHidd_PixFmt_StdPixFmt
, vHidd_StdPixFmt_BGR032
}, /* 12 Native */
478 { aHidd_PixFmt_BitMapType
, vHidd_BitMapType_Chunky
}, /* 15 */
482 struct TagItem pftags_16bpp
[] = {
483 { aHidd_PixFmt_RedShift
, 16 }, /* 0 */
484 { aHidd_PixFmt_GreenShift
, 21 }, /* 1 */
485 { aHidd_PixFmt_BlueShift
, 27 }, /* 2 */
486 { aHidd_PixFmt_AlphaShift
, 0 }, /* 3 */
487 { aHidd_PixFmt_RedMask
, 0x0000f800 }, /* 4 */
488 { aHidd_PixFmt_GreenMask
, 0x000007e0 }, /* 5 */
489 { aHidd_PixFmt_BlueMask
, 0x0000001f }, /* 6 */
490 { aHidd_PixFmt_AlphaMask
, 0x00000000 }, /* 7 */
491 { aHidd_PixFmt_ColorModel
, vHidd_ColorModel_TrueColor
}, /* 8 */
492 { aHidd_PixFmt_Depth
, 16 }, /* 9 */
493 { aHidd_PixFmt_BytesPerPixel
, 2 }, /* 10 */
494 { aHidd_PixFmt_BitsPerPixel
, 16 }, /* 11 */
495 { aHidd_PixFmt_StdPixFmt
, vHidd_StdPixFmt_RGB16_LE
}, /* 12 */
496 { aHidd_PixFmt_BitMapType
, vHidd_BitMapType_Chunky
}, /* 15 */
500 struct TagItem pftags_15bpp
[] = {
501 { aHidd_PixFmt_RedShift
, 17 }, /* 0 */
502 { aHidd_PixFmt_GreenShift
, 22 }, /* 1 */
503 { aHidd_PixFmt_BlueShift
, 27 }, /* 2 */
504 { aHidd_PixFmt_AlphaShift
, 0 }, /* 3 */
505 { aHidd_PixFmt_RedMask
, 0x00007c00 }, /* 4 */
506 { aHidd_PixFmt_GreenMask
, 0x000003e0 }, /* 5 */
507 { aHidd_PixFmt_BlueMask
, 0x0000001f }, /* 6 */
508 { aHidd_PixFmt_AlphaMask
, 0x00000000 }, /* 7 */
509 { aHidd_PixFmt_ColorModel
, vHidd_ColorModel_TrueColor
}, /* 8 */
510 { aHidd_PixFmt_Depth
, 15 }, /* 9 */
511 { aHidd_PixFmt_BytesPerPixel
, 2 }, /* 10 */
512 { aHidd_PixFmt_BitsPerPixel
, 15 }, /* 11 */
513 { aHidd_PixFmt_StdPixFmt
, vHidd_StdPixFmt_RGB15_LE
}, /* 12 */
514 { aHidd_PixFmt_BitMapType
, vHidd_BitMapType_Chunky
}, /* 15 */
518 MAKE_SYNC(640x480_60
, 25174,
523 MAKE_SYNC(800x600_56
, 36000, // 36000
528 MAKE_SYNC(1024x768_60
, 65000, //78654=60kHz, 75Hz. 65000=50kHz,62Hz
529 1024, 1048, 1184, 1344,
533 MAKE_SYNC(1152x864_60
, 80000,
534 1152, 1216, 1328, 1456,
538 MAKE_SYNC(1280x1024_60
, 107991,
539 1280, 1328, 1440, 1688,
540 1024, 1025, 1028, 1066,
543 MAKE_SYNC(1600x1200_60
, 155982,
544 1600, 1632, 1792, 2048,
545 1200, 1210, 1218, 1270,
548 struct TagItem modetags
[] = {
549 { aHidd_Gfx_PixFmtTags
, (IPTR
)pftags_24bpp
},
550 { aHidd_Gfx_PixFmtTags
, (IPTR
)pftags_16bpp
},
551 { aHidd_Gfx_PixFmtTags
, (IPTR
)pftags_15bpp
},
552 { aHidd_Gfx_SyncTags
, (IPTR
)sync_1280x1024_60
},
553 { aHidd_Gfx_SyncTags
, (IPTR
)sync_640x480_60
},
554 { aHidd_Gfx_SyncTags
, (IPTR
)sync_800x600_56
},
555 { aHidd_Gfx_SyncTags
, (IPTR
)sync_1024x768_60
},
556 { aHidd_Gfx_SyncTags
, (IPTR
)sync_1152x864_60
},
557 { aHidd_Gfx_SyncTags
, (IPTR
)sync_1600x1200_60
},
561 struct TagItem mytags
[] = {
562 { aHidd_Gfx_ModeTags
, (IPTR
)modetags
},
563 { TAG_MORE
, (IPTR
)msg
->attrList
}
566 struct pRoot_New mymsg
;
568 mymsg
.mID
= msg
->mID
;
569 mymsg
.attrList
= mytags
;
573 o
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
579 EnterFunc(bug("[ATI] RadeonDriver::New()=%08x\n",o
));
584 void METHOD(ATI
, Root
, Get
)
589 if (IS_GFX_ATTR(msg
->attrID
, idx
))
593 case aoHidd_Gfx_SupportsHWCursor
:
594 *msg
->storage
= (IPTR
)TRUE
;
598 case aoHidd_Gfx_DPMSLevel
:
599 *msg
->storage
= sd
->dpms
;
606 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
611 void METHOD(ATI
, Root
, Set
)
615 const struct TagItem
*tags
= msg
->attrList
;
617 while ((tag
= NextTagItem(&tags
)))
619 if (IS_GFX_ATTR(tag
->ti_Tag
, idx
))
623 case aoHidd_Gfx_DPMSLevel
:
626 DPMS(sd
, tag
->ti_Data
);
627 sd
->dpms
= tag
->ti_Data
;
635 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);