Added a test for MUIA_Listview_SelectChange.
[AROS.git] / workbench / hidds / nvidia / nvidiaclass.c
blobfeb77978b9bf3fea0b6f2496b1c6ddae898f38d0
1 /*
2 Copyright © 2004-2015, 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;
71 struct TagItem *tag;
72 struct TagItem *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(1400x1050_60, 121750,
191 1400, 1488, 1632, 1864,
192 1050, 1053, 1057, 1089,
193 "NVIDIA:1400x1050");
195 MAKE_SYNC(1600x1200_60, 155982,
196 1600, 1632, 1792, 2048,
197 1200, 1210, 1218, 1270,
198 "NVIDIA:1600x1200");
200 /* "new" 16:10 modes */
202 MAKE_SYNC(1280x800_60, 83530,
203 1280, 1344, 1480, 1680,
204 800, 801, 804, 828,
205 "NVIDIA:1280x800");
207 MAKE_SYNC(1440x900_60, 106470,
208 1440, 1520, 1672, 1904,
209 900, 901, 904, 932,
210 "NVIDIA:1440x900");
212 MAKE_SYNC(1680x1050_60, 119000,
213 1680, 1728, 1760, 1840,
214 1050, 1053, 1059, 1080,
215 "NVIDIA:1680x1050");
217 MAKE_SYNC(1920x1080_60, 173000,
218 1920, 2048, 2248, 2576,
219 1080, 1083, 1088, 1120,
220 "NVIDIA:1920x1080");
222 MAKE_SYNC(1920x1200_60, 162090,
223 1920, 1984, 2176, 2480,
224 1200, 1201, 1204, 1250,
225 "NVIDIA:1920x1200");
227 struct TagItem modetags[] = {
228 { aHidd_Gfx_PixFmtTags, (IPTR)pftags_24bpp },
229 { aHidd_Gfx_PixFmtTags, (IPTR)pftags_16bpp },
230 { aHidd_Gfx_PixFmtTags, (IPTR)pftags_15bpp },
231 { aHidd_Gfx_SyncTags, (IPTR)sync_640x480_60 },
232 { aHidd_Gfx_SyncTags, (IPTR)sync_800x600_56 },
233 { aHidd_Gfx_SyncTags, (IPTR)sync_1024x768_60 },
234 { aHidd_Gfx_SyncTags, (IPTR)sync_1152x864_60 },
235 { aHidd_Gfx_SyncTags, (IPTR)sync_1280x1024_60 },
236 { aHidd_Gfx_SyncTags, (IPTR)sync_1400x1050_60 },
237 { aHidd_Gfx_SyncTags, (IPTR)sync_1600x1200_60 },
238 { aHidd_Gfx_SyncTags, (IPTR)sync_1280x800_60 },
239 { aHidd_Gfx_SyncTags, (IPTR)sync_1440x900_60 },
240 { aHidd_Gfx_SyncTags, (IPTR)sync_1680x1050_60 },
241 { aHidd_Gfx_SyncTags, (IPTR)sync_1920x1080_60 },
242 { aHidd_Gfx_SyncTags, (IPTR)sync_1920x1200_60 },
244 { TAG_DONE, 0UL }
247 struct TagItem mytags[] = {
248 { aHidd_Gfx_ModeTags, (IPTR)modetags },
249 { TAG_MORE, (IPTR)msg->attrList }
252 struct pRoot_New mymsg;
254 mymsg.mID = msg->mID;
255 mymsg.attrList = mytags;
257 msg = &mymsg;
259 EnterFunc(bug("[NVidia] nv::new()\n"));
261 o = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
262 if (o)
264 _sd->nvobject = o;
267 return o;
270 OOP_Object *NV__Hidd_Gfx__CreateObject(OOP_Class *cl, OOP_Object *o,
271 struct pHidd_Gfx_CreateObject *msg)
273 OOP_Object *object = NULL;
275 if (msg->cl == _sd->basebm)
277 BOOL displayable, framebuffer;
278 OOP_Class *classptr = NULL;
279 struct TagItem mytags[] =
281 { TAG_IGNORE, TAG_IGNORE }, /* Placeholder for aHidd_BitMap_ClassPtr */
282 { TAG_MORE, (IPTR)msg->attrList }
285 struct pHidd_Gfx_CreateObject p;
287 /* Displayable bitmap ? */
288 displayable = GetTagData(aHidd_BitMap_Displayable, FALSE, msg->attrList);
289 framebuffer = GetTagData(aHidd_BitMap_FrameBuffer, FALSE, msg->attrList);
291 D(bug("[NVidia] CreateObject: framebuffer=%d, displayable=%d\n", framebuffer, displayable));
293 if (framebuffer)
295 /* If the user asks for a framebuffer map we must ALLWAYS supply a class */
296 classptr = _sd->onbmclass;
298 else if (displayable)
300 classptr = _sd->onbmclass; //offbmclass;
302 else
304 HIDDT_ModeID modeid;
306 For the non-displayable case we can either supply a class ourselves
307 if we can optimize a certain type of non-displayable bitmaps. Or we
308 can let the superclass create on for us.
310 The attributes that might come from the user deciding the bitmap
311 pixel format are:
312 - aHidd_BitMap_ModeID: a modeid. create a nondisplayable
313 bitmap with the size and pixelformat of a gfxmode.
314 - aHidd_BitMap_StdPixFmt: a standard pixelformat as described in
315 hidd/graphics.h
316 - aHidd_BitMap_Friend: if this is supplied and none of the two above
317 are supplied, then the pixel format of the created bitmap
318 will be the same as the one of the friend bitmap.
320 These tags are listed in prioritized order, so if
321 the user supplied a ModeID tag, then you should not care about StdPixFmt
322 or Friend. If there is no ModeID, but a StdPixFmt tag supplied,
323 then you should not care about Friend because you have to
324 create the correct pixelformat. And as said above, if only Friend
325 is supplied, you can create a bitmap with same pixelformat as Frien
329 modeid = (HIDDT_ModeID)GetTagData(aHidd_BitMap_ModeID, vHidd_ModeID_Invalid, msg->attrList);
330 if (vHidd_ModeID_Invalid != modeid) {
331 /* User supplied a valid modeid. We can use our offscreen class */
332 classptr = _sd->offbmclass;
333 } else {
334 /* We may create an offscreen bitmap if the user supplied a friend
335 bitmap. But we need to check that he did not supplied a StdPixFmt
337 HIDDT_StdPixFmt stdpf;
338 stdpf = (HIDDT_StdPixFmt)GetTagData(aHidd_BitMap_StdPixFmt, vHidd_StdPixFmt_Unknown, msg->attrList);
339 if (vHidd_StdPixFmt_Plane == stdpf) {
340 classptr = _sd->planarbmclass;
342 else if (vHidd_StdPixFmt_Unknown == stdpf) {
343 /* No std pixfmt supplied */
344 OOP_Object *friend;
346 /* Did the user supply a friend bitmap ? */
347 friend = (OOP_Object *)GetTagData(aHidd_BitMap_Friend, 0, msg->attrList);
348 if (NULL != friend) {
349 OOP_Class *friend_class = NULL;
350 /* User supplied friend bitmap. Is the friend bitmap a
351 NVidia Gfx hidd bitmap ? */
352 OOP_GetAttr(friend, aHidd_BitMap_ClassPtr, (APTR)&friend_class);
353 if (friend_class == _sd->onbmclass) {
354 /* Friend was NVidia hidd bitmap. Now we can supply our own class */
355 classptr = _sd->offbmclass;
362 D(bug("classptr = %p\n", classptr));
363 /* Do we supply our own class ? */
364 if (NULL != classptr) {
365 /* Yes. We must let the superclass not that we do this. This is
366 done through adding a tag in the frot of the taglist */
367 mytags[0].ti_Tag = aHidd_BitMap_ClassPtr;
368 mytags[0].ti_Data = (IPTR)classptr;
371 /* Like in Gfx::New() we init a new message struct */
372 p.mID = msg->mID;
373 p.cl = msg->cl;
374 p.attrList = mytags;
376 /* Pass the new message to the superclass */
377 object = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)&p);
379 else
380 object = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
382 return object;
385 OOP_Object *NV__Hidd_Gfx__Show(OOP_Class *cl, OOP_Object *o,
386 struct pHidd_Gfx_Show *msg)
388 OOP_Object *fb = NULL;
389 if (msg->bitMap)
391 nvBitMap *bm = OOP_INST_DATA(OOP_OCLASS(msg->bitMap), msg->bitMap);
393 if (bm->state)
395 /* Suppose bm has properly allocated state structure */
396 if (bm->fbgfx)
398 bm->usecount++;
400 LOCK_HW
402 LoadState(_sd, bm->state);
403 DPMS(_sd, _sd->dpms);
405 fb = bm->BitMap;
406 NVShowHideCursor(_sd, _sd->Card.cursorVisible);
408 UNLOCK_HW
413 if (!fb)
414 fb = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
416 return fb;
419 VOID NV__Hidd_Gfx__CopyBox(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_CopyBox *msg)
421 ULONG mode = GC_DRMD(msg->gc);
422 IPTR src=0, dst=0;
424 /* Check whether we can get Drawable attribute of our nVidia class */
425 OOP_GetAttr(msg->src, aHidd_nvBitMap_Drawable, &src);
426 OOP_GetAttr(msg->dest, aHidd_nvBitMap_Drawable, &dst);
428 if (!dst || !src)
430 /* No. One of the bitmaps is not nVidia bitmap */
431 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
433 else
435 /* Yes. Get the instance data of both bitmaps */
436 nvBitMap *bm_src = OOP_INST_DATA(OOP_OCLASS(msg->src), msg->src);
437 nvBitMap *bm_dst = OOP_INST_DATA(OOP_OCLASS(msg->dest), msg->dest);
439 /* Case -1: (To be fixed) one of the bitmaps have chunky outside GFX mem */
440 if (!bm_src->fbgfx || !bm_dst->fbgfx)
442 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
444 /* Case 0: one of bitmaps is 8bpp, whereas the other is TrueColor one */
445 else if ((bm_src->depth <= 8 || bm_dst->depth <= 8) &&
446 (bm_src->depth != bm_dst->depth))
448 /* Unsupported case */
449 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
450 return;
452 /* Case 1: both bitmaps have the same depth - use Blit engine */
453 else if (bm_src->depth == bm_dst->depth)
455 LOCK_MULTI_BITMAP
456 LOCK_BITMAP_BM(bm_src)
457 LOCK_BITMAP_BM(bm_dst)
458 UNLOCK_MULTI_BITMAP
460 LOCK_HW
462 _sd->Card.DMAKickoffCallback = NVDMAKickoffCallback;
463 _sd->gpu_busy = TRUE;
465 NVSetRopSolid(_sd, mode, ~0 << bm_src->depth);
467 if (bm_dst->surface_format != _sd->surface_format)
469 NVDmaStart(&_sd->Card, SURFACE_FORMAT, 1);
470 NVDmaNext(&_sd->Card, bm_dst->surface_format);
471 _sd->surface_format = bm_dst->surface_format;
472 // D(bug("[NVidia] surface_format <- %d\n", _sd->surface_format));
474 if ((bm_dst->pitch != _sd->dst_pitch) || (bm_src->pitch != _sd->src_pitch))
476 NVDmaStart(&_sd->Card, SURFACE_PITCH, 1);
477 NVDmaNext(&_sd->Card, (bm_dst->pitch << 16) | bm_src->pitch);
478 _sd->src_pitch = bm_src->pitch;
479 _sd->dst_pitch = bm_dst->pitch;
480 // D(bug("[NVidia] pitch <- %08x\n", (_sd->dst_pitch << 16) | _sd->src_pitch));
482 if (bm_src->framebuffer != _sd->src_offset)
484 NVDmaStart(&_sd->Card, SURFACE_OFFSET_SRC, 1);
485 NVDmaNext(&_sd->Card, bm_src->framebuffer);
486 _sd->src_offset = bm_src->framebuffer;
487 // D(bug("[NVidia] src_offset=%p\n", _sd->src_offset));
489 if (bm_dst->framebuffer != _sd->dst_offset)
491 NVDmaStart(&_sd->Card, SURFACE_OFFSET_DST, 1);
492 NVDmaNext(&_sd->Card, bm_dst->framebuffer);
493 _sd->dst_offset = bm_dst->framebuffer;
494 // D(bug("[NVidia] dst_offset=%p\n", _sd->dst_offset));
497 NVDmaStart(&_sd->Card, BLIT_POINT_SRC, 3);
498 NVDmaNext(&_sd->Card, (msg->srcY << 16) | (msg->srcX & 0xffff));
499 NVDmaNext(&_sd->Card, (msg->destY << 16) | (msg->destX & 0xffff));
500 NVDmaNext(&_sd->Card, (msg->height << 16) | (msg->width & 0xffff));
502 NVDmaKickoff(&_sd->Card);
503 //NVSync(_sd);
505 UNLOCK_HW
507 UNLOCK_BITMAP_BM(bm_src)
508 UNLOCK_BITMAP_BM(bm_dst)
511 else /* Case 2: different bitmaps. use Stretch engine */
513 LOCK_MULTI_BITMAP
514 LOCK_BITMAP_BM(bm_src)
515 LOCK_BITMAP_BM(bm_dst)
516 UNLOCK_MULTI_BITMAP
518 LOCK_HW
520 _sd->Card.DMAKickoffCallback = NVDMAKickoffCallback;
521 _sd->gpu_busy = TRUE;
523 if ((bm_dst->surface_format != _sd->surface_format) && bm_dst->depth != 15)
526 NVDmaStart(&_sd->Card, SURFACE_FORMAT, 1);
527 NVDmaNext(&_sd->Card, bm_dst->surface_format);
528 _sd->surface_format = bm_dst->surface_format;
529 // D(bug("[NVidia] surface_format <- %d\n", _sd->surface_format));
532 if (bm_dst->depth == 15)
534 NVDmaStart(&_sd->Card, SURFACE_FORMAT, 1);
535 NVDmaNext(&_sd->Card, SURFACE_FORMAT_DEPTH15);
536 _sd->surface_format = SURFACE_FORMAT_DEPTH16;
539 if (bm_dst->pitch != _sd->dst_pitch)
541 NVDmaStart(&_sd->Card, SURFACE_PITCH, 1);
542 NVDmaNext(&_sd->Card, (bm_dst->pitch << 16) | _sd->src_pitch);
543 _sd->dst_pitch = bm_dst->pitch;
544 // D(bug("[NVidia] pitch <- %08x\n", (_sd->dst_pitch << 16) | _sd->src_pitch));
547 if (bm_dst->framebuffer != _sd->dst_offset)
549 NVDmaStart(&_sd->Card, SURFACE_OFFSET_DST, 1);
550 NVDmaNext(&_sd->Card, bm_dst->framebuffer);
551 _sd->dst_offset = bm_dst->framebuffer;
552 // D(bug("[NVidia] dst_offset=%p\n", _sd->dst_offset));
555 NVDmaStart(&_sd->Card, RECT_SOLID_COLOR, 1);
556 NVDmaNext(&_sd->Card, 0);
558 NVDmaStart(&_sd->Card, STRETCH_BLIT_FORMAT, 1);
559 switch (bm_src->depth)
561 case 15:
562 NVDmaNext(&_sd->Card, STRETCH_BLIT_FORMAT_DEPTH15);
563 break;
564 case 16:
565 NVDmaNext(&_sd->Card, STRETCH_BLIT_FORMAT_DEPTH16);
566 break;
567 case 24:
568 NVDmaNext(&_sd->Card, STRETCH_BLIT_FORMAT_DEPTH24);
569 break;
570 default:
571 NVDmaNext(&_sd->Card, STRETCH_BLIT_FORMAT_DEPTH8);
572 break;
575 NVDmaStart(&_sd->Card, STRETCH_BLIT_CLIP_POINT, 6);
576 NVDmaNext(&_sd->Card, 0x00000000); // dst_CLip
577 NVDmaNext(&_sd->Card, 0xffffffff); // dst_Clip
578 NVDmaNext(&_sd->Card, (msg->destY << 16) | (msg->destX));// dst_y | dst_x
579 NVDmaNext(&_sd->Card, (msg->height << 16)| (msg->width));// dst_h | dst_w
580 NVDmaNext(&_sd->Card, 1 << 20); // src_w / dst_w 1:1
581 NVDmaNext(&_sd->Card, 1 << 20); // src_h / dst_h 1:1
583 NVDmaStart(&_sd->Card, STRETCH_BLIT_SRC_SIZE, 4);
584 NVDmaNext(&_sd->Card, (msg->height << 16) | (msg->width));// src_h | src_w
585 NVDmaNext(&_sd->Card,
586 (STRETCH_BLIT_SRC_FORMAT_FILTER_POINT_SAMPLE << 24) | // BILINEAR | _POINT_SAMPLE
587 (STRETCH_BLIT_SRC_FORMAT_ORIGIN_CORNER << 16) |
588 (bm_src->pitch)); // src_pitch
589 NVDmaNext(&_sd->Card, bm_src->framebuffer); // src_offset
590 NVDmaNext(&_sd->Card, ((msg->srcY << 20) & 0xffff0000)
591 | ((msg->srcX << 4) & 0xffff)); // src_y | src_x
593 NVDmaKickoff(&_sd->Card);
595 if (bm_dst->depth == 15)
597 NVDmaStart(&_sd->Card, SURFACE_FORMAT, 1);
598 NVDmaNext(&_sd->Card, SURFACE_FORMAT_DEPTH16);
600 //NVSync(_sd);
602 UNLOCK_HW
604 UNLOCK_BITMAP_BM(bm_src)
605 UNLOCK_BITMAP_BM(bm_dst)
609 D(bug("[NVidia] CopyBox(src(%p,%d:%d@%d),dst(%p,%d:%d@%d),%d:%d\n",
610 bm_src->framebuffer,msg->srcX,msg->srcY,bm_src->depth,
611 bm_dst->framebuffer,msg->destX,msg->destY,bm_dst->depth,
612 msg->width, msg->height));
614 bm_src->usecount++;
615 bm_dst->usecount++;
619 #define ToRGB555(c) \
620 (((c & 0xf80000) >> 9) | ((c & 0xf800) >> 6) | ((c & 0xf8) >> 3) | ((c & 0xFF000000) ? 0x8000 : 0))
622 /* Do we miss similar definition in include/hidd/graphics.h ? */
623 #if AROS_BIG_ENDIAN
624 #define Machine_ARGB32 vHidd_StdPixFmt_ARGB32
625 #else
626 #define Machine_ARGB32 vHidd_StdPixFmt_BGRA32
627 #endif
629 BOOL NV__Hidd_Gfx__SetCursorShape(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_SetCursorShape *msg)
631 if (msg->shape == NULL)
633 NVShowHideCursor(_sd, 0);
634 _sd->Card.cursorVisible = 0;
635 return TRUE;
637 else
639 IPTR width, height, x;
641 OOP_GetAttr(msg->shape, aHidd_BitMap_Width, &width);
642 OOP_GetAttr(msg->shape, aHidd_BitMap_Height, &height);
644 if (_sd->Card.alphaCursor)
646 ULONG *curimg = (ULONG *)_sd->Card.CURSOR;
648 if (width > 64) width = 64;
649 if (height > 64) height = 64;
651 LOCK_HW
653 /* Clear the matrix */
654 for (x = 0; x < 64*64; x++)
655 curimg[x] = 0;
657 /* Get data from the bitmap */
658 HIDD_BM_GetImage(msg->shape, (UBYTE *)curimg, 64*4, 0, 0, width, height, Machine_ARGB32);
660 UNLOCK_HW
661 return TRUE;
663 else
665 ULONG *tmp;
666 UWORD *curimg = (UWORD *)_sd->Card.CURSOR;
668 if (width > 32) width = 32;
669 if (height > 32) height = 32;
671 /* Allocate a temporary buffer. It will be cleared because the pool was created with MEMF_CLEAR */
672 tmp = AllocPooled(_sd->memPool, 4 * 32 * 32);
673 if (tmp) {
674 /* Get data from the bitmap, we need alpha channel too */
675 HIDD_BM_GetImage(msg->shape, (UBYTE *)tmp, 4 * 32, 0, 0, width, height, Machine_ARGB32);
677 LOCK_HW
679 /* Now convert the data */
680 for (x = 0; x < 32*32; x++)
681 curimg[x] = ToRGB555(tmp[x]);
683 UNLOCK_HW
685 FreePooled(_sd->memPool, tmp, 4 * 32 * 32);
686 return TRUE;
687 } else
688 return FALSE;
694 VOID NV__Hidd_Gfx__SetCursorVisible(OOP_Class *cl, OOP_Object *o,
695 struct pHidd_Gfx_SetCursorVisible *msg)
697 NVShowHideCursor(_sd, msg->visible);
698 _sd->Card.cursorVisible = msg->visible;
701 VOID NV__Hidd_Gfx__SetCursorPos(OOP_Class *cl, OOP_Object *o,
702 struct pHidd_Gfx_SetCursorPos *msg)
704 _sd->Card.PRAMDAC[0x0300 / 4] = (msg->y << 16) | (msg->x & 0xffff);
706 /* Class related functions */
708 #undef _sd
709 #define _sd sd
712 Allocates some memory area on GFX card, which may be sufficient for bitmap
713 with given size and depth. The must_have bit may be defined but doesn't
714 have to. If it is TRUE, the allocator will do everything to get the memory -
715 eg. it will throw other bitmaps away from it or it will shift them within
716 GFX memory
719 IPTR AllocBitmapArea(struct staticdata *sd, ULONG width, ULONG height,
720 ULONG bpp, BOOL must_have)
722 IPTR result;
724 LOCK_HW
726 Forbid();
727 result = (IPTR)Allocate(sd->CardMem, ((width * bpp + 63) & ~63) * height);
728 Permit();
730 D(bug("[NVidia] AllocBitmapArea(%dx%d@%d) = %p\n",
731 width, height, bpp, result));
733 If Allocate failed, make the 0xffffffff as return. If it succeeded, make
734 the memory pointer relative to the begin of GFX memory
736 if (result == 0) --result;
737 else result -= (IPTR)sd->Card.FrameBuffer;
739 UNLOCK_HW
741 /* Generic thing. Will be extended later */
742 return result;
745 VOID FreeBitmapArea(struct staticdata *sd, IPTR bmp, ULONG width, ULONG height,
746 ULONG bpp)
748 APTR ptr = (APTR)(bmp + sd->Card.FrameBuffer);
750 LOCK_HW
752 D(bug("[NVidia] FreeBitmapArea(%p,%dx%d@%d)\n",
753 bmp, width, height, bpp));
755 Forbid();
756 Deallocate(sd->CardMem, ptr, ((width * bpp + 63) & ~63) * height);
757 Permit();
759 UNLOCK_HW