2 Copyright © 2010, The AROS Development Team. All rights reserved.
6 #include "nouveau_intern.h"
7 #include "compositing.h"
9 #include <graphics/displayinfo.h>
10 #include <proto/utility.h>
11 #include <nouveau_drm.h>
14 #include <aros/debug.h>
15 #include <proto/oop.h>
17 #include "arosdrmmode.h"
19 #undef HiddPixFmtAttrBase
20 #undef HiddGfxAttrBase
21 #undef HiddGfxNouveauAttrBase
22 #undef HiddSyncAttrBase
23 #undef HiddBitMapAttrBase
24 #undef HiddCompositingAttrBase
25 #undef HiddBitMapNouveauAttrBase
27 #define HiddPixFmtAttrBase (SD(cl)->pixFmtAttrBase)
28 #define HiddGfxAttrBase (SD(cl)->gfxAttrBase)
29 #define HiddGfxNouveauAttrBase (SD(cl)->gfxNouveauAttrBase)
30 #define HiddSyncAttrBase (SD(cl)->syncAttrBase)
31 #define HiddBitMapAttrBase (SD(cl)->bitMapAttrBase)
32 #define HiddCompositingAttrBase (SD(cl)->compositingAttrBase)
33 #define HiddBitMapNouveauAttrBase (SD(cl)->bitMapNouveauAttrBase)
35 #define MAX_BITMAP_WIDTH 4096
36 #define MAX_BITMAP_HEIGHT 4096
37 #define GART_BUFFER_SIZE (12 * 1024 * 1024)
39 /* HELPER FUNCTIONS */
40 VOID
HIDDNouveauShowCursor(OOP_Object
* gfx
, BOOL visible
)
42 OOP_Class
* cl
= OOP_OCLASS(gfx
);
43 struct HIDDNouveauData
* gfxdata
= OOP_INST_DATA(cl
, gfx
);
44 struct CardData
* carddata
= &(SD(cl
)->carddata
);
45 struct nouveau_device_priv
* nvdev
= nouveau_device(carddata
->dev
);
49 drmModeSetCursor(nvdev
->fd
, gfxdata
->selectedcrtcid
,
50 gfxdata
->cursor
->handle
, 64, 64);
54 drmModeSetCursor(nvdev
->fd
, gfxdata
->selectedcrtcid
,
59 static BOOL
HIDDNouveauSelectConnectorCrtc(LONG fd
, drmModeConnectorPtr
* selectedconnector
,
60 drmModeCrtcPtr
* selectedcrtc
)
62 *selectedconnector
= NULL
;
64 drmModeResPtr drmmode
= NULL
;
65 LONG i
; ULONG crtc_id
;
67 /* Get all components information */
68 drmmode
= drmModeGetResources(fd
);
71 D(bug("[Nouveau] Not able to get resources information\n"));
75 /* Selecting connector */
76 for (i
= 0; i
< drmmode
->count_connectors
; i
++)
78 drmModeConnectorPtr connector
= drmModeGetConnector(fd
, drmmode
->connectors
[i
]);
82 if (connector
->connection
== DRM_MODE_CONNECTED
)
84 /* Found connected connector */
85 *selectedconnector
= connector
;
89 drmModeFreeConnector(connector
);
93 if (!(*selectedconnector
))
95 D(bug("[Nouveau] No connected connector\n"));
96 drmModeFreeResources(drmmode
);
100 /* Selecting first available CRTC */
101 if (drmmode
->count_crtcs
> 0)
102 crtc_id
= drmmode
->crtcs
[0];
106 *selectedcrtc
= drmModeGetCrtc(fd
, crtc_id
);
107 if (!(*selectedcrtc
))
109 D(bug("[Nouveau] Not able to get crtc information for crtc_id %d\n", crtc_id
));
110 drmModeFreeConnector(*selectedconnector
);
111 *selectedconnector
= NULL
;
112 drmModeFreeResources(drmmode
);
116 drmModeFreeResources(drmmode
);
122 static struct TagItem
* HIDDNouveauCreateSyncTagsFromConnector(OOP_Class
* cl
, drmModeConnectorPtr connector
)
124 struct TagItem
* syncs
= NULL
;
125 ULONG modescount
= connector
->count_modes
;
131 /* Allocate enough structures */
132 syncs
= HIDDNouveauAlloc(sizeof(struct TagItem
) * modescount
);
134 for (i
= 0; i
< modescount
; i
++)
136 struct TagItem
* sync
= HIDDNouveauAlloc(sizeof(struct TagItem
) * 15);
139 drmModeModeInfoPtr mode
= &connector
->modes
[i
];
141 sync
[j
].ti_Tag
= aHidd_Sync_PixelClock
; sync
[j
++].ti_Data
= mode
->clock
;
143 sync
[j
].ti_Tag
= aHidd_Sync_HDisp
; sync
[j
++].ti_Data
= mode
->hdisplay
;
144 sync
[j
].ti_Tag
= aHidd_Sync_HSyncStart
; sync
[j
++].ti_Data
= mode
->hsync_start
;
145 sync
[j
].ti_Tag
= aHidd_Sync_HSyncEnd
; sync
[j
++].ti_Data
= mode
->hsync_end
;
146 sync
[j
].ti_Tag
= aHidd_Sync_HTotal
; sync
[j
++].ti_Data
= mode
->htotal
;
147 sync
[j
].ti_Tag
= aHidd_Sync_HMin
; sync
[j
++].ti_Data
= mode
->hdisplay
;
148 sync
[j
].ti_Tag
= aHidd_Sync_HMax
; sync
[j
++].ti_Data
= MAX_BITMAP_WIDTH
;
150 sync
[j
].ti_Tag
= aHidd_Sync_VDisp
; sync
[j
++].ti_Data
= mode
->vdisplay
;
151 sync
[j
].ti_Tag
= aHidd_Sync_VSyncStart
; sync
[j
++].ti_Data
= mode
->vsync_start
;
152 sync
[j
].ti_Tag
= aHidd_Sync_VSyncEnd
; sync
[j
++].ti_Data
= mode
->vsync_end
;
153 sync
[j
].ti_Tag
= aHidd_Sync_VTotal
; sync
[j
++].ti_Data
= mode
->vtotal
;
154 sync
[j
].ti_Tag
= aHidd_Sync_VMin
; sync
[j
++].ti_Data
= mode
->vdisplay
;
155 sync
[j
].ti_Tag
= aHidd_Sync_VMax
; sync
[j
++].ti_Data
= MAX_BITMAP_HEIGHT
;
158 STRPTR syncname
= HIDDNouveauAlloc(32);
159 sprintf(syncname
, "NV:%dx%d@%d", mode
->hdisplay
, mode
->vdisplay
, mode
->vrefresh
);
161 sync
[j
].ti_Tag
= aHidd_Sync_Description
; sync
[j
++].ti_Data
= (IPTR
)syncname
;
163 sync
[j
].ti_Tag
= TAG_DONE
; sync
[j
++].ti_Data
= 0UL;
165 syncs
[i
].ti_Tag
= aHidd_Gfx_SyncTags
;
166 syncs
[i
].ti_Data
= (IPTR
)sync
;
172 /* This function assumes that the mode, crtc and output are already selected */
173 static BOOL
HIDDNouveauShowBitmapForSelectedMode(OOP_Object
* bm
)
175 OOP_Class
* cl
= OOP_OCLASS(bm
);
176 struct HIDDNouveauData
* gfxdata
= NULL
;
177 struct HIDDNouveauBitMapData
* bmdata
= OOP_INST_DATA(cl
, bm
);
178 struct CardData
* carddata
= &(SD(cl
)->carddata
);
179 struct nouveau_device_priv
*nvdev
= nouveau_device(carddata
->dev
);
180 uint32_t output_ids
[] = {0};
181 uint32_t output_count
= 1;
183 OOP_Object
* gfx
= NULL
;
188 /* Check if passed bitmap has been registered as framebuffer */
189 if (bmdata
->fbid
== 0)
195 OOP_GetAttr(bm
, aHidd_BitMap_GfxHidd
, &e
);
196 gfx
= (OOP_Object
*)e
;
197 gfxdata
= OOP_INST_DATA(OOP_OCLASS(gfx
), gfx
);
198 output_ids
[0] = ((drmModeConnectorPtr
)gfxdata
->selectedconnector
)->connector_id
;
201 ret
= drmModeSetCrtc(nvdev
->fd
, gfxdata
->selectedcrtcid
,
202 bmdata
->fbid
, -bmdata
->xoffset
, -bmdata
->yoffset
, output_ids
,
203 output_count
, gfxdata
->selectedmode
);
207 if (ret
) return FALSE
; else return TRUE
;
210 BOOL
HIDDNouveauSwitchToVideoMode(OOP_Object
* bm
)
212 OOP_Class
* cl
= OOP_OCLASS(bm
);
213 struct HIDDNouveauBitMapData
* bmdata
= OOP_INST_DATA(cl
, bm
);
214 OOP_Object
* gfx
= NULL
;
215 struct HIDDNouveauData
* gfxdata
= NULL
;
216 struct CardData
* carddata
= &(SD(cl
)->carddata
);
217 struct nouveau_device_priv
*nvdev
= nouveau_device(carddata
->dev
);
219 drmModeConnectorPtr selectedconnector
= NULL
;
224 IPTR hdisp
, vdisp
, hstart
, hend
, htotal
, vstart
, vend
, vtotal
;
228 OOP_GetAttr(bm
, aHidd_BitMap_GfxHidd
, &e
);
229 gfx
= (OOP_Object
*)e
;
230 gfxdata
= OOP_INST_DATA(OOP_OCLASS(gfx
), gfx
);
231 selectedconnector
= (drmModeConnectorPtr
)gfxdata
->selectedconnector
;
233 D(bug("[Nouveau] HIDDNouveauSwitchToVideoMode, bm: 0x%x\n", bm
));
235 /* We should be able to get modeID from the bitmap */
236 OOP_GetAttr(bm
, aHidd_BitMap_ModeID
, &modeid
);
238 if (modeid
== vHidd_ModeID_Invalid
)
240 D(bug("[Nouveau] Invalid ModeID\n"));
244 /* Get Sync and PixelFormat properties */
245 struct pHidd_Gfx_GetMode __getmodemsg
=
250 }, *getmodemsg
= &__getmodemsg
;
252 getmodemsg
->mID
= OOP_GetMethodID(IID_Hidd_Gfx
, moHidd_Gfx_GetMode
);
253 OOP_DoMethod(gfx
, (OOP_Msg
)getmodemsg
);
255 OOP_GetAttr(sync
, aHidd_Sync_PixelClock
, &pixel
);
256 OOP_GetAttr(sync
, aHidd_Sync_HDisp
, &hdisp
);
257 OOP_GetAttr(sync
, aHidd_Sync_VDisp
, &vdisp
);
258 OOP_GetAttr(sync
, aHidd_Sync_HSyncStart
, &hstart
);
259 OOP_GetAttr(sync
, aHidd_Sync_VSyncStart
, &vstart
);
260 OOP_GetAttr(sync
, aHidd_Sync_HSyncEnd
, &hend
);
261 OOP_GetAttr(sync
, aHidd_Sync_VSyncEnd
, &vend
);
262 OOP_GetAttr(sync
, aHidd_Sync_HTotal
, &htotal
);
263 OOP_GetAttr(sync
, aHidd_Sync_VTotal
, &vtotal
);
265 D(bug("[Nouveau] Sync: %d, %d, %d, %d, %d, %d, %d, %d, %d\n",
266 pixel
, hdisp
, hstart
, hend
, htotal
, vdisp
, vstart
, vend
, vtotal
));
268 D(bug("[Nouveau] Connector %d, CRTC %d\n",
269 selectedconnector
->connector_id
, gfxdata
->selectedcrtcid
));
272 gfxdata
->selectedmode
= NULL
;
273 for (i
= 0; i
< selectedconnector
->count_modes
; i
++)
275 drmModeModeInfoPtr mode
= &selectedconnector
->modes
[i
];
277 if ((mode
->hdisplay
== hdisp
) && (mode
->vdisplay
== vdisp
) &&
278 (mode
->hsync_start
== hstart
) && (mode
->vsync_start
== vstart
) &&
279 (mode
->hsync_end
== hend
) && (mode
->vsync_end
== vend
))
281 gfxdata
->selectedmode
= mode
;
286 if (!gfxdata
->selectedmode
)
288 D(bug("[Nouveau] Not able to select mode\n"));
292 /* For screen switching the bitmap might have already once been a framebuffer
293 - check bmdata->fbid. Also the bitmap itself needs to know whether it is
294 added as framebuffer so that it can unregister itself in Dispose */
296 /* Add as frame buffer */
297 if (bmdata
->fbid
== 0)
299 ret
= drmModeAddFB(nvdev
->fd
, bmdata
->width
, bmdata
->height
,
300 bmdata
->depth
, bmdata
->bytesperpixel
* 8,
301 bmdata
->pitch
, bmdata
->bo
->handle
, &bmdata
->fbid
);
304 D(bug("[Nouveau] Not able to add framebuffer\n"));
311 if (!HIDDNouveauShowBitmapForSelectedMode(bm
))
313 D(bug("[Nouveau] Not able to set crtc\n"));
317 HIDDNouveauShowCursor(gfx
, TRUE
);
323 OOP_Object
* METHOD(Nouveau
, Root
, New
)
325 drmModeCrtcPtr selectedcrtc
= NULL
;
326 drmModeConnectorPtr selectedconnector
= NULL
;
327 struct nouveau_device
* dev
= NULL
;
328 struct nouveau_device_priv
* nvdev
= NULL
;
329 struct TagItem
* syncs
= NULL
;
330 struct CardData
* carddata
= &(SD(cl
)->carddata
);
332 ULONG selectedcrtcid
;
334 if (nouveau_init() < 0)
337 nouveau_device_open(&dev
, "");
338 nvdev
= nouveau_device(dev
);
340 /* Select crtc and connector */
341 if (!HIDDNouveauSelectConnectorCrtc(nvdev
->fd
, &selectedconnector
, &selectedcrtc
))
343 D(bug("[Nouveau] Not able to select connector and crtc\n"));
347 selectedcrtcid
= selectedcrtc
->crtc_id
;
348 drmModeFreeCrtc(selectedcrtc
);
350 /* Read connector and build sync tags */
351 syncs
= HIDDNouveauCreateSyncTagsFromConnector(cl
, selectedconnector
);
354 D(bug("[Nouveau] Not able to read any sync modes\n"));
359 /* Call super contructor */
361 struct TagItem pftags_24bpp
[] = {
362 { aHidd_PixFmt_RedShift
, 8 }, /* 0 */
363 { aHidd_PixFmt_GreenShift
, 16 }, /* 1 */
364 { aHidd_PixFmt_BlueShift
, 24 }, /* 2 */
365 { aHidd_PixFmt_AlphaShift
, 0 }, /* 3 */
366 { aHidd_PixFmt_RedMask
, 0x00ff0000 }, /* 4 */
367 { aHidd_PixFmt_GreenMask
, 0x0000ff00 }, /* 5 */
368 { aHidd_PixFmt_BlueMask
, 0x000000ff }, /* 6 */
369 { aHidd_PixFmt_AlphaMask
, 0x00000000 }, /* 7 */
370 { aHidd_PixFmt_ColorModel
, vHidd_ColorModel_TrueColor
}, /* 8 */
371 { aHidd_PixFmt_Depth
, 24 }, /* 9 */
372 { aHidd_PixFmt_BytesPerPixel
, 4 }, /* 10 */
373 { aHidd_PixFmt_BitsPerPixel
, 24 }, /* 11 */
374 { aHidd_PixFmt_StdPixFmt
, vHidd_StdPixFmt_BGR032
}, /* 12 Native */
375 { aHidd_PixFmt_BitMapType
, vHidd_BitMapType_Chunky
}, /* 15 */
379 struct TagItem pftags_16bpp
[] = {
380 { aHidd_PixFmt_RedShift
, 16 }, /* 0 */
381 { aHidd_PixFmt_GreenShift
, 21 }, /* 1 */
382 { aHidd_PixFmt_BlueShift
, 27 }, /* 2 */
383 { aHidd_PixFmt_AlphaShift
, 0 }, /* 3 */
384 { aHidd_PixFmt_RedMask
, 0x0000f800 }, /* 4 */
385 { aHidd_PixFmt_GreenMask
, 0x000007e0 }, /* 5 */
386 { aHidd_PixFmt_BlueMask
, 0x0000001f }, /* 6 */
387 { aHidd_PixFmt_AlphaMask
, 0x00000000 }, /* 7 */
388 { aHidd_PixFmt_ColorModel
, vHidd_ColorModel_TrueColor
}, /* 8 */
389 { aHidd_PixFmt_Depth
, 16 }, /* 9 */
390 { aHidd_PixFmt_BytesPerPixel
, 2 }, /* 10 */
391 { aHidd_PixFmt_BitsPerPixel
, 16 }, /* 11 */
392 { aHidd_PixFmt_StdPixFmt
, vHidd_StdPixFmt_RGB16_LE
}, /* 12 */
393 { aHidd_PixFmt_BitMapType
, vHidd_BitMapType_Chunky
}, /* 15 */
397 struct TagItem modetags
[] = {
398 { aHidd_Gfx_PixFmtTags
, (IPTR
)pftags_24bpp
},
399 { aHidd_Gfx_PixFmtTags
, (IPTR
)pftags_16bpp
},
400 { TAG_MORE
, (IPTR
)syncs
}, /* FIXME: sync tags will leak */
404 struct TagItem mytags
[] = {
405 { aHidd_Gfx_ModeTags
, (IPTR
)modetags
},
406 { TAG_MORE
, (IPTR
)msg
->attrList
}
409 struct pRoot_New mymsg
;
411 mymsg
.mID
= msg
->mID
;
412 mymsg
.attrList
= mytags
;
417 o
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
419 D(bug("[Nouveau] GFX New\n"));
423 struct HIDDNouveauData
* gfxdata
= OOP_INST_DATA(cl
, o
);
424 /* Pass local information to class */
425 gfxdata
->selectedcrtcid
= selectedcrtcid
;
426 gfxdata
->selectedmode
= NULL
;
427 gfxdata
->selectedconnector
= selectedconnector
;
432 /* Check chipset architecture */
433 switch (carddata
->dev
->chipset
& 0xf0)
436 carddata
->architecture
= NV_ARCH_04
;
439 carddata
->architecture
= NV_ARCH_10
;
442 carddata
->architecture
= NV_ARCH_20
;
445 carddata
->architecture
= NV_ARCH_30
;
449 carddata
->architecture
= NV_ARCH_40
;
455 carddata
->architecture
= NV_ARCH_50
;
458 carddata
->architecture
= NV_ARCH_C0
;
461 /* TODO: report error, how to handle it? */
465 nouveau_device_get_param(carddata
->dev
, NOUVEAU_GETPARAM_BUS_TYPE
, &value
);
466 if (value
== NV_PCIE
)
467 carddata
->IsPCIE
= TRUE
;
469 carddata
->IsPCIE
= FALSE
;
471 /* Allocate dma channel */
472 ret
= nouveau_channel_alloc(carddata
->dev
, NvDmaFB
, NvDmaTT
,
473 24 * 1024, &carddata
->chan
);
476 /* TODO: Check ret, how to handle ? */
479 /* Initialize acceleration objects */
481 ret
= HIDDNouveauAccelCommonInit(carddata
);
484 /* TODO: Check ret, how to handle ? */
487 /* Allocate buffer object for cursor */
488 nouveau_bo_new(carddata
->dev
, NOUVEAU_BO_VRAM
| NOUVEAU_BO_MAP
,
489 0, 64 * 64 * 4, &gfxdata
->cursor
);
490 /* TODO: Check return, hot to handle */
492 /* Allocate GART scratch buffer */
493 if (carddata
->dev
->vm_gart_size
> GART_BUFFER_SIZE
)
494 gartsize
= GART_BUFFER_SIZE
;
496 /* always leave 512kb for other things like the fifos */
497 gartsize
= carddata
->dev
->vm_gart_size
- 512 * 1024;
500 nouveau_bo_new(carddata
->dev
, NOUVEAU_BO_GART
| NOUVEAU_BO_MAP
,
501 0, gartsize
, &carddata
->GART
);
502 InitSemaphore(&carddata
->gartsemaphore
);
504 /* Set initial pattern (else 16-bit ROPs are not working) */
505 switch(carddata
->architecture
)
513 HIDDNouveauNV04SetPattern(carddata
, ~0, ~0, ~0, ~0);
516 HIDDNouveauNV50SetPattern(carddata
, ~0, ~0, ~0, ~0);
519 HIDDNouveauNVC0SetPattern(carddata
, ~0, ~0, ~0, ~0);
523 /* Create compositing object */
525 struct TagItem comptags
[] =
527 { aHidd_Compositing_GfxHidd
, (IPTR
)o
},
528 { TAG_DONE
, TAG_DONE
}
530 gfxdata
->compositing
= OOP_NewObject(SD(cl
)->compositingclass
, NULL
, comptags
);
531 /* TODO: Check if object was created, how to handle ? */
542 /* FIXME: IMPLEMENT DISPOSE - calling nouveau_close(), freeing cursor bo, gart bo,
543 selectedconnector, gfxdata->compositing, HIDDNouveauAccelFree */
545 /* FIXME: IMPLEMENT DISPOSE BITMAP - REMOVE FROM FB IF MARKED AS SUCH */
547 OOP_Object
* METHOD(Nouveau
, Hidd_Gfx
, NewBitMap
)
549 struct pHidd_Gfx_NewBitMap mymsg
;
551 HIDDT_StdPixFmt stdpf
;
552 struct HIDDNouveauData
* gfxdata
= OOP_INST_DATA(cl
, o
);
553 struct TagItem mytags
[] =
555 { TAG_IGNORE
, TAG_IGNORE
}, /* Placeholder for aHidd_BitMap_ClassPtr */
556 { TAG_IGNORE
, TAG_IGNORE
}, /* Placeholder for aHidd_BitMap_Align */
557 { aHidd_BitMap_Nouveau_CompositingHidd
, (IPTR
)gfxdata
->compositing
},
558 { TAG_MORE
, (IPTR
)msg
->attrList
}
561 /* Check if user provided valid ModeID */
562 /* Check for framebuffer - not needed as Nouveau is a NoFramebuffer driver */
563 /* Check for displayable - not needed - displayable has ModeID and we don't
564 distinguish between on-screen and off-screen bitmaps */
565 modeid
= (HIDDT_ModeID
)GetTagData(aHidd_BitMap_ModeID
, vHidd_ModeID_Invalid
, msg
->attrList
);
566 if (vHidd_ModeID_Invalid
!= modeid
)
568 /* User supplied a valid modeid. We can use our bitmap class */
569 mytags
[0].ti_Tag
= aHidd_BitMap_ClassPtr
;
570 mytags
[0].ti_Data
= (IPTR
)SD(cl
)->bmclass
;
573 /* Check if bitmap is a planar bitmap */
574 stdpf
= (HIDDT_StdPixFmt
)GetTagData(aHidd_BitMap_StdPixFmt
, vHidd_StdPixFmt_Unknown
, msg
->attrList
);
575 if (vHidd_StdPixFmt_Plane
== stdpf
)
577 mytags
[1].ti_Tag
= aHidd_BitMap_Align
;
578 mytags
[1].ti_Data
= 32;
581 /* We init a new message struct */
582 mymsg
.mID
= msg
->mID
;
583 mymsg
.attrList
= mytags
;
585 /* Pass the new message to the superclass */
588 return (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
591 VOID
METHOD(Nouveau
, Hidd_Gfx
, CopyBox
)
593 OOP_Class
* srcclass
= OOP_OCLASS(msg
->src
);
594 OOP_Class
* destclass
= OOP_OCLASS(msg
->dest
);
596 if (IS_NOUVEAU_BM_CLASS(srcclass
) && IS_NOUVEAU_BM_CLASS(destclass
))
598 /* FIXME: add checks for pixel format, etc */
599 struct HIDDNouveauBitMapData
* srcdata
= OOP_INST_DATA(srcclass
, msg
->src
);
600 struct HIDDNouveauBitMapData
* destdata
= OOP_INST_DATA(destclass
, msg
->dest
);
601 struct CardData
* carddata
= &(SD(cl
)->carddata
);
604 D(bug("[Nouveau] CopyBox 0x%x -> 0x%x\n", msg
->src
, msg
->dest
));
607 LOCK_BITMAP_BM(srcdata
)
608 LOCK_BITMAP_BM(destdata
)
610 UNMAP_BUFFER_BM(srcdata
)
611 UNMAP_BUFFER_BM(destdata
)
613 switch(carddata
->architecture
)
621 ret
= HIDDNouveauNV04CopySameFormat(carddata
, srcdata
, destdata
,
622 msg
->srcX
, msg
->srcY
, msg
->destX
, msg
->destY
,
623 msg
->width
, msg
->height
, GC_DRMD(msg
->gc
));
626 ret
= HIDDNouveauNV50CopySameFormat(carddata
, srcdata
, destdata
,
627 msg
->srcX
, msg
->srcY
, msg
->destX
, msg
->destY
,
628 msg
->width
, msg
->height
, GC_DRMD(msg
->gc
));
631 ret
= HIDDNouveauNVC0CopySameFormat(carddata
, srcdata
, destdata
,
632 msg
->srcX
, msg
->srcY
, msg
->destX
, msg
->destY
,
633 msg
->width
, msg
->height
, GC_DRMD(msg
->gc
));
637 UNLOCK_BITMAP_BM(destdata
);
638 UNLOCK_BITMAP_BM(srcdata
);
643 /* If operation failed, fallback to default method */
646 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
650 VOID
METHOD(Nouveau
, Root
, Get
)
654 if (IS_GFX_ATTR(msg
->attrID
, idx
))
658 case aoHidd_Gfx_NoFrameBuffer
:
659 *msg
->storage
= (IPTR
)TRUE
;
661 case aoHidd_Gfx_SupportsHWCursor
:
662 *msg
->storage
= (IPTR
)TRUE
;
664 case aoHidd_Gfx_HWSpriteTypes
:
665 *msg
->storage
= vHidd_SpriteType_DirectColor
;
667 case aoHidd_Gfx_DriverName
:
668 *msg
->storage
= (IPTR
)"Nouveau";
673 if (IS_GFXNOUVEAU_ATTR(msg
->attrID
, idx
))
677 case(aoHidd_Gfx_Nouveau_VRAMSize
):
680 nouveau_device_get_param(SD(cl
)->carddata
.dev
, NOUVEAU_GETPARAM_VRAM_SIZE
, &value
);
681 *msg
->storage
= (IPTR
)value
;
684 case(aoHidd_Gfx_Nouveau_GARTSize
):
687 nouveau_device_get_param(SD(cl
)->carddata
.dev
, NOUVEAU_GETPARAM_GART_SIZE
, &value
);
688 *msg
->storage
= (IPTR
)value
;
691 case(aoHidd_Gfx_Nouveau_VRAMFree
):
694 nouveau_device_get_param(SD(cl
)->carddata
.dev
, NOUVEAU_GETPARAM_VRAM_FREE
, &value
);
695 *msg
->storage
= (IPTR
)value
;
698 case(aoHidd_Gfx_Nouveau_GARTFree
):
701 nouveau_device_get_param(SD(cl
)->carddata
.dev
, NOUVEAU_GETPARAM_GART_FREE
, &value
);
702 *msg
->storage
= (IPTR
)value
;
708 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
711 ULONG
METHOD(Nouveau
, Hidd_Gfx
, ShowViewPorts
)
713 struct HIDDNouveauData
* gfxdata
= OOP_INST_DATA(cl
, o
);
714 struct pHidd_Compositing_BitMapStackChanged bscmsg
=
716 mID
: OOP_GetMethodID(IID_Hidd_Compositing
, moHidd_Compositing_BitMapStackChanged
),
720 D(bug("[Nouveau] ShowViewPorts enter TopLevelBM %x\n", (msg
->Data
? (msg
->Data
->Bitmap
) : NULL
)));
722 OOP_DoMethod(gfxdata
->compositing
, (OOP_Msg
)&bscmsg
);
724 return TRUE
; /* Indicate driver supports this method */
728 #define Machine_ARGB32 vHidd_StdPixFmt_ARGB32
730 #define Machine_ARGB32 vHidd_StdPixFmt_BGRA32
733 BOOL
METHOD(Nouveau
, Hidd_Gfx
, SetCursorShape
)
735 struct HIDDNouveauData
* gfxdata
= OOP_INST_DATA(cl
, o
);
737 if (msg
->shape
== NULL
)
740 HIDDNouveauShowCursor(o
, FALSE
);
747 ULONG curimage
[64 * 64];
748 struct CardData
* carddata
= &(SD(cl
)->carddata
);
750 OOP_GetAttr(msg
->shape
, aHidd_BitMap_Width
, &width
);
751 OOP_GetAttr(msg
->shape
, aHidd_BitMap_Height
, &height
);
754 if (width
> 64) width
= 64;
755 if (height
> 64) height
= 64;
757 /* Map the cursor buffer */
758 nouveau_bo_map(gfxdata
->cursor
, NOUVEAU_BO_WR
);
760 /* Clear the matrix */
761 for (i
= 0; i
< 64 * 64; i
++)
762 ((ULONG
*)gfxdata
->cursor
->map
)[i
] = 0;
764 /* Get data from the bitmap */
765 HIDD_BM_GetImage(msg
->shape
, (UBYTE
*)curimage
, 64 * 4, 0, 0,
766 width
, height
, Machine_ARGB32
);
768 if (carddata
->architecture
< NV_ARCH_50
)
770 ULONG offset
, pixel
, blue
, green
, red
, alpha
;
772 /* The image needs to be premultiplied */
773 for (y
= 0; y
< height
; y
++)
774 for (x
= 0; x
< width
; x
++)
777 pixel
= curimage
[offset
];
778 blue
= (pixel
& 0x000000FF);
779 green
= (pixel
& 0x0000FF00) >> 8;
780 red
= (pixel
& 0x00FF0000) >> 16;
781 alpha
= (pixel
& 0xFF000000) >> 24;
783 blue
= (blue
* alpha
) / 255;
784 green
= (green
* alpha
) / 255;
785 red
= (red
* alpha
) / 255;
787 curimage
[offset
] = (alpha
<< 24) | (red
<< 16) | (green
<< 8) | blue
;
791 for (y
= 0; y
< height
; y
++)
792 for (x
= 0; x
< width
; x
++)
794 ULONG offset
= y
* 64 + x
;
795 writel(curimage
[offset
], ((ULONG
*)gfxdata
->cursor
->map
) + (offset
));
798 nouveau_bo_unmap(gfxdata
->cursor
);
800 /* Show updated cursor */
801 HIDDNouveauShowCursor(o
, TRUE
);
807 BOOL
METHOD(Nouveau
, Hidd_Gfx
, SetCursorPos
)
809 struct HIDDNouveauData
* gfxdata
= OOP_INST_DATA(cl
, o
);
810 struct CardData
* carddata
= &(SD(cl
)->carddata
);
811 struct nouveau_device_priv
* nvdev
= nouveau_device(carddata
->dev
);
813 drmModeMoveCursor(nvdev
->fd
, gfxdata
->selectedcrtcid
, msg
->x
, msg
->y
);
818 VOID
METHOD(Nouveau
, Hidd_Gfx
, SetCursorVisible
)
820 HIDDNouveauShowCursor(o
, msg
->visible
);
823 static struct HIDD_ModeProperties modeprops
=
830 ULONG
METHOD(Nouveau
, Hidd_Gfx
, ModeProperties
)
832 ULONG len
= msg
->propsLen
;
834 if (len
> sizeof(modeprops
))
835 len
= sizeof(modeprops
);
836 CopyMem(&modeprops
, msg
->props
, len
);