use the targets size, to suppress a warning.
[AROS.git] / workbench / hidds / nouveau / nouveau_hiddclass.c
blob39eeedd32d35d21826ba5a1d5ccec50feca59c47
1 /*
2 Copyright © 2010-2017, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include "nouveau_intern.h"
7 #include "compositor.h"
9 #include <graphics/displayinfo.h>
10 #include <proto/utility.h>
11 #include <nouveau_drm.h>
13 #define DEBUG 0
14 #include <aros/debug.h>
15 #include <proto/oop.h>
17 #include "arosdrmmode.h"
19 #undef HiddAttrBase
20 #undef HiddPixFmtAttrBase
21 #undef HiddGfxAttrBase
22 #undef HiddGfxNouveauAttrBase
23 #undef HiddSyncAttrBase
24 #undef HiddBitMapAttrBase
25 #undef HiddCompositorAttrBase
26 #undef HiddBitMapNouveauAttrBase
28 #define HiddAttrBase (SD(cl)->hiddAttrBase)
29 #define HiddPixFmtAttrBase (SD(cl)->pixFmtAttrBase)
30 #define HiddGfxAttrBase (SD(cl)->gfxAttrBase)
31 #define HiddGfxNouveauAttrBase (SD(cl)->gfxNouveauAttrBase)
32 #define HiddSyncAttrBase (SD(cl)->syncAttrBase)
33 #define HiddBitMapAttrBase (SD(cl)->bitMapAttrBase)
34 #define HiddCompositorAttrBase (SD(cl)->compositorAttrBase)
35 #define HiddBitMapNouveauAttrBase (SD(cl)->bitMapNouveauAttrBase)
37 #define MAX_BITMAP_WIDTH 4096
38 #define MAX_BITMAP_HEIGHT 4096
39 #define GART_BUFFER_SIZE (12 * 1024 * 1024)
41 /* HELPER FUNCTIONS */
42 VOID HIDDNouveauShowCursor(OOP_Object * gfx, BOOL visible)
44 OOP_Class * cl = OOP_OCLASS(gfx);
45 struct HIDDNouveauData * gfxdata = OOP_INST_DATA(cl, gfx);
46 struct CardData * carddata = &(SD(cl)->carddata);
47 struct nouveau_device_priv * nvdev = nouveau_device(carddata->dev);
49 LOCK_ENGINE
51 if (visible)
53 drmModeSetCursor(nvdev->fd, gfxdata->selectedcrtcid,
54 gfxdata->cursor->handle, 64, 64);
56 else
58 drmModeSetCursor(nvdev->fd, gfxdata->selectedcrtcid,
59 0, 64, 64);
62 UNLOCK_ENGINE
65 static BOOL HIDDNouveauSelectConnectorCrtc(LONG fd, drmModeConnectorPtr * selectedconnector,
66 drmModeCrtcPtr * selectedcrtc)
68 *selectedconnector = NULL;
69 *selectedcrtc = NULL;
70 drmModeResPtr drmmode = NULL;
71 LONG i; ULONG crtc_id;
73 LOCK_ENGINE
75 /* Get all components information */
76 drmmode = drmModeGetResources(fd);
77 if (!drmmode)
79 D(bug("[Nouveau] Not able to get resources information\n"));
80 UNLOCK_ENGINE
81 return FALSE;
84 /* Selecting connector */
85 for (i = 0; i < drmmode->count_connectors; i++)
87 drmModeConnectorPtr connector = drmModeGetConnector(fd, drmmode->connectors[i]);
89 if (connector)
91 if (connector->connection == DRM_MODE_CONNECTED)
93 /* Found connected connector */
94 *selectedconnector = connector;
95 break;
98 drmModeFreeConnector(connector);
102 if (!(*selectedconnector))
104 D(bug("[Nouveau] No connected connector\n"));
105 drmModeFreeResources(drmmode);
106 UNLOCK_ENGINE
107 return FALSE;
110 /* Selecting first available CRTC */
111 if (drmmode->count_crtcs > 0)
112 crtc_id = drmmode->crtcs[0];
113 else
114 crtc_id = 0;
116 *selectedcrtc = drmModeGetCrtc(fd, crtc_id);
117 if (!(*selectedcrtc))
119 D(bug("[Nouveau] Not able to get crtc information for crtc_id %d\n", crtc_id));
120 drmModeFreeConnector(*selectedconnector);
121 *selectedconnector = NULL;
122 drmModeFreeResources(drmmode);
123 UNLOCK_ENGINE
124 return FALSE;
127 drmModeFreeResources(drmmode);
128 UNLOCK_ENGINE
129 return TRUE;
132 #include <stdio.h>
134 static struct TagItem * HIDDNouveauCreateSyncTagsFromConnector(OOP_Class * cl, drmModeConnectorPtr connector)
136 struct TagItem * syncs = NULL;
137 ULONG modescount = connector->count_modes;
138 ULONG i;
140 if (modescount == 0)
141 return NULL;
143 /* Allocate enough structures */
144 syncs = HIDDNouveauAlloc(sizeof(struct TagItem) * modescount);
146 for (i = 0; i < modescount; i++)
148 struct TagItem * sync = HIDDNouveauAlloc(sizeof(struct TagItem) * 15);
149 LONG j = 0;
151 drmModeModeInfoPtr mode = &connector->modes[i];
153 sync[j].ti_Tag = aHidd_Sync_PixelClock; sync[j++].ti_Data = mode->clock;
155 sync[j].ti_Tag = aHidd_Sync_HDisp; sync[j++].ti_Data = mode->hdisplay;
156 sync[j].ti_Tag = aHidd_Sync_HSyncStart; sync[j++].ti_Data = mode->hsync_start;
157 sync[j].ti_Tag = aHidd_Sync_HSyncEnd; sync[j++].ti_Data = mode->hsync_end;
158 sync[j].ti_Tag = aHidd_Sync_HTotal; sync[j++].ti_Data = mode->htotal;
159 sync[j].ti_Tag = aHidd_Sync_HMin; sync[j++].ti_Data = mode->hdisplay;
160 sync[j].ti_Tag = aHidd_Sync_HMax; sync[j++].ti_Data = MAX_BITMAP_WIDTH;
162 sync[j].ti_Tag = aHidd_Sync_VDisp; sync[j++].ti_Data = mode->vdisplay;
163 sync[j].ti_Tag = aHidd_Sync_VSyncStart; sync[j++].ti_Data = mode->vsync_start;
164 sync[j].ti_Tag = aHidd_Sync_VSyncEnd; sync[j++].ti_Data = mode->vsync_end;
165 sync[j].ti_Tag = aHidd_Sync_VTotal; sync[j++].ti_Data = mode->vtotal;
166 sync[j].ti_Tag = aHidd_Sync_VMin; sync[j++].ti_Data = mode->vdisplay;
167 sync[j].ti_Tag = aHidd_Sync_VMax; sync[j++].ti_Data = MAX_BITMAP_HEIGHT;
169 /* Name */
170 STRPTR syncname = HIDDNouveauAlloc(32);
171 sprintf(syncname, "NV:%dx%d@%d", mode->hdisplay, mode->vdisplay, mode->vrefresh);
173 sync[j].ti_Tag = aHidd_Sync_Description; sync[j++].ti_Data = (IPTR)syncname;
175 sync[j].ti_Tag = TAG_DONE; sync[j++].ti_Data = 0UL;
177 syncs[i].ti_Tag = aHidd_Gfx_SyncTags;
178 syncs[i].ti_Data = (IPTR)sync;
181 return syncs;
184 /* This function assumes that the mode, crtc and output are already selected */
185 static BOOL HIDDNouveauShowBitmapForSelectedMode(OOP_Object * bm)
187 OOP_Class * cl = OOP_OCLASS(bm);
188 struct HIDDNouveauData * gfxdata = NULL;
189 struct HIDDNouveauBitMapData * bmdata = OOP_INST_DATA(cl, bm);
190 struct CardData * carddata = &(SD(cl)->carddata);
191 struct nouveau_device_priv *nvdev = nouveau_device(carddata->dev);
192 uint32_t output_ids[] = {0};
193 uint32_t output_count = 1;
194 IPTR e = (IPTR)NULL;
195 OOP_Object * gfx = NULL;
196 LONG ret;
198 LOCK_ENGINE
199 LOCK_BITMAP
201 /* Check if passed bitmap has been registered as framebuffer */
202 if (bmdata->fbid == 0)
204 UNLOCK_BITMAP
205 UNLOCK_ENGINE
206 return FALSE;
209 OOP_GetAttr(bm, aHidd_BitMap_GfxHidd, &e);
210 gfx = (OOP_Object *)e;
211 gfxdata = OOP_INST_DATA(OOP_OCLASS(gfx), gfx);
212 output_ids[0] = ((drmModeConnectorPtr)gfxdata->selectedconnector)->connector_id;
215 ret = drmModeSetCrtc(nvdev->fd, gfxdata->selectedcrtcid,
216 bmdata->fbid, -bmdata->xoffset, -bmdata->yoffset, output_ids,
217 output_count, gfxdata->selectedmode);
219 UNLOCK_BITMAP
220 UNLOCK_ENGINE
222 if (ret) return FALSE; else return TRUE;
225 BOOL HIDDNouveauSwitchToVideoMode(OOP_Object * bm)
227 OOP_Class * cl = OOP_OCLASS(bm);
228 struct HIDDNouveauBitMapData * bmdata = OOP_INST_DATA(cl, bm);
229 OOP_Object * gfx = NULL;
230 struct HIDDNouveauData * gfxdata = NULL;
231 struct CardData * carddata = &(SD(cl)->carddata);
232 struct nouveau_device_priv *nvdev = nouveau_device(carddata->dev);
233 LONG i;
234 drmModeConnectorPtr selectedconnector = NULL;
235 HIDDT_ModeID modeid;
236 OOP_Object * sync;
237 OOP_Object * pf;
238 IPTR pixel, e;
239 IPTR hdisp, vdisp, hstart, hend, htotal, vstart, vend, vtotal;
240 LONG ret;
242 LOCK_ENGINE
244 OOP_GetAttr(bm, aHidd_BitMap_GfxHidd, &e);
245 gfx = (OOP_Object *)e;
246 gfxdata = OOP_INST_DATA(OOP_OCLASS(gfx), gfx);
247 selectedconnector = (drmModeConnectorPtr)gfxdata->selectedconnector;
249 D(bug("[Nouveau] HIDDNouveauSwitchToVideoMode, bm: 0x%x\n", bm));
251 /* We should be able to get modeID from the bitmap */
252 OOP_GetAttr(bm, aHidd_BitMap_ModeID, &modeid);
254 if (modeid == vHidd_ModeID_Invalid)
256 D(bug("[Nouveau] Invalid ModeID\n"));
257 UNLOCK_ENGINE
258 return FALSE;
261 /* Get Sync and PixelFormat properties */
262 struct pHidd_Gfx_GetMode __getmodemsg =
264 modeID: modeid,
265 syncPtr: &sync,
266 pixFmtPtr: &pf,
267 }, *getmodemsg = &__getmodemsg;
269 getmodemsg->mID = OOP_GetMethodID(IID_Hidd_Gfx, moHidd_Gfx_GetMode);
270 OOP_DoMethod(gfx, (OOP_Msg)getmodemsg);
272 OOP_GetAttr(sync, aHidd_Sync_PixelClock, &pixel);
273 OOP_GetAttr(sync, aHidd_Sync_HDisp, &hdisp);
274 OOP_GetAttr(sync, aHidd_Sync_VDisp, &vdisp);
275 OOP_GetAttr(sync, aHidd_Sync_HSyncStart, &hstart);
276 OOP_GetAttr(sync, aHidd_Sync_VSyncStart, &vstart);
277 OOP_GetAttr(sync, aHidd_Sync_HSyncEnd, &hend);
278 OOP_GetAttr(sync, aHidd_Sync_VSyncEnd, &vend);
279 OOP_GetAttr(sync, aHidd_Sync_HTotal, &htotal);
280 OOP_GetAttr(sync, aHidd_Sync_VTotal, &vtotal);
282 D(bug("[Nouveau] Sync: %d, %d, %d, %d, %d, %d, %d, %d, %d\n",
283 pixel, hdisp, hstart, hend, htotal, vdisp, vstart, vend, vtotal));
285 D(bug("[Nouveau] Connector %d, CRTC %d\n",
286 selectedconnector->connector_id, gfxdata->selectedcrtcid));
288 /* Select mode */
289 gfxdata->selectedmode = NULL;
290 for (i = 0; i < selectedconnector->count_modes; i++)
292 drmModeModeInfoPtr mode = &selectedconnector->modes[i];
294 if ((mode->hdisplay == hdisp) && (mode->vdisplay == vdisp) &&
295 (mode->hsync_start == hstart) && (mode->vsync_start == vstart) &&
296 (mode->hsync_end == hend) && (mode->vsync_end == vend))
298 gfxdata->selectedmode = mode;
299 break;
303 if (!gfxdata->selectedmode)
305 D(bug("[Nouveau] Not able to select mode\n"));
306 UNLOCK_ENGINE
307 return FALSE;
310 /* For screen switching the bitmap might have already once been a framebuffer
311 - check bmdata->fbid. Also the bitmap itself needs to know whether it is
312 added as framebuffer so that it can unregister itself in Dispose */
314 /* Add as frame buffer */
315 if (bmdata->fbid == 0)
317 ret = drmModeAddFB(nvdev->fd, bmdata->width, bmdata->height,
318 bmdata->depth, bmdata->bytesperpixel * 8,
319 bmdata->pitch, bmdata->bo->handle, &bmdata->fbid);
320 if (ret)
322 D(bug("[Nouveau] Not able to add framebuffer\n"));
323 UNLOCK_ENGINE
324 return FALSE;
329 /* Switch mode */
330 if (!HIDDNouveauShowBitmapForSelectedMode(bm))
332 D(bug("[Nouveau] Not able to set crtc\n"));
333 UNLOCK_ENGINE
334 return FALSE;
337 HIDDNouveauShowCursor(gfx, TRUE);
339 UNLOCK_ENGINE
340 return TRUE;
343 /* PUBLIC METHODS */
344 OOP_Object * METHOD(Nouveau, Root, New)
346 drmModeCrtcPtr selectedcrtc = NULL;
347 drmModeConnectorPtr selectedconnector = NULL;
348 struct nouveau_device * dev = NULL;
349 struct nouveau_device_priv * nvdev = NULL;
350 struct TagItem * syncs = NULL;
351 struct CardData * carddata = &(SD(cl)->carddata);
352 LONG ret;
353 ULONG selectedcrtcid;
355 if (nouveau_init() < 0)
356 return NULL;
358 LOCK_ENGINE
360 nouveau_device_open(&dev, "");
361 nvdev = nouveau_device(dev);
363 /* Select crtc and connector */
364 if (!HIDDNouveauSelectConnectorCrtc(nvdev->fd, &selectedconnector, &selectedcrtc))
366 D(bug("[Nouveau] Not able to select connector and crtc\n"));
368 UNLOCK_ENGINE
370 return NULL;
373 selectedcrtcid = selectedcrtc->crtc_id;
374 drmModeFreeCrtc(selectedcrtc);
376 /* Read connector and build sync tags */
377 syncs = HIDDNouveauCreateSyncTagsFromConnector(cl, selectedconnector);
378 if (syncs == NULL)
380 D(bug("[Nouveau] Not able to read any sync modes\n"));
381 UNLOCK_ENGINE
382 return NULL;
386 /* Call super contructor */
388 struct TagItem pftags_24bpp[] = {
389 { aHidd_PixFmt_RedShift, 8 }, /* 0 */
390 { aHidd_PixFmt_GreenShift, 16 }, /* 1 */
391 { aHidd_PixFmt_BlueShift, 24 }, /* 2 */
392 { aHidd_PixFmt_AlphaShift, 0 }, /* 3 */
393 { aHidd_PixFmt_RedMask, 0x00ff0000 }, /* 4 */
394 { aHidd_PixFmt_GreenMask, 0x0000ff00 }, /* 5 */
395 { aHidd_PixFmt_BlueMask, 0x000000ff }, /* 6 */
396 { aHidd_PixFmt_AlphaMask, 0x00000000 }, /* 7 */
397 { aHidd_PixFmt_ColorModel, vHidd_ColorModel_TrueColor }, /* 8 */
398 { aHidd_PixFmt_Depth, 24 }, /* 9 */
399 { aHidd_PixFmt_BytesPerPixel, 4 }, /* 10 */
400 { aHidd_PixFmt_BitsPerPixel, 24 }, /* 11 */
401 { aHidd_PixFmt_StdPixFmt, vHidd_StdPixFmt_BGR032 }, /* 12 Native */
402 { aHidd_PixFmt_BitMapType, vHidd_BitMapType_Chunky }, /* 15 */
403 { TAG_DONE, 0UL }
406 struct TagItem pftags_16bpp[] = {
407 { aHidd_PixFmt_RedShift, 16 }, /* 0 */
408 { aHidd_PixFmt_GreenShift, 21 }, /* 1 */
409 { aHidd_PixFmt_BlueShift, 27 }, /* 2 */
410 { aHidd_PixFmt_AlphaShift, 0 }, /* 3 */
411 { aHidd_PixFmt_RedMask, 0x0000f800 }, /* 4 */
412 { aHidd_PixFmt_GreenMask, 0x000007e0 }, /* 5 */
413 { aHidd_PixFmt_BlueMask, 0x0000001f }, /* 6 */
414 { aHidd_PixFmt_AlphaMask, 0x00000000 }, /* 7 */
415 { aHidd_PixFmt_ColorModel, vHidd_ColorModel_TrueColor }, /* 8 */
416 { aHidd_PixFmt_Depth, 16 }, /* 9 */
417 { aHidd_PixFmt_BytesPerPixel, 2 }, /* 10 */
418 { aHidd_PixFmt_BitsPerPixel, 16 }, /* 11 */
419 { aHidd_PixFmt_StdPixFmt, vHidd_StdPixFmt_RGB16_LE }, /* 12 */
420 { aHidd_PixFmt_BitMapType, vHidd_BitMapType_Chunky }, /* 15 */
421 { TAG_DONE, 0UL }
424 struct TagItem modetags[] = {
425 { aHidd_Gfx_PixFmtTags, (IPTR)pftags_24bpp },
426 { aHidd_Gfx_PixFmtTags, (IPTR)pftags_16bpp },
427 { TAG_MORE, (IPTR)syncs }, /* FIXME: sync tags will leak */
428 { TAG_DONE, 0UL }
431 struct TagItem mytags[] = {
432 { aHidd_Gfx_ModeTags, (IPTR)modetags },
433 { aHidd_Name , (IPTR)"Nouveau" },
434 { aHidd_HardwareName , (IPTR)"Nvidia Gfx Adaptor" },
435 { aHidd_ProducerName , (IPTR)"Nvidia Corporation" },
436 { TAG_MORE, (IPTR)msg->attrList }
439 struct pRoot_New mymsg;
441 mymsg.mID = msg->mID;
442 mymsg.attrList = mytags;
444 msg = &mymsg;
447 o = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
449 D(bug("[Nouveau] GFX New\n"));
451 if (o)
453 struct HIDDNouveauData * gfxdata = OOP_INST_DATA(cl, o);
454 /* Pass local information to class */
455 gfxdata->selectedcrtcid = selectedcrtcid;
456 gfxdata->selectedmode = NULL;
457 gfxdata->selectedconnector = selectedconnector;
458 carddata->dev = dev;
459 ULONG gartsize = 0;
460 UQUAD value;
462 /* Check chipset architecture */
463 switch (carddata->dev->chipset & 0xf0)
465 case 0x00:
466 carddata->architecture = NV_ARCH_04;
467 break;
468 case 0x10:
469 carddata->architecture = NV_ARCH_10;
470 break;
471 case 0x20:
472 carddata->architecture = NV_ARCH_20;
473 break;
474 case 0x30:
475 carddata->architecture = NV_ARCH_30;
476 break;
477 case 0x40:
478 case 0x60:
479 carddata->architecture = NV_ARCH_40;
480 break;
481 case 0x50:
482 case 0x80:
483 case 0x90:
484 case 0xa0:
485 carddata->architecture = NV_ARCH_50;
486 break;
487 case 0xc0:
488 carddata->architecture = NV_ARCH_C0;
489 break;
490 default:
491 /* TODO: report error, how to handle it? */
492 UNLOCK_ENGINE
493 return NULL;
496 nouveau_device_get_param(carddata->dev, NOUVEAU_GETPARAM_BUS_TYPE, &value);
497 if (value == NV_PCIE)
498 carddata->IsPCIE = TRUE;
499 else
500 carddata->IsPCIE = FALSE;
502 /* Allocate dma channel */
503 ret = nouveau_channel_alloc(carddata->dev, NvDmaFB, NvDmaTT,
504 24 * 1024, &carddata->chan);
505 if (ret < 0)
507 /* TODO: Check ret, how to handle ? */
510 /* Initialize acceleration objects */
512 ret = HIDDNouveauAccelCommonInit(carddata);
513 if (ret < 0)
515 /* TODO: Check ret, how to handle ? */
518 /* Allocate buffer object for cursor */
519 nouveau_bo_new(carddata->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_MAP,
520 0, 64 * 64 * 4, &gfxdata->cursor);
521 /* TODO: Check return, hot to handle */
523 /* Allocate GART scratch buffer */
524 if (carddata->dev->vm_gart_size > GART_BUFFER_SIZE)
525 gartsize = GART_BUFFER_SIZE;
526 else
527 /* always leave 512kb for other things like the fifos */
528 gartsize = carddata->dev->vm_gart_size - 512 * 1024;
530 /* This can fail */
531 nouveau_bo_new(carddata->dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP,
532 0, gartsize, &carddata->GART);
533 InitSemaphore(&carddata->gartsemaphore);
535 /* Set initial pattern (else 16-bit ROPs are not working) */
536 switch(carddata->architecture)
538 case(NV_ARCH_03):
539 case(NV_ARCH_04):
540 case(NV_ARCH_10):
541 case(NV_ARCH_20):
542 case(NV_ARCH_30):
543 case(NV_ARCH_40):
544 HIDDNouveauNV04SetPattern(carddata, ~0, ~0, ~0, ~0);
545 break;
546 case(NV_ARCH_50):
547 HIDDNouveauNV50SetPattern(carddata, ~0, ~0, ~0, ~0);
548 break;
549 case(NV_ARCH_C0):
550 HIDDNouveauNVC0SetPattern(carddata, ~0, ~0, ~0, ~0);
551 break;
554 /* Create compositor object */
556 struct TagItem comptags [] =
558 { aHidd_Compositor_GfxHidd, (IPTR)o },
559 { TAG_DONE, TAG_DONE }
561 gfxdata->compositor = OOP_NewObject(SD(cl)->compositorclass, NULL, comptags);
562 /* TODO: Check if object was created, how to handle ? */
566 UNLOCK_ENGINE
568 return o;
570 UNLOCK_ENGINE
572 return NULL;
575 /* FIXME: IMPLEMENT DISPOSE - calling nouveau_close(), freeing cursor bo, gart bo,
576 selectedconnector, gfxdata->compositor, HIDDNouveauAccelFree */
578 /* FIXME: IMPLEMENT DISPOSE BITMAP - REMOVE FROM FB IF MARKED AS SUCH */
580 OOP_Object * METHOD(Nouveau, Hidd_Gfx, CreateObject)
582 struct HIDDNouveauData * gfxdata = OOP_INST_DATA(cl, o);
583 OOP_Object *object = NULL;
585 if (msg->cl == SD(cl)->basebm)
587 struct pHidd_Gfx_CreateObject mymsg;
588 HIDDT_ModeID modeid;
589 HIDDT_StdPixFmt stdpf;
591 struct TagItem mytags [] =
593 { TAG_IGNORE, TAG_IGNORE }, /* Placeholder for aHidd_BitMap_ClassPtr */
594 { TAG_IGNORE, TAG_IGNORE }, /* Placeholder for aHidd_BitMap_Align */
595 { aHidd_BitMap_Nouveau_CompositorHidd, (IPTR)gfxdata->compositor },
596 { TAG_MORE, (IPTR)msg->attrList }
599 /* Check if user provided valid ModeID */
600 /* Check for framebuffer - not needed as Nouveau is a NoFramebuffer driver */
601 /* Check for displayable - not needed - displayable has ModeID and we don't
602 distinguish between on-screen and off-screen bitmaps */
603 modeid = (HIDDT_ModeID)GetTagData(aHidd_BitMap_ModeID, vHidd_ModeID_Invalid, msg->attrList);
604 if (vHidd_ModeID_Invalid != modeid)
606 /* User supplied a valid modeid. We can use our bitmap class */
607 mytags[0].ti_Tag = aHidd_BitMap_ClassPtr;
608 mytags[0].ti_Data = (IPTR)SD(cl)->bmclass;
611 /* Check if bitmap is a planar bitmap */
612 stdpf = (HIDDT_StdPixFmt)GetTagData(aHidd_BitMap_StdPixFmt, vHidd_StdPixFmt_Unknown, msg->attrList);
613 if (vHidd_StdPixFmt_Plane == stdpf)
615 mytags[1].ti_Tag = aHidd_BitMap_Align;
616 mytags[1].ti_Data = 32;
619 /* We init a new message struct */
620 mymsg.mID = msg->mID;
621 mymsg.cl = msg->cl;
622 mymsg.attrList = mytags;
624 /* Pass the new message to the superclass */
625 object = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)&mymsg);
627 else if (SD(cl)->basegallium && (msg->cl == SD(cl)->basegallium))
629 object = OOP_NewObject(NULL, CLID_Hidd_Gallium_Nouveau, msg->attrList);
631 else
632 object = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
634 return object;
637 VOID METHOD(Nouveau, Hidd_Gfx, CopyBox)
639 OOP_Class * srcclass = OOP_OCLASS(msg->src);
640 OOP_Class * destclass = OOP_OCLASS(msg->dest);
642 if (IS_NOUVEAU_BM_CLASS(srcclass) && IS_NOUVEAU_BM_CLASS(destclass))
644 /* FIXME: add checks for pixel format, etc */
645 struct HIDDNouveauBitMapData * srcdata = OOP_INST_DATA(srcclass, msg->src);
646 struct HIDDNouveauBitMapData * destdata = OOP_INST_DATA(destclass, msg->dest);
647 struct CardData * carddata = &(SD(cl)->carddata);
648 BOOL ret = FALSE;
650 D(bug("[Nouveau] CopyBox 0x%x -> 0x%x\n", msg->src, msg->dest));
652 LOCK_ENGINE
654 LOCK_MULTI_BITMAP
655 LOCK_BITMAP_BM(srcdata)
656 LOCK_BITMAP_BM(destdata)
657 UNLOCK_MULTI_BITMAP
658 UNMAP_BUFFER_BM(srcdata)
659 UNMAP_BUFFER_BM(destdata)
661 switch(carddata->architecture)
663 case(NV_ARCH_03):
664 case(NV_ARCH_04):
665 case(NV_ARCH_10):
666 case(NV_ARCH_20):
667 case(NV_ARCH_30):
668 case(NV_ARCH_40):
669 ret = HIDDNouveauNV04CopySameFormat(carddata, srcdata, destdata,
670 msg->srcX, msg->srcY, msg->destX, msg->destY,
671 msg->width, msg->height, GC_DRMD(msg->gc));
672 break;
673 case(NV_ARCH_50):
674 ret = HIDDNouveauNV50CopySameFormat(carddata, srcdata, destdata,
675 msg->srcX, msg->srcY, msg->destX, msg->destY,
676 msg->width, msg->height, GC_DRMD(msg->gc));
677 break;
678 case(NV_ARCH_C0):
679 ret = HIDDNouveauNVC0CopySameFormat(carddata, srcdata, destdata,
680 msg->srcX, msg->srcY, msg->destX, msg->destY,
681 msg->width, msg->height, GC_DRMD(msg->gc));
682 break;
685 UNLOCK_BITMAP_BM(destdata);
686 UNLOCK_BITMAP_BM(srcdata);
688 UNLOCK_ENGINE
690 if (ret)
691 return;
693 /* If operation failed, fallback to default method */
696 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
700 VOID METHOD(Nouveau, Root, Get)
702 ULONG idx;
704 if (IS_GFX_ATTR(msg->attrID, idx))
706 switch (idx)
708 case aoHidd_Gfx_NoFrameBuffer:
709 *msg->storage = (IPTR)TRUE;
710 return;
711 case aoHidd_Gfx_SupportsHWCursor:
712 *msg->storage = (IPTR)TRUE;
713 return;
714 case aoHidd_Gfx_HWSpriteTypes:
715 *msg->storage = vHidd_SpriteType_DirectColor;
716 return;
717 case aoHidd_Gfx_DriverName:
718 *msg->storage = (IPTR)"Nouveau";
719 return;
723 if (IS_GFXNOUVEAU_ATTR(msg->attrID, idx))
725 switch(idx)
727 case(aoHidd_Gfx_Nouveau_VRAMSize):
729 UQUAD value;
730 nouveau_device_get_param(SD(cl)->carddata.dev, NOUVEAU_GETPARAM_VRAM_SIZE, &value);
731 *msg->storage = (IPTR)value;
732 return;
734 case(aoHidd_Gfx_Nouveau_GARTSize):
736 UQUAD value;
737 nouveau_device_get_param(SD(cl)->carddata.dev, NOUVEAU_GETPARAM_GART_SIZE, &value);
738 *msg->storage = (IPTR)value;
739 return;
741 case(aoHidd_Gfx_Nouveau_VRAMFree):
743 UQUAD value;
744 nouveau_device_get_param(SD(cl)->carddata.dev, NOUVEAU_GETPARAM_VRAM_FREE, &value);
745 *msg->storage = (IPTR)value;
746 return;
748 case(aoHidd_Gfx_Nouveau_GARTFree):
750 UQUAD value;
751 nouveau_device_get_param(SD(cl)->carddata.dev, NOUVEAU_GETPARAM_GART_FREE, &value);
752 *msg->storage = (IPTR)value;
753 return;
758 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
761 ULONG METHOD(Nouveau, Hidd_Gfx, ShowViewPorts)
763 struct HIDDNouveauData * gfxdata = OOP_INST_DATA(cl, o);
764 struct pHidd_Compositor_BitMapStackChanged bscmsg =
766 mID : OOP_GetMethodID(IID_Hidd_Compositor, moHidd_Compositor_BitMapStackChanged),
767 data : msg->Data
770 D(bug("[Nouveau] ShowViewPorts enter TopLevelBM %x\n", (msg->Data ? (msg->Data->Bitmap) : NULL)));
772 OOP_DoMethod(gfxdata->compositor, (OOP_Msg)&bscmsg);
774 return TRUE; /* Indicate driver supports this method */
777 #if AROS_BIG_ENDIAN
778 #define Machine_ARGB32 vHidd_StdPixFmt_ARGB32
779 #else
780 #define Machine_ARGB32 vHidd_StdPixFmt_BGRA32
781 #endif
783 BOOL METHOD(Nouveau, Hidd_Gfx, SetCursorShape)
785 struct HIDDNouveauData * gfxdata = OOP_INST_DATA(cl, o);
787 if (msg->shape == NULL)
789 /* Hide cursor */
790 HIDDNouveauShowCursor(o, FALSE);
792 else
794 IPTR width, height;
795 ULONG i;
796 ULONG x, y;
797 ULONG curimage[64 * 64];
798 struct CardData * carddata = &(SD(cl)->carddata);
800 OOP_GetAttr(msg->shape, aHidd_BitMap_Width, &width);
801 OOP_GetAttr(msg->shape, aHidd_BitMap_Height, &height);
804 if (width > 64) width = 64;
805 if (height > 64) height = 64;
807 LOCK_ENGINE
809 /* Map the cursor buffer */
810 nouveau_bo_map(gfxdata->cursor, NOUVEAU_BO_WR);
812 /* Clear the matrix */
813 for (i = 0; i < 64 * 64; i++)
814 ((ULONG*)gfxdata->cursor->map)[i] = 0;
816 /* Get data from the bitmap */
817 HIDD_BM_GetImage(msg->shape, (UBYTE *)curimage, 64 * 4, 0, 0,
818 width, height, Machine_ARGB32);
820 if (carddata->architecture < NV_ARCH_50)
822 ULONG offset, pixel, blue, green, red, alpha;
824 /* The image needs to be premultiplied */
825 for (y = 0; y < height; y++)
826 for (x = 0; x < width; x++)
828 offset = y * 64 + x;
829 pixel = curimage[offset];
830 blue = (pixel & 0x000000FF);
831 green = (pixel & 0x0000FF00) >> 8;
832 red = (pixel & 0x00FF0000) >> 16;
833 alpha = (pixel & 0xFF000000) >> 24;
835 blue = (blue * alpha) / 255;
836 green = (green * alpha) / 255;
837 red = (red * alpha) / 255;
839 curimage[offset] = (alpha << 24) | (red << 16) | (green << 8) | blue;
843 for (y = 0; y < height; y++)
844 for (x = 0; x < width; x++)
846 ULONG offset = y * 64 + x;
847 writel(curimage[offset], ((ULONG *)gfxdata->cursor->map) + (offset));
850 nouveau_bo_unmap(gfxdata->cursor);
852 /* Show updated cursor */
853 HIDDNouveauShowCursor(o, TRUE);
855 UNLOCK_ENGINE
858 return TRUE;
861 BOOL METHOD(Nouveau, Hidd_Gfx, SetCursorPos)
863 struct HIDDNouveauData * gfxdata = OOP_INST_DATA(cl, o);
864 struct CardData * carddata = &(SD(cl)->carddata);
865 struct nouveau_device_priv * nvdev = nouveau_device(carddata->dev);
867 LOCK_ENGINE
868 drmModeMoveCursor(nvdev->fd, gfxdata->selectedcrtcid, msg->x, msg->y);
869 UNLOCK_ENGINE
871 return TRUE;
874 VOID METHOD(Nouveau, Hidd_Gfx, SetCursorVisible)
876 HIDDNouveauShowCursor(o, msg->visible);
879 static struct HIDD_ModeProperties modeprops =
881 DIPF_IS_SPRITES,
883 COMPF_ABOVE
886 ULONG METHOD(Nouveau, Hidd_Gfx, ModeProperties)
888 ULONG len = msg->propsLen;
890 if (len > sizeof(modeprops))
891 len = sizeof(modeprops);
892 CopyMem(&modeprops, msg->props, len);
894 return len;