Updated PCI IDs to latest snapshot.
[tangerine.git] / arch / common / hidd.nvidia / nvidiaclass.c
blobccc7bd5481e9ee29aa639caa5b628f95ff79e6b9
1 /*
2 Copyright © 2004-2006, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: NVidia gfx class
6 Lang: English
7 */
9 #include <exec/types.h>
10 #include <exec/memory.h>
12 #include <hidd/hidd.h>
13 #include <hidd/graphics.h>
15 #include <proto/exec.h>
16 #include <proto/oop.h>
17 #include <proto/utility.h>
19 #include "nv.h"
20 #include "nv_dma.h"
22 #define DEBUG 0
23 #include <aros/debug.h>
25 #define _sd (&((LIBBASETYPEPTR)cl->UserData)->sd)
27 #undef HiddPCIDeviceAttrBase
28 #undef HiddGfxAttrBase
29 #undef HiddPixFmtAttrBase
30 #undef HiddSyncAttrBase
31 #undef HiddBitMapAttrBase
32 #define HiddPCIDeviceAttrBase (_sd->pciAttrBase)
33 #define HiddNVidiaBitMapAttrBase (_sd->nvBitMapAttrBase)
34 #define HiddBitMapAttrBase (_sd->bitMapAttrBase)
35 #define HiddPixFmtAttrBase (_sd->pixFmtAttrBase)
36 #define HiddGfxAttrBase (_sd->gfxAttrBase)
37 #define HiddSyncAttrBase (_sd->syncAttrBase)
39 /* Class methods */
41 VOID NV__Root__Get(OOP_Class *cl, OOP_Object *o, struct pRoot_Get *msg)
43 ULONG idx;
44 BOOL found = FALSE;
45 if (IS_GFX_ATTR(msg->attrID, idx))
47 switch (idx)
49 case aoHidd_Gfx_SupportsHWCursor:
50 *msg->storage = (IPTR)TRUE;
51 found = TRUE;
52 break;
54 case aoHidd_Gfx_DPMSLevel:
55 *msg->storage = _sd->dpms;
56 found = TRUE;
57 break;
61 if (!found)
62 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
64 return;
67 VOID NV__Root__Set(OOP_Class *cl, OOP_Object *o, struct pRoot_Set *msg)
69 ULONG idx;
70 struct TagItem *tags, *tag;
72 tags = msg->attrList;
74 while ((tag = NextTagItem(&tags)))
76 if (IS_GFX_ATTR(tag->ti_Tag, idx))
78 switch(idx)
80 case aoHidd_Gfx_DPMSLevel:
81 LOCK_HW
83 DPMS(_sd, tag->ti_Data);
84 _sd->dpms = tag->ti_Data;
86 UNLOCK_HW
87 break;
92 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
95 #define MAKE_SYNC(name,clock,hdisp,hstart,hend,htotal,vdisp,vstart,vend,vtotal,descr) \
96 struct TagItem sync_ ## name[]={ \
97 { aHidd_Sync_PixelClock, clock*1000 }, \
98 { aHidd_Sync_HDisp, hdisp }, \
99 { aHidd_Sync_HSyncStart, hstart }, \
100 { aHidd_Sync_HSyncEnd, hend }, \
101 { aHidd_Sync_HTotal, htotal }, \
102 { aHidd_Sync_VDisp, vdisp }, \
103 { aHidd_Sync_VSyncStart, vstart }, \
104 { aHidd_Sync_VSyncEnd, vend }, \
105 { aHidd_Sync_VTotal, vtotal }, \
106 { aHidd_Sync_Description, (IPTR)descr}, \
107 { TAG_DONE, 0UL }}
109 OOP_Object *NV__Root__New(OOP_Class *cl, OOP_Object *o, struct pRoot_New *msg)
111 struct TagItem pftags_24bpp[] = {
112 { aHidd_PixFmt_RedShift, 8 }, /* 0 */
113 { aHidd_PixFmt_GreenShift, 16 }, /* 1 */
114 { aHidd_PixFmt_BlueShift, 24 }, /* 2 */
115 { aHidd_PixFmt_AlphaShift, 0 }, /* 3 */
116 { aHidd_PixFmt_RedMask, 0x00ff0000 }, /* 4 */
117 { aHidd_PixFmt_GreenMask, 0x0000ff00 }, /* 5 */
118 { aHidd_PixFmt_BlueMask, 0x000000ff }, /* 6 */
119 { aHidd_PixFmt_AlphaMask, 0x00000000 }, /* 7 */
120 { aHidd_PixFmt_ColorModel, vHidd_ColorModel_TrueColor }, /* 8 */
121 { aHidd_PixFmt_Depth, 24 }, /* 9 */
122 { aHidd_PixFmt_BytesPerPixel, 4 }, /* 10 */
123 { aHidd_PixFmt_BitsPerPixel, 24 }, /* 11 */
124 { aHidd_PixFmt_StdPixFmt, vHidd_StdPixFmt_BGR032 }, /* 12 Native */
125 { aHidd_PixFmt_BitMapType, vHidd_BitMapType_Chunky }, /* 15 */
126 { TAG_DONE, 0UL }
129 struct TagItem pftags_16bpp[] = {
130 { aHidd_PixFmt_RedShift, 16 }, /* 0 */
131 { aHidd_PixFmt_GreenShift, 21 }, /* 1 */
132 { aHidd_PixFmt_BlueShift, 27 }, /* 2 */
133 { aHidd_PixFmt_AlphaShift, 0 }, /* 3 */
134 { aHidd_PixFmt_RedMask, 0x0000f800 }, /* 4 */
135 { aHidd_PixFmt_GreenMask, 0x000007e0 }, /* 5 */
136 { aHidd_PixFmt_BlueMask, 0x0000001f }, /* 6 */
137 { aHidd_PixFmt_AlphaMask, 0x00000000 }, /* 7 */
138 { aHidd_PixFmt_ColorModel, vHidd_ColorModel_TrueColor }, /* 8 */
139 { aHidd_PixFmt_Depth, 16 }, /* 9 */
140 { aHidd_PixFmt_BytesPerPixel, 2 }, /* 10 */
141 { aHidd_PixFmt_BitsPerPixel, 16 }, /* 11 */
142 { aHidd_PixFmt_StdPixFmt, vHidd_StdPixFmt_RGB16_LE }, /* 12 */
143 { aHidd_PixFmt_BitMapType, vHidd_BitMapType_Chunky }, /* 15 */
144 { TAG_DONE, 0UL }
147 struct TagItem pftags_15bpp[] = {
148 { aHidd_PixFmt_RedShift, 17 }, /* 0 */
149 { aHidd_PixFmt_GreenShift, 22 }, /* 1 */
150 { aHidd_PixFmt_BlueShift, 27 }, /* 2 */
151 { aHidd_PixFmt_AlphaShift, 0 }, /* 3 */
152 { aHidd_PixFmt_RedMask, 0x00007c00 }, /* 4 */
153 { aHidd_PixFmt_GreenMask, 0x000003e0 }, /* 5 */
154 { aHidd_PixFmt_BlueMask, 0x0000001f }, /* 6 */
155 { aHidd_PixFmt_AlphaMask, 0x00000000 }, /* 7 */
156 { aHidd_PixFmt_ColorModel, vHidd_ColorModel_TrueColor }, /* 8 */
157 { aHidd_PixFmt_Depth, 15 }, /* 9 */
158 { aHidd_PixFmt_BytesPerPixel, 2 }, /* 10 */
159 { aHidd_PixFmt_BitsPerPixel, 15 }, /* 11 */
160 { aHidd_PixFmt_StdPixFmt, vHidd_StdPixFmt_RGB15_LE }, /* 12 */
161 { aHidd_PixFmt_BitMapType, vHidd_BitMapType_Chunky }, /* 15 */
162 { TAG_DONE, 0UL }
165 MAKE_SYNC(640x480_60, 25174,
166 640, 656, 752, 800,
167 480, 490, 492, 525,
168 "NVIDIA:640x480");
170 MAKE_SYNC(800x600_56, 36000, // 36000
171 800, 824, 896, 1024,
172 600, 601, 603, 625,
173 "NVIDIA:800x600");
175 MAKE_SYNC(1024x768_60, 65000, //78654=60kHz, 75Hz. 65000=50kHz,62Hz
176 1024, 1048, 1184, 1344,
177 768, 771, 777, 806,
178 "NVIDIA:1024x768");
180 MAKE_SYNC(1152x864_60, 80000,
181 1152, 1216, 1328, 1456,
182 864, 870, 875, 916,
183 "NVIDIA:1152x864");
185 MAKE_SYNC(1280x1024_60, 107991,
186 1280, 1328, 1440, 1688,
187 1024, 1025, 1028, 1066,
188 "NVIDIA:1280x1024");
190 MAKE_SYNC(1600x1200_60, 155982,
191 1600, 1632, 1792, 2048,
192 1200, 1210, 1218, 1270,
193 "NVIDIA:1600x1200");
195 /* "new" 16:10 modes */
197 MAKE_SYNC(1280x800_60, 83530,
198 1280, 1344, 1480, 1680,
199 800, 801, 804, 828,
200 "NVIDIA:1280x800");
202 MAKE_SYNC(1440x900_60, 106470,
203 1440, 1520, 1672, 1904,
204 900, 901, 904, 932,
205 "NVIDIA:1440x900");
207 MAKE_SYNC(1680x1050_60, 119000,
208 1680, 1728, 1760, 1840,
209 1050, 1053, 1059, 1080,
210 "NVIDIA:1680x1050");
212 MAKE_SYNC(1920x1200_60, 162090,
213 1920, 1984, 2176, 2480,
214 1200, 1201, 1204, 1250,
215 "NVIDIA:1920x1200");
217 struct TagItem modetags[] = {
218 { aHidd_Gfx_PixFmtTags, (IPTR)pftags_24bpp },
219 { aHidd_Gfx_PixFmtTags, (IPTR)pftags_16bpp },
220 { aHidd_Gfx_PixFmtTags, (IPTR)pftags_15bpp },
221 { aHidd_Gfx_SyncTags, (IPTR)sync_640x480_60 },
222 { aHidd_Gfx_SyncTags, (IPTR)sync_800x600_56 },
223 { aHidd_Gfx_SyncTags, (IPTR)sync_1024x768_60 },
224 { aHidd_Gfx_SyncTags, (IPTR)sync_1152x864_60 },
225 { aHidd_Gfx_SyncTags, (IPTR)sync_1280x1024_60 },
226 { aHidd_Gfx_SyncTags, (IPTR)sync_1600x1200_60 },
227 { aHidd_Gfx_SyncTags, (IPTR)sync_1280x800_60 },
228 { aHidd_Gfx_SyncTags, (IPTR)sync_1440x900_60 },
229 { aHidd_Gfx_SyncTags, (IPTR)sync_1680x1050_60 },
230 { aHidd_Gfx_SyncTags, (IPTR)sync_1920x1200_60 },
232 { TAG_DONE, 0UL }
235 struct TagItem mytags[] = {
236 { aHidd_Gfx_ModeTags, (IPTR)modetags },
237 { TAG_MORE, (IPTR)msg->attrList }
240 struct pRoot_New mymsg;
242 mymsg.mID = msg->mID;
243 mymsg.attrList = mytags;
245 msg = &mymsg;
247 EnterFunc(bug("[NVidia] nv::new()\n"));
249 o = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
250 if (o)
252 _sd->nvobject = o;
255 return o;
258 OOP_Object *NV__Hidd_Gfx__NewBitMap(OOP_Class *cl, OOP_Object *o,
259 struct pHidd_Gfx_NewBitMap *msg)
261 BOOL displayable, framebuffer;
262 OOP_Class *classptr = NULL;
263 struct TagItem mytags[2];
264 struct pHidd_Gfx_NewBitMap mymsg;
266 /* Displayable bitmap ? */
267 displayable = GetTagData(aHidd_BitMap_Displayable, FALSE, msg->attrList);
268 framebuffer = GetTagData(aHidd_BitMap_FrameBuffer, FALSE, msg->attrList);
270 D(bug("[NVidia] NewBitmap: framebuffer=%d, displayable=%d\n", framebuffer, displayable));
272 if (framebuffer)
274 /* If the user asks for a framebuffer map we must ALLWAYS supply a class */
275 classptr = _sd->onbmclass;
277 else if (displayable)
279 classptr = _sd->onbmclass; //offbmclass;
281 else
283 HIDDT_ModeID modeid;
285 For the non-displayable case we can either supply a class ourselves
286 if we can optimize a certain type of non-displayable bitmaps. Or we
287 can let the superclass create on for us.
289 The attributes that might come from the user deciding the bitmap
290 pixel format are:
291 - aHidd_BitMap_ModeID: a modeid. create a nondisplayable
292 bitmap with the size and pixelformat of a gfxmode.
293 - aHidd_BitMap_StdPixFmt: a standard pixelformat as described in
294 hidd/graphics.h
295 - aHidd_BitMap_Friend: if this is supplied and none of the two above
296 are supplied, then the pixel format of the created bitmap
297 will be the same as the one of the friend bitmap.
299 These tags are listed in prioritized order, so if
300 the user supplied a ModeID tag, then you should not care about StdPixFmt
301 or Friend. If there is no ModeID, but a StdPixFmt tag supplied,
302 then you should not care about Friend because you have to
303 create the correct pixelformat. And as said above, if only Friend
304 is supplied, you can create a bitmap with same pixelformat as Frien
308 modeid = (HIDDT_ModeID)GetTagData(aHidd_BitMap_ModeID, vHidd_ModeID_Invalid, msg->attrList);
309 if (vHidd_ModeID_Invalid != modeid) {
310 /* User supplied a valid modeid. We can use our offscreen class */
311 classptr = _sd->onbmclass;
312 } else {
313 /* We may create an offscreen bitmap if the user supplied a friend
314 bitmap. But we need to check that he did not supplied a StdPixFmt
316 HIDDT_StdPixFmt stdpf;
317 stdpf = (HIDDT_StdPixFmt)GetTagData(aHidd_BitMap_StdPixFmt, vHidd_StdPixFmt_Unknown, msg->attrList);
318 if (vHidd_StdPixFmt_Plane == stdpf) {
319 classptr = _sd->planarbmclass;
321 else if (vHidd_StdPixFmt_Unknown == stdpf) {
322 /* No std pixfmt supplied */
323 OOP_Object *friend;
325 /* Did the user supply a friend bitmap ? */
326 friend = (OOP_Object *)GetTagData(aHidd_BitMap_Friend, 0, msg->attrList);
327 if (NULL != friend) {
328 OOP_Object * gfxhidd;
329 /* User supplied friend bitmap. Is the friend bitmap a
330 NVidia Gfx hidd bitmap ? */
331 OOP_GetAttr(friend, aHidd_BitMap_GfxHidd, (APTR)&gfxhidd);
332 if (gfxhidd == o) {
333 /* Friend was NVidia hidd bitmap. Now we can supply our own class */
334 classptr = _sd->offbmclass;
341 D(bug("classptr = %p\n", classptr));
342 /* Do we supply our own class ? */
343 if (NULL != classptr) {
344 /* Yes. We must let the superclass not that we do this. This is
345 done through adding a tag in the frot of the taglist */
346 mytags[0].ti_Tag = aHidd_BitMap_ClassPtr;
347 mytags[0].ti_Data = (IPTR)classptr;
348 mytags[1].ti_Tag = TAG_MORE;
349 mytags[1].ti_Data = (IPTR)msg->attrList;
351 /* Like in Gfx::New() we init a new message struct */
352 mymsg.mID = msg->mID;
353 mymsg.attrList = mytags;
355 /* Pass the new message to the superclass */
356 msg = &mymsg;
359 return (OOP_Object*)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
362 OOP_Object *NV__Hidd_Gfx__Show(OOP_Class *cl, OOP_Object *o,
363 struct pHidd_Gfx_Show *msg)
365 OOP_Object *fb = NULL;
366 if (msg->bitMap)
368 nvBitMap *bm = OOP_INST_DATA(OOP_OCLASS(msg->bitMap), msg->bitMap);
370 if (bm->state)
372 /* Suppose bm has properly allocated state structure */
373 if (bm->fbgfx)
375 bm->usecount++;
377 LOCK_HW
379 LoadState(_sd, bm->state);
380 DPMS(_sd, _sd->dpms);
382 fb = bm->BitMap;
383 NVShowHideCursor(_sd, _sd->Card.cursorVisible);
385 UNLOCK_HW
390 if (!fb)
391 fb = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
393 return fb;
396 VOID NV__Hidd_Gfx__CopyBox(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_CopyBox *msg)
398 ULONG mode = GC_DRMD(msg->gc);
399 IPTR src=0, dst=0;
401 /* Check whether we can get Drawable attribute of our nVidia class */
402 OOP_GetAttr(msg->src, aHidd_nvBitMap_Drawable, &src);
403 OOP_GetAttr(msg->dest, aHidd_nvBitMap_Drawable, &dst);
405 if (!dst || !src)
407 /* No. One of the bitmaps is not nVidia bitmap */
408 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
410 else
412 /* Yes. Get the instance data of both bitmaps */
413 nvBitMap *bm_src = OOP_INST_DATA(OOP_OCLASS(msg->src), msg->src);
414 nvBitMap *bm_dst = OOP_INST_DATA(OOP_OCLASS(msg->dest), msg->dest);
416 /* Case -1: (To be fixed) one of the bitmaps have chunky outside GFX mem */
417 if (!bm_src->fbgfx || !bm_dst->fbgfx)
419 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
421 /* Case 0: one of bitmaps is 8bpp, whereas the other is TrueColor one */
422 else if ((bm_src->depth <= 8 || bm_dst->depth <= 8) &&
423 (bm_src->depth != bm_dst->depth))
425 /* Unsupported case */
426 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
427 return;
429 /* Case 1: both bitmaps have the same depth - use Blit engine */
430 else if (bm_src->depth == bm_dst->depth)
432 LOCK_MULTI_BITMAP
433 LOCK_BITMAP_BM(bm_src)
434 LOCK_BITMAP_BM(bm_dst)
435 UNLOCK_MULTI_BITMAP
437 LOCK_HW
439 _sd->Card.DMAKickoffCallback = NVDMAKickoffCallback;
440 _sd->gpu_busy = TRUE;
442 NVSetRopSolid(_sd, mode, ~0 << bm_src->depth);
444 if (bm_dst->surface_format != _sd->surface_format)
446 NVDmaStart(&_sd->Card, SURFACE_FORMAT, 1);
447 NVDmaNext(&_sd->Card, bm_dst->surface_format);
448 _sd->surface_format = bm_dst->surface_format;
449 // D(bug("[NVidia] surface_format <- %d\n", _sd->surface_format));
451 if ((bm_dst->pitch != _sd->dst_pitch) || (bm_src->pitch != _sd->src_pitch))
453 NVDmaStart(&_sd->Card, SURFACE_PITCH, 1);
454 NVDmaNext(&_sd->Card, (bm_dst->pitch << 16) | bm_src->pitch);
455 _sd->src_pitch = bm_src->pitch;
456 _sd->dst_pitch = bm_dst->pitch;
457 // D(bug("[NVidia] pitch <- %08x\n", (_sd->dst_pitch << 16) | _sd->src_pitch));
459 if (bm_src->framebuffer != _sd->src_offset)
461 NVDmaStart(&_sd->Card, SURFACE_OFFSET_SRC, 1);
462 NVDmaNext(&_sd->Card, bm_src->framebuffer);
463 _sd->src_offset = bm_src->framebuffer;
464 // D(bug("[NVidia] src_offset=%p\n", _sd->src_offset));
466 if (bm_dst->framebuffer != _sd->dst_offset)
468 NVDmaStart(&_sd->Card, SURFACE_OFFSET_DST, 1);
469 NVDmaNext(&_sd->Card, bm_dst->framebuffer);
470 _sd->dst_offset = bm_dst->framebuffer;
471 // D(bug("[NVidia] dst_offset=%p\n", _sd->dst_offset));
474 NVDmaStart(&_sd->Card, BLIT_POINT_SRC, 3);
475 NVDmaNext(&_sd->Card, (msg->srcY << 16) | (msg->srcX & 0xffff));
476 NVDmaNext(&_sd->Card, (msg->destY << 16) | (msg->destX & 0xffff));
477 NVDmaNext(&_sd->Card, (msg->height << 16) | (msg->width & 0xffff));
479 NVDmaKickoff(&_sd->Card);
480 //NVSync(_sd);
482 UNLOCK_HW
484 UNLOCK_BITMAP_BM(bm_src)
485 UNLOCK_BITMAP_BM(bm_dst)
488 else /* Case 2: different bitmaps. use Stretch engine */
490 LOCK_MULTI_BITMAP
491 LOCK_BITMAP_BM(bm_src)
492 LOCK_BITMAP_BM(bm_dst)
493 UNLOCK_MULTI_BITMAP
495 LOCK_HW
497 _sd->Card.DMAKickoffCallback = NVDMAKickoffCallback;
498 _sd->gpu_busy = TRUE;
500 if ((bm_dst->surface_format != _sd->surface_format) && bm_dst->depth != 15)
503 NVDmaStart(&_sd->Card, SURFACE_FORMAT, 1);
504 NVDmaNext(&_sd->Card, bm_dst->surface_format);
505 _sd->surface_format = bm_dst->surface_format;
506 // D(bug("[NVidia] surface_format <- %d\n", _sd->surface_format));
509 if (bm_dst->depth == 15)
511 NVDmaStart(&_sd->Card, SURFACE_FORMAT, 1);
512 NVDmaNext(&_sd->Card, SURFACE_FORMAT_DEPTH15);
513 _sd->surface_format = SURFACE_FORMAT_DEPTH16;
516 if (bm_dst->pitch != _sd->dst_pitch)
518 NVDmaStart(&_sd->Card, SURFACE_PITCH, 1);
519 NVDmaNext(&_sd->Card, (bm_dst->pitch << 16) | _sd->src_pitch);
520 _sd->dst_pitch = bm_dst->pitch;
521 // D(bug("[NVidia] pitch <- %08x\n", (_sd->dst_pitch << 16) | _sd->src_pitch));
524 if (bm_dst->framebuffer != _sd->dst_offset)
526 NVDmaStart(&_sd->Card, SURFACE_OFFSET_DST, 1);
527 NVDmaNext(&_sd->Card, bm_dst->framebuffer);
528 _sd->dst_offset = bm_dst->framebuffer;
529 // D(bug("[NVidia] dst_offset=%p\n", _sd->dst_offset));
532 NVDmaStart(&_sd->Card, RECT_SOLID_COLOR, 1);
533 NVDmaNext(&_sd->Card, 0);
535 NVDmaStart(&_sd->Card, STRETCH_BLIT_FORMAT, 1);
536 switch (bm_src->depth)
538 case 15:
539 NVDmaNext(&_sd->Card, STRETCH_BLIT_FORMAT_DEPTH15);
540 break;
541 case 16:
542 NVDmaNext(&_sd->Card, STRETCH_BLIT_FORMAT_DEPTH16);
543 break;
544 case 24:
545 NVDmaNext(&_sd->Card, STRETCH_BLIT_FORMAT_DEPTH24);
546 break;
547 default:
548 NVDmaNext(&_sd->Card, STRETCH_BLIT_FORMAT_DEPTH8);
549 break;
552 NVDmaStart(&_sd->Card, STRETCH_BLIT_CLIP_POINT, 6);
553 NVDmaNext(&_sd->Card, 0x00000000); // dst_CLip
554 NVDmaNext(&_sd->Card, 0xffffffff); // dst_Clip
555 NVDmaNext(&_sd->Card, (msg->destY << 16) | (msg->destX));// dst_y | dst_x
556 NVDmaNext(&_sd->Card, (msg->height << 16)| (msg->width));// dst_h | dst_w
557 NVDmaNext(&_sd->Card, 1 << 20); // src_w / dst_w 1:1
558 NVDmaNext(&_sd->Card, 1 << 20); // src_h / dst_h 1:1
560 NVDmaStart(&_sd->Card, STRETCH_BLIT_SRC_SIZE, 4);
561 NVDmaNext(&_sd->Card, (msg->height << 16) | (msg->width));// src_h | src_w
562 NVDmaNext(&_sd->Card,
563 (STRETCH_BLIT_SRC_FORMAT_FILTER_POINT_SAMPLE << 24) | // BILINEAR | _POINT_SAMPLE
564 (STRETCH_BLIT_SRC_FORMAT_ORIGIN_CORNER << 16) |
565 (bm_src->pitch)); // src_pitch
566 NVDmaNext(&_sd->Card, bm_src->framebuffer); // src_offset
567 NVDmaNext(&_sd->Card, ((msg->srcY << 20) & 0xffff0000)
568 | ((msg->srcX << 4) & 0xffff)); // src_y | src_x
570 NVDmaKickoff(&_sd->Card);
572 if (bm_dst->depth == 15)
574 NVDmaStart(&_sd->Card, SURFACE_FORMAT, 1);
575 NVDmaNext(&_sd->Card, SURFACE_FORMAT_DEPTH16);
577 //NVSync(_sd);
579 UNLOCK_HW
581 UNLOCK_BITMAP_BM(bm_src)
582 UNLOCK_BITMAP_BM(bm_dst)
586 D(bug("[NVidia] CopyBox(src(%p,%d:%d@%d),dst(%p,%d:%d@%d),%d:%d\n",
587 bm_src->framebuffer,msg->srcX,msg->srcY,bm_src->depth,
588 bm_dst->framebuffer,msg->destX,msg->destY,bm_dst->depth,
589 msg->width, msg->height));
591 bm_src->usecount++;
592 bm_dst->usecount++;
596 #define ToRGB555(c) \
597 (((c & 0xf80000) >> 9) | ((c & 0xf800) >> 6) | ((c & 0xf8) >> 3) | 0x8000)
599 #define ToRGB8888(alp,c) ((c) | ((alp) << 24))
601 static void TransformCursor(struct staticdata *);
603 BOOL NV__Hidd_Gfx__SetCursorShape(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_SetCursorShape *msg)
605 // bug("SetCursorShape %p\n", msg->shape);
606 // return OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
607 if (msg->shape == NULL)
609 NVShowHideCursor(_sd, 0);
610 _sd->Card.cursorVisible = 0;
612 else
614 OOP_Object *pfmt;
615 OOP_Object *colormap;
616 HIDDT_StdPixFmt pixfmt;
617 HIDDT_Color color;
619 IPTR width, height, x, y;
620 IPTR maxw,maxh;
622 ULONG *curimg = (ULONG*)((IPTR)_sd->Card.CursorStart + (IPTR)_sd->Card.FrameBuffer);
624 struct pHidd_BitMap_GetPixel __gp = {
625 mID: OOP_GetMethodID(IID_Hidd_BitMap, moHidd_BitMap_GetPixel)
626 }, *getpixel = &__gp;
628 struct pHidd_ColorMap_GetColor __gc = {
629 mID: OOP_GetMethodID(IID_Hidd_ColorMap, moHidd_ColorMap_GetColor),
630 colorReturn: &color,
631 }, *getcolor = &__gc;
633 OOP_GetAttr(msg->shape, aHidd_BitMap_Width, &width);
634 OOP_GetAttr(msg->shape, aHidd_BitMap_Height, &height);
635 OOP_GetAttr(msg->shape, aHidd_BitMap_PixFmt, (APTR)&pfmt);
636 OOP_GetAttr(pfmt, aHidd_PixFmt_StdPixFmt, &pixfmt);
637 OOP_GetAttr(msg->shape, aHidd_BitMap_ColorMap, (APTR)&colormap);
639 if (_sd->Card.alphaCursor)
641 if (width > 64) width = 64;
642 if (height > 64) height = 64;
644 maxw = 64;
645 maxh = 64;
647 else
649 if (width > 32) width = 32;
650 if (height > 32) height = 32;
652 maxw = 32;
653 maxh = 32;
656 LOCK_HW
658 for (x = 0; x < maxw*maxh; x++)
659 curimg[x] = 0;
661 for (y = 0; y < height; y++)
663 for (x = 0; x < width; x++)
665 HIDDT_Pixel pixel;
666 getpixel->x = x;
667 getpixel->y = y;
668 pixel = OOP_DoMethod(msg->shape, (OOP_Msg)getpixel);
670 if (pixfmt == vHidd_StdPixFmt_LUT8)
672 getcolor->colorNo = pixel;
673 OOP_DoMethod(colormap, (OOP_Msg)getcolor);
674 pixel = ((color.red << 8) & 0xff0000) |
675 ((color.green) & 0x00ff00) |
676 ((color.blue >> 8) & 0x0000ff);
678 curimg[maxw*2+3] = pixel ? 0x50000000 : 0x00000000;
679 if (pixel)
680 *curimg++ = pixel;
681 else curimg++;
684 for (x=width; x < maxw; x++, curimg++)
685 if (*curimg!=0x50000000) *curimg = 0;
688 for (y=height; y < maxh; y++)
689 for (x=0; x < maxw; x++)
690 { if (*curimg!=0x50000000) *curimg = 0; curimg++; }
692 UNLOCK_HW
695 TransformCursor(_sd);
696 return TRUE;
699 VOID NV__Hidd_Gfx__SetCursorVisible(OOP_Class *cl, OOP_Object *o,
700 struct pHidd_Gfx_SetCursorVisible *msg)
702 NVShowHideCursor(_sd, msg->visible);
703 _sd->Card.cursorVisible = msg->visible;
706 VOID NV__Hidd_Gfx__SetCursorPos(OOP_Class *cl, OOP_Object *o,
707 struct pHidd_Gfx_SetCursorPos *msg)
709 _sd->Card.PRAMDAC[0x0300 / 4] = (msg->y << 16) | (msg->x & 0xffff);
711 /* Class related functions */
713 #undef _sd
714 #define _sd sd
716 static void TransformCursor(struct staticdata *sd)
718 ULONG *tmp = AllocPooled(sd->memPool, 4 * 64 * 64);
719 ULONG dwords,i;
720 ULONG *curimg = (ULONG*)((IPTR)sd->Card.CursorStart + (IPTR)sd->Card.FrameBuffer);
723 if (sd->Card.alphaCursor)
725 dwords = 64*64;
726 for (i=0; i < dwords; i++)
728 UBYTE alp;
729 if (curimg[i] == 0) alp = 0;
730 else alp = 0xe0;
732 if (curimg[i] == 0x50000000) ((ULONG*)tmp)[i] = ToRGB8888(0x50,0);
733 else ((ULONG*)tmp)[i] = ToRGB8888(alp, curimg[i]);
736 else
738 dwords = (32*32) >> 1;
740 for(i=0; i < dwords; i++)
742 if (!curimg[i]) ((UWORD*)tmp)[i] = 0;
743 else ((UWORD*)tmp)[i] = ToRGB555(curimg[i]);
747 LOCK_HW
749 for (i=0; i < dwords; i++)
750 sd->Card.CURSOR[i] = tmp[i];
752 UNLOCK_HW
754 FreePooled(sd->memPool, tmp, 4*64*64);
759 Allocates some memory area on GFX card, which may be sufficient for bitmap
760 with given size and depth. The must_have bit may be defined but doesn't
761 have to. If it is TRUE, the allocator will do everything to get the memory -
762 eg. it will throw other bitmaps away from it or it will shift them within
763 GFX memory
766 IPTR AllocBitmapArea(struct staticdata *sd, ULONG width, ULONG height,
767 ULONG bpp, BOOL must_have)
769 IPTR result;
771 LOCK_HW
773 Forbid();
774 result = (IPTR)Allocate(sd->CardMem, ((width * bpp + 63) & ~63) * height);
775 Permit();
777 D(bug("[NVidia] AllocBitmapArea(%dx%d@%d) = %p\n",
778 width, height, bpp, result));
780 If Allocate failed, make the 0xffffffff as return. If it succeeded, make
781 the memory pointer relative to the begin of GFX memory
783 if (result == 0) --result;
784 else result -= (IPTR)sd->Card.FrameBuffer;
786 UNLOCK_HW
788 /* Generic thing. Will be extended later */
789 return result;
792 VOID FreeBitmapArea(struct staticdata *sd, IPTR bmp, ULONG width, ULONG height,
793 ULONG bpp)
795 APTR ptr = (APTR)(bmp + sd->Card.FrameBuffer);
797 LOCK_HW
799 D(bug("[NVidia] FreeBitmapArea(%p,%dx%d@%d)\n",
800 bmp, width, height, bpp));
802 Forbid();
803 Deallocate(sd->CardMem, ptr, ((width * bpp + 63) & ~63) * height);
804 Permit();
806 UNLOCK_HW