revert between 56095 -> 55830 in arch
[AROS.git] / workbench / hidds / nvidia / nvidiaclass.c
blobd109b18a5c3a47f5a6df561f921c1e9e303b5d94
1 /*
2 Copyright © 2004-2017, 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/gfx.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 HiddAttrBase
29 #undef HiddGfxAttrBase
30 #undef HiddPixFmtAttrBase
31 #undef HiddSyncAttrBase
32 #undef HiddBitMapAttrBase
33 #define HiddPCIDeviceAttrBase (_sd->pciAttrBase)
34 #define HiddAttrBase (_sd->hiddAttrBase)
35 #define HiddNVidiaBitMapAttrBase (_sd->nvBitMapAttrBase)
36 #define HiddBitMapAttrBase (_sd->bitMapAttrBase)
37 #define HiddPixFmtAttrBase (_sd->pixFmtAttrBase)
38 #define HiddGfxAttrBase (_sd->gfxAttrBase)
39 #define HiddSyncAttrBase (_sd->syncAttrBase)
41 /* Class methods */
43 VOID NV__Root__Get(OOP_Class *cl, OOP_Object *o, struct pRoot_Get *msg)
45 ULONG idx;
46 BOOL found = FALSE;
47 if (IS_GFX_ATTR(msg->attrID, idx))
49 switch (idx)
51 case aoHidd_Gfx_SupportsHWCursor:
52 *msg->storage = (IPTR)TRUE;
53 found = TRUE;
54 break;
56 case aoHidd_Gfx_DPMSLevel:
57 *msg->storage = _sd->dpms;
58 found = TRUE;
59 break;
63 if (!found)
64 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
66 return;
69 VOID NV__Root__Set(OOP_Class *cl, OOP_Object *o, struct pRoot_Set *msg)
71 ULONG idx;
73 struct TagItem *tag;
74 struct TagItem *tags = msg->attrList;
76 while ((tag = NextTagItem(&tags)))
78 if (IS_GFX_ATTR(tag->ti_Tag, idx))
80 switch(idx)
82 case aoHidd_Gfx_DPMSLevel:
83 LOCK_HW
85 DPMS(_sd, tag->ti_Data);
86 _sd->dpms = tag->ti_Data;
88 UNLOCK_HW
89 break;
94 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
97 #define MAKE_SYNC(name,clock,hdisp,hstart,hend,htotal,vdisp,vstart,vend,vtotal,descr) \
98 struct TagItem sync_ ## name[]={ \
99 { aHidd_Sync_PixelClock, clock*1000 }, \
100 { aHidd_Sync_HDisp, hdisp }, \
101 { aHidd_Sync_HSyncStart, hstart }, \
102 { aHidd_Sync_HSyncEnd, hend }, \
103 { aHidd_Sync_HTotal, htotal }, \
104 { aHidd_Sync_VDisp, vdisp }, \
105 { aHidd_Sync_VSyncStart, vstart }, \
106 { aHidd_Sync_VSyncEnd, vend }, \
107 { aHidd_Sync_VTotal, vtotal }, \
108 { aHidd_Sync_Description, (IPTR)descr}, \
109 { TAG_DONE, 0UL }}
111 OOP_Object *NV__Root__New(OOP_Class *cl, OOP_Object *o, struct pRoot_New *msg)
113 struct TagItem pftags_24bpp[] = {
114 { aHidd_PixFmt_RedShift, 8 }, /* 0 */
115 { aHidd_PixFmt_GreenShift, 16 }, /* 1 */
116 { aHidd_PixFmt_BlueShift, 24 }, /* 2 */
117 { aHidd_PixFmt_AlphaShift, 0 }, /* 3 */
118 { aHidd_PixFmt_RedMask, 0x00ff0000 }, /* 4 */
119 { aHidd_PixFmt_GreenMask, 0x0000ff00 }, /* 5 */
120 { aHidd_PixFmt_BlueMask, 0x000000ff }, /* 6 */
121 { aHidd_PixFmt_AlphaMask, 0x00000000 }, /* 7 */
122 { aHidd_PixFmt_ColorModel, vHidd_ColorModel_TrueColor }, /* 8 */
123 { aHidd_PixFmt_Depth, 24 }, /* 9 */
124 { aHidd_PixFmt_BytesPerPixel, 4 }, /* 10 */
125 { aHidd_PixFmt_BitsPerPixel, 24 }, /* 11 */
126 { aHidd_PixFmt_StdPixFmt, vHidd_StdPixFmt_BGR032 }, /* 12 Native */
127 { aHidd_PixFmt_BitMapType, vHidd_BitMapType_Chunky }, /* 15 */
128 { TAG_DONE, 0UL }
131 struct TagItem pftags_16bpp[] = {
132 { aHidd_PixFmt_RedShift, 16 }, /* 0 */
133 { aHidd_PixFmt_GreenShift, 21 }, /* 1 */
134 { aHidd_PixFmt_BlueShift, 27 }, /* 2 */
135 { aHidd_PixFmt_AlphaShift, 0 }, /* 3 */
136 { aHidd_PixFmt_RedMask, 0x0000f800 }, /* 4 */
137 { aHidd_PixFmt_GreenMask, 0x000007e0 }, /* 5 */
138 { aHidd_PixFmt_BlueMask, 0x0000001f }, /* 6 */
139 { aHidd_PixFmt_AlphaMask, 0x00000000 }, /* 7 */
140 { aHidd_PixFmt_ColorModel, vHidd_ColorModel_TrueColor }, /* 8 */
141 { aHidd_PixFmt_Depth, 16 }, /* 9 */
142 { aHidd_PixFmt_BytesPerPixel, 2 }, /* 10 */
143 { aHidd_PixFmt_BitsPerPixel, 16 }, /* 11 */
144 { aHidd_PixFmt_StdPixFmt, vHidd_StdPixFmt_RGB16_LE }, /* 12 */
145 { aHidd_PixFmt_BitMapType, vHidd_BitMapType_Chunky }, /* 15 */
146 { TAG_DONE, 0UL }
149 struct TagItem pftags_15bpp[] = {
150 { aHidd_PixFmt_RedShift, 17 }, /* 0 */
151 { aHidd_PixFmt_GreenShift, 22 }, /* 1 */
152 { aHidd_PixFmt_BlueShift, 27 }, /* 2 */
153 { aHidd_PixFmt_AlphaShift, 0 }, /* 3 */
154 { aHidd_PixFmt_RedMask, 0x00007c00 }, /* 4 */
155 { aHidd_PixFmt_GreenMask, 0x000003e0 }, /* 5 */
156 { aHidd_PixFmt_BlueMask, 0x0000001f }, /* 6 */
157 { aHidd_PixFmt_AlphaMask, 0x00000000 }, /* 7 */
158 { aHidd_PixFmt_ColorModel, vHidd_ColorModel_TrueColor }, /* 8 */
159 { aHidd_PixFmt_Depth, 15 }, /* 9 */
160 { aHidd_PixFmt_BytesPerPixel, 2 }, /* 10 */
161 { aHidd_PixFmt_BitsPerPixel, 15 }, /* 11 */
162 { aHidd_PixFmt_StdPixFmt, vHidd_StdPixFmt_RGB15_LE }, /* 12 */
163 { aHidd_PixFmt_BitMapType, vHidd_BitMapType_Chunky }, /* 15 */
164 { TAG_DONE, 0UL }
167 MAKE_SYNC(640x480_60, 25174,
168 640, 656, 752, 800,
169 480, 490, 492, 525,
170 "NVIDIA:640x480");
172 MAKE_SYNC(800x600_56, 36000, // 36000
173 800, 824, 896, 1024,
174 600, 601, 603, 625,
175 "NVIDIA:800x600");
177 MAKE_SYNC(1024x768_60, 65000, //78654=60kHz, 75Hz. 65000=50kHz,62Hz
178 1024, 1048, 1184, 1344,
179 768, 771, 777, 806,
180 "NVIDIA:1024x768");
182 MAKE_SYNC(1152x864_60, 80000,
183 1152, 1216, 1328, 1456,
184 864, 870, 875, 916,
185 "NVIDIA:1152x864");
187 MAKE_SYNC(1280x1024_60, 107991,
188 1280, 1328, 1440, 1688,
189 1024, 1025, 1028, 1066,
190 "NVIDIA:1280x1024");
192 MAKE_SYNC(1400x1050_60, 121750,
193 1400, 1488, 1632, 1864,
194 1050, 1053, 1057, 1089,
195 "NVIDIA:1400x1050");
197 MAKE_SYNC(1600x1200_60, 155982,
198 1600, 1632, 1792, 2048,
199 1200, 1210, 1218, 1270,
200 "NVIDIA:1600x1200");
202 /* "new" 16:10 modes */
204 MAKE_SYNC(1280x800_60, 83530,
205 1280, 1344, 1480, 1680,
206 800, 801, 804, 828,
207 "NVIDIA:1280x800");
209 MAKE_SYNC(1440x900_60, 106470,
210 1440, 1520, 1672, 1904,
211 900, 901, 904, 932,
212 "NVIDIA:1440x900");
214 MAKE_SYNC(1680x1050_60, 119000,
215 1680, 1728, 1760, 1840,
216 1050, 1053, 1059, 1080,
217 "NVIDIA:1680x1050");
219 MAKE_SYNC(1920x1080_60, 173000,
220 1920, 2048, 2248, 2576,
221 1080, 1083, 1088, 1120,
222 "NVIDIA:1920x1080");
224 MAKE_SYNC(1920x1200_60, 162090,
225 1920, 1984, 2176, 2480,
226 1200, 1201, 1204, 1250,
227 "NVIDIA:1920x1200");
229 struct TagItem modetags[] = {
230 { aHidd_Gfx_PixFmtTags, (IPTR)pftags_24bpp },
231 { aHidd_Gfx_PixFmtTags, (IPTR)pftags_16bpp },
232 { aHidd_Gfx_PixFmtTags, (IPTR)pftags_15bpp },
233 { aHidd_Gfx_SyncTags, (IPTR)sync_640x480_60 },
234 { aHidd_Gfx_SyncTags, (IPTR)sync_800x600_56 },
235 { aHidd_Gfx_SyncTags, (IPTR)sync_1024x768_60 },
236 { aHidd_Gfx_SyncTags, (IPTR)sync_1152x864_60 },
237 { aHidd_Gfx_SyncTags, (IPTR)sync_1280x1024_60 },
238 { aHidd_Gfx_SyncTags, (IPTR)sync_1400x1050_60 },
239 { aHidd_Gfx_SyncTags, (IPTR)sync_1600x1200_60 },
240 { aHidd_Gfx_SyncTags, (IPTR)sync_1280x800_60 },
241 { aHidd_Gfx_SyncTags, (IPTR)sync_1440x900_60 },
242 { aHidd_Gfx_SyncTags, (IPTR)sync_1680x1050_60 },
243 { aHidd_Gfx_SyncTags, (IPTR)sync_1920x1080_60 },
244 { aHidd_Gfx_SyncTags, (IPTR)sync_1920x1200_60 },
246 { TAG_DONE, 0UL }
249 struct TagItem mytags[] = {
250 { aHidd_Gfx_ModeTags, (IPTR)modetags },
251 { aHidd_Name , (IPTR)"Nvidia" },
252 { aHidd_HardwareName , (IPTR)"Nvidia Gfx Adaptor" },
253 { aHidd_ProducerName , (IPTR)"Nvidia Corporation" },
254 { TAG_MORE, (IPTR)msg->attrList }
257 struct pRoot_New mymsg;
259 mymsg.mID = msg->mID;
260 mymsg.attrList = mytags;
262 msg = &mymsg;
264 EnterFunc(bug("[NVidia] nv::new()\n"));
266 o = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
267 if (o)
269 _sd->nvobject = o;
272 return o;
275 OOP_Object *NV__Hidd_Gfx__CreateObject(OOP_Class *cl, OOP_Object *o,
276 struct pHidd_Gfx_CreateObject *msg)
278 OOP_Object *object = NULL;
280 if (msg->cl == _sd->basebm)
282 BOOL displayable, framebuffer;
283 OOP_Class *classptr = NULL;
284 struct TagItem mytags[] =
286 { TAG_IGNORE, TAG_IGNORE }, /* Placeholder for aHidd_BitMap_ClassPtr */
287 { TAG_MORE, (IPTR)msg->attrList }
290 struct pHidd_Gfx_CreateObject p;
292 /* Displayable bitmap ? */
293 displayable = GetTagData(aHidd_BitMap_Displayable, FALSE, msg->attrList);
294 framebuffer = GetTagData(aHidd_BitMap_FrameBuffer, FALSE, msg->attrList);
296 D(bug("[NVidia] CreateObject: framebuffer=%d, displayable=%d\n", framebuffer, displayable));
298 if (framebuffer)
300 /* If the user asks for a framebuffer map we must ALLWAYS supply a class */
301 classptr = _sd->onbmclass;
303 else if (displayable)
305 classptr = _sd->onbmclass; //offbmclass;
307 else
309 HIDDT_ModeID modeid;
311 For the non-displayable case we can either supply a class ourselves
312 if we can optimize a certain type of non-displayable bitmaps. Or we
313 can let the superclass create on for us.
315 The attributes that might come from the user deciding the bitmap
316 pixel format are:
317 - aHidd_BitMap_ModeID: a modeid. create a nondisplayable
318 bitmap with the size and pixelformat of a gfxmode.
319 - aHidd_BitMap_StdPixFmt: a standard pixelformat as described in
320 hidd/graphics.h
321 - aHidd_BitMap_Friend: if this is supplied and none of the two above
322 are supplied, then the pixel format of the created bitmap
323 will be the same as the one of the friend bitmap.
325 These tags are listed in prioritized order, so if
326 the user supplied a ModeID tag, then you should not care about StdPixFmt
327 or Friend. If there is no ModeID, but a StdPixFmt tag supplied,
328 then you should not care about Friend because you have to
329 create the correct pixelformat. And as said above, if only Friend
330 is supplied, you can create a bitmap with same pixelformat as Frien
334 modeid = (HIDDT_ModeID)GetTagData(aHidd_BitMap_ModeID, vHidd_ModeID_Invalid, msg->attrList);
335 if (vHidd_ModeID_Invalid != modeid) {
336 /* User supplied a valid modeid. We can use our offscreen class */
337 classptr = _sd->offbmclass;
338 } else {
339 /* We may create an offscreen bitmap if the user supplied a friend
340 bitmap. But we need to check that he did not supplied a StdPixFmt
342 HIDDT_StdPixFmt stdpf;
343 stdpf = (HIDDT_StdPixFmt)GetTagData(aHidd_BitMap_StdPixFmt, vHidd_StdPixFmt_Unknown, msg->attrList);
344 if (vHidd_StdPixFmt_Plane == stdpf) {
345 classptr = _sd->planarbmclass;
347 else if (vHidd_StdPixFmt_Unknown == stdpf) {
348 /* No std pixfmt supplied */
349 OOP_Object *friend;
351 /* Did the user supply a friend bitmap ? */
352 friend = (OOP_Object *)GetTagData(aHidd_BitMap_Friend, 0, msg->attrList);
353 if (NULL != friend) {
354 OOP_Class *friend_class = NULL;
355 /* User supplied friend bitmap. Is the friend bitmap a
356 NVidia Gfx hidd bitmap ? */
357 OOP_GetAttr(friend, aHidd_BitMap_ClassPtr, (APTR)&friend_class);
358 if (friend_class == _sd->onbmclass) {
359 /* Friend was NVidia hidd bitmap. Now we can supply our own class */
360 classptr = _sd->offbmclass;
367 D(bug("classptr = %p\n", classptr));
368 /* Do we supply our own class ? */
369 if (NULL != classptr) {
370 /* Yes. We must let the superclass not that we do this. This is
371 done through adding a tag in the frot of the taglist */
372 mytags[0].ti_Tag = aHidd_BitMap_ClassPtr;
373 mytags[0].ti_Data = (IPTR)classptr;
376 /* Like in Gfx::New() we init a new message struct */
377 p.mID = msg->mID;
378 p.cl = msg->cl;
379 p.attrList = mytags;
381 /* Pass the new message to the superclass */
382 object = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)&p);
384 else
385 object = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
387 return object;
390 OOP_Object *NV__Hidd_Gfx__Show(OOP_Class *cl, OOP_Object *o,
391 struct pHidd_Gfx_Show *msg)
393 OOP_Object *fb = NULL;
394 if (msg->bitMap)
396 nvBitMap *bm = OOP_INST_DATA(OOP_OCLASS(msg->bitMap), msg->bitMap);
398 if (bm->state)
400 /* Suppose bm has properly allocated state structure */
401 if (bm->fbgfx)
403 bm->usecount++;
405 LOCK_HW
407 LoadState(_sd, bm->state);
408 DPMS(_sd, _sd->dpms);
410 fb = bm->BitMap;
411 NVShowHideCursor(_sd, _sd->Card.cursorVisible);
413 UNLOCK_HW
418 if (!fb)
419 fb = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
421 return fb;
424 VOID NV__Hidd_Gfx__CopyBox(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_CopyBox *msg)
426 ULONG mode = GC_DRMD(msg->gc);
427 IPTR src=0, dst=0;
429 /* Check whether we can get Drawable attribute of our nVidia class */
430 OOP_GetAttr(msg->src, aHidd_nvBitMap_Drawable, &src);
431 OOP_GetAttr(msg->dest, aHidd_nvBitMap_Drawable, &dst);
433 if (!dst || !src)
435 /* No. One of the bitmaps is not nVidia bitmap */
436 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
438 else
440 /* Yes. Get the instance data of both bitmaps */
441 nvBitMap *bm_src = OOP_INST_DATA(OOP_OCLASS(msg->src), msg->src);
442 nvBitMap *bm_dst = OOP_INST_DATA(OOP_OCLASS(msg->dest), msg->dest);
444 /* Case -1: (To be fixed) one of the bitmaps have chunky outside GFX mem */
445 if (!bm_src->fbgfx || !bm_dst->fbgfx)
447 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
449 /* Case 0: one of bitmaps is 8bpp, whereas the other is TrueColor one */
450 else if ((bm_src->depth <= 8 || bm_dst->depth <= 8) &&
451 (bm_src->depth != bm_dst->depth))
453 /* Unsupported case */
454 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
455 return;
457 /* Case 1: both bitmaps have the same depth - use Blit engine */
458 else if (bm_src->depth == bm_dst->depth)
460 LOCK_MULTI_BITMAP
461 LOCK_BITMAP_BM(bm_src)
462 LOCK_BITMAP_BM(bm_dst)
463 UNLOCK_MULTI_BITMAP
465 LOCK_HW
467 _sd->Card.DMAKickoffCallback = NVDMAKickoffCallback;
468 _sd->gpu_busy = TRUE;
470 NVSetRopSolid(_sd, mode, ~0 << bm_src->depth);
472 if (bm_dst->surface_format != _sd->surface_format)
474 NVDmaStart(&_sd->Card, SURFACE_FORMAT, 1);
475 NVDmaNext(&_sd->Card, bm_dst->surface_format);
476 _sd->surface_format = bm_dst->surface_format;
477 // D(bug("[NVidia] surface_format <- %d\n", _sd->surface_format));
479 if ((bm_dst->pitch != _sd->dst_pitch) || (bm_src->pitch != _sd->src_pitch))
481 NVDmaStart(&_sd->Card, SURFACE_PITCH, 1);
482 NVDmaNext(&_sd->Card, (bm_dst->pitch << 16) | bm_src->pitch);
483 _sd->src_pitch = bm_src->pitch;
484 _sd->dst_pitch = bm_dst->pitch;
485 // D(bug("[NVidia] pitch <- %08x\n", (_sd->dst_pitch << 16) | _sd->src_pitch));
487 if (bm_src->framebuffer != _sd->src_offset)
489 NVDmaStart(&_sd->Card, SURFACE_OFFSET_SRC, 1);
490 NVDmaNext(&_sd->Card, bm_src->framebuffer);
491 _sd->src_offset = bm_src->framebuffer;
492 // D(bug("[NVidia] src_offset=%p\n", _sd->src_offset));
494 if (bm_dst->framebuffer != _sd->dst_offset)
496 NVDmaStart(&_sd->Card, SURFACE_OFFSET_DST, 1);
497 NVDmaNext(&_sd->Card, bm_dst->framebuffer);
498 _sd->dst_offset = bm_dst->framebuffer;
499 // D(bug("[NVidia] dst_offset=%p\n", _sd->dst_offset));
502 NVDmaStart(&_sd->Card, BLIT_POINT_SRC, 3);
503 NVDmaNext(&_sd->Card, (msg->srcY << 16) | (msg->srcX & 0xffff));
504 NVDmaNext(&_sd->Card, (msg->destY << 16) | (msg->destX & 0xffff));
505 NVDmaNext(&_sd->Card, (msg->height << 16) | (msg->width & 0xffff));
507 NVDmaKickoff(&_sd->Card);
508 //NVSync(_sd);
510 UNLOCK_HW
512 UNLOCK_BITMAP_BM(bm_src)
513 UNLOCK_BITMAP_BM(bm_dst)
516 else /* Case 2: different bitmaps. use Stretch engine */
518 LOCK_MULTI_BITMAP
519 LOCK_BITMAP_BM(bm_src)
520 LOCK_BITMAP_BM(bm_dst)
521 UNLOCK_MULTI_BITMAP
523 LOCK_HW
525 _sd->Card.DMAKickoffCallback = NVDMAKickoffCallback;
526 _sd->gpu_busy = TRUE;
528 if ((bm_dst->surface_format != _sd->surface_format) && bm_dst->depth != 15)
531 NVDmaStart(&_sd->Card, SURFACE_FORMAT, 1);
532 NVDmaNext(&_sd->Card, bm_dst->surface_format);
533 _sd->surface_format = bm_dst->surface_format;
534 // D(bug("[NVidia] surface_format <- %d\n", _sd->surface_format));
537 if (bm_dst->depth == 15)
539 NVDmaStart(&_sd->Card, SURFACE_FORMAT, 1);
540 NVDmaNext(&_sd->Card, SURFACE_FORMAT_DEPTH15);
541 _sd->surface_format = SURFACE_FORMAT_DEPTH16;
544 if (bm_dst->pitch != _sd->dst_pitch)
546 NVDmaStart(&_sd->Card, SURFACE_PITCH, 1);
547 NVDmaNext(&_sd->Card, (bm_dst->pitch << 16) | _sd->src_pitch);
548 _sd->dst_pitch = bm_dst->pitch;
549 // D(bug("[NVidia] pitch <- %08x\n", (_sd->dst_pitch << 16) | _sd->src_pitch));
552 if (bm_dst->framebuffer != _sd->dst_offset)
554 NVDmaStart(&_sd->Card, SURFACE_OFFSET_DST, 1);
555 NVDmaNext(&_sd->Card, bm_dst->framebuffer);
556 _sd->dst_offset = bm_dst->framebuffer;
557 // D(bug("[NVidia] dst_offset=%p\n", _sd->dst_offset));
560 NVDmaStart(&_sd->Card, RECT_SOLID_COLOR, 1);
561 NVDmaNext(&_sd->Card, 0);
563 NVDmaStart(&_sd->Card, STRETCH_BLIT_FORMAT, 1);
564 switch (bm_src->depth)
566 case 15:
567 NVDmaNext(&_sd->Card, STRETCH_BLIT_FORMAT_DEPTH15);
568 break;
569 case 16:
570 NVDmaNext(&_sd->Card, STRETCH_BLIT_FORMAT_DEPTH16);
571 break;
572 case 24:
573 NVDmaNext(&_sd->Card, STRETCH_BLIT_FORMAT_DEPTH24);
574 break;
575 default:
576 NVDmaNext(&_sd->Card, STRETCH_BLIT_FORMAT_DEPTH8);
577 break;
580 NVDmaStart(&_sd->Card, STRETCH_BLIT_CLIP_POINT, 6);
581 NVDmaNext(&_sd->Card, 0x00000000); // dst_CLip
582 NVDmaNext(&_sd->Card, 0xffffffff); // dst_Clip
583 NVDmaNext(&_sd->Card, (msg->destY << 16) | (msg->destX));// dst_y | dst_x
584 NVDmaNext(&_sd->Card, (msg->height << 16)| (msg->width));// dst_h | dst_w
585 NVDmaNext(&_sd->Card, 1 << 20); // src_w / dst_w 1:1
586 NVDmaNext(&_sd->Card, 1 << 20); // src_h / dst_h 1:1
588 NVDmaStart(&_sd->Card, STRETCH_BLIT_SRC_SIZE, 4);
589 NVDmaNext(&_sd->Card, (msg->height << 16) | (msg->width));// src_h | src_w
590 NVDmaNext(&_sd->Card,
591 (STRETCH_BLIT_SRC_FORMAT_FILTER_POINT_SAMPLE << 24) | // BILINEAR | _POINT_SAMPLE
592 (STRETCH_BLIT_SRC_FORMAT_ORIGIN_CORNER << 16) |
593 (bm_src->pitch)); // src_pitch
594 NVDmaNext(&_sd->Card, bm_src->framebuffer); // src_offset
595 NVDmaNext(&_sd->Card, ((msg->srcY << 20) & 0xffff0000)
596 | ((msg->srcX << 4) & 0xffff)); // src_y | src_x
598 NVDmaKickoff(&_sd->Card);
600 if (bm_dst->depth == 15)
602 NVDmaStart(&_sd->Card, SURFACE_FORMAT, 1);
603 NVDmaNext(&_sd->Card, SURFACE_FORMAT_DEPTH16);
605 //NVSync(_sd);
607 UNLOCK_HW
609 UNLOCK_BITMAP_BM(bm_src)
610 UNLOCK_BITMAP_BM(bm_dst)
614 D(bug("[NVidia] CopyBox(src(%p,%d:%d@%d),dst(%p,%d:%d@%d),%d:%d\n",
615 bm_src->framebuffer,msg->srcX,msg->srcY,bm_src->depth,
616 bm_dst->framebuffer,msg->destX,msg->destY,bm_dst->depth,
617 msg->width, msg->height));
619 bm_src->usecount++;
620 bm_dst->usecount++;
624 #define ToRGB555(c) \
625 (((c & 0xf80000) >> 9) | ((c & 0xf800) >> 6) | ((c & 0xf8) >> 3) | ((c & 0xFF000000) ? 0x8000 : 0))
627 /* Do we miss similar definition in include/hidd/graphics.h ? */
628 #if AROS_BIG_ENDIAN
629 #define Machine_ARGB32 vHidd_StdPixFmt_ARGB32
630 #else
631 #define Machine_ARGB32 vHidd_StdPixFmt_BGRA32
632 #endif
634 BOOL NV__Hidd_Gfx__SetCursorShape(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_SetCursorShape *msg)
636 if (msg->shape == NULL)
638 NVShowHideCursor(_sd, 0);
639 _sd->Card.cursorVisible = 0;
640 return TRUE;
642 else
644 IPTR width, height, x;
646 OOP_GetAttr(msg->shape, aHidd_BitMap_Width, &width);
647 OOP_GetAttr(msg->shape, aHidd_BitMap_Height, &height);
649 if (_sd->Card.alphaCursor)
651 ULONG *curimg = (ULONG *)_sd->Card.CURSOR;
653 if (width > 64) width = 64;
654 if (height > 64) height = 64;
656 LOCK_HW
658 /* Clear the matrix */
659 for (x = 0; x < 64*64; x++)
660 curimg[x] = 0;
662 /* Get data from the bitmap */
663 HIDD_BM_GetImage(msg->shape, (UBYTE *)curimg, 64*4, 0, 0, width, height, Machine_ARGB32);
665 UNLOCK_HW
666 return TRUE;
668 else
670 ULONG *tmp;
671 UWORD *curimg = (UWORD *)_sd->Card.CURSOR;
673 if (width > 32) width = 32;
674 if (height > 32) height = 32;
676 /* Allocate a temporary buffer. It will be cleared because the pool was created with MEMF_CLEAR */
677 tmp = AllocPooled(_sd->memPool, 4 * 32 * 32);
678 if (tmp) {
679 /* Get data from the bitmap, we need alpha channel too */
680 HIDD_BM_GetImage(msg->shape, (UBYTE *)tmp, 4 * 32, 0, 0, width, height, Machine_ARGB32);
682 LOCK_HW
684 /* Now convert the data */
685 for (x = 0; x < 32*32; x++)
686 curimg[x] = ToRGB555(tmp[x]);
688 UNLOCK_HW
690 FreePooled(_sd->memPool, tmp, 4 * 32 * 32);
691 return TRUE;
692 } else
693 return FALSE;
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
717 Allocates some memory area on GFX card, which may be sufficient for bitmap
718 with given size and depth. The must_have bit may be defined but doesn't
719 have to. If it is TRUE, the allocator will do everything to get the memory -
720 eg. it will throw other bitmaps away from it or it will shift them within
721 GFX memory
724 IPTR AllocBitmapArea(struct staticdata *sd, ULONG width, ULONG height,
725 ULONG bpp, BOOL must_have)
727 IPTR result;
729 LOCK_HW
731 Forbid();
732 result = (IPTR)Allocate(sd->CardMem, ((width * bpp + 63) & ~63) * height);
733 Permit();
735 D(bug("[NVidia] AllocBitmapArea(%dx%d@%d) = %p\n",
736 width, height, bpp, result));
738 If Allocate failed, make the 0xffffffff as return. If it succeeded, make
739 the memory pointer relative to the begin of GFX memory
741 if (result == 0) --result;
742 else result -= (IPTR)sd->Card.FrameBuffer;
744 UNLOCK_HW
746 /* Generic thing. Will be extended later */
747 return result;
750 VOID FreeBitmapArea(struct staticdata *sd, IPTR bmp, ULONG width, ULONG height,
751 ULONG bpp)
753 APTR ptr = (APTR)(bmp + sd->Card.FrameBuffer);
755 LOCK_HW
757 D(bug("[NVidia] FreeBitmapArea(%p,%dx%d@%d)\n",
758 bmp, width, height, bpp));
760 Forbid();
761 Deallocate(sd->CardMem, ptr, ((width * bpp + 63) & ~63) * height);
762 Permit();
764 UNLOCK_HW