wip prep commit in lieu of gfx subsystem update changes.
[AROS.git] / workbench / devs / monitors / IntelGMA / intelgma_bitmapclass.c
blobdb64b09432eb277f00238ee8c387d9327e36a7d3
1 /*
2 Copyright © 1995-2017, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #define DEBUG 0
8 #include <aros/debug.h>
9 #include <aros/libcall.h>
10 #include <aros/asmcall.h>
11 #include <aros/symbolsets.h>
12 #include <utility/tagitem.h>
13 #include <hidd/gfx.h>
14 #include <hidd/i2c.h>
15 #include <proto/oop.h>
16 #include <proto/exec.h>
17 #include <proto/utility.h>
19 #include <stdint.h>
20 #include <stdlib.h>
22 #include "intelgma_hidd.h"
23 #include "intelG45_regs.h"
24 #include "compositing.h"
26 struct __ROP ROP_table[] = {
27 { ROP3_ZERO, ROP3_ZERO }, /* GXclear */
28 { ROP3_DSa, ROP3_DPa }, /* Gxand */
29 { ROP3_SDna, ROP3_PDna }, /* GXandReverse */
30 { ROP3_S, ROP3_P }, /* GXcopy */
31 { ROP3_DSna, ROP3_DPna }, /* GXandInverted */
32 { ROP3_D, ROP3_D }, /* GXnoop */
33 { ROP3_DSx, ROP3_DPx }, /* GXxor */
34 { ROP3_DSo, ROP3_DPo }, /* GXor */
35 { ROP3_DSon, ROP3_DPon }, /* GXnor */
36 { ROP3_DSxn, ROP3_PDxn }, /* GXequiv */
37 { ROP3_Dn, ROP3_Dn }, /* GXinvert */
38 { ROP3_SDno, ROP3_PDno }, /* GXorReverse */
39 { ROP3_Sn, ROP3_Pn }, /* GXcopyInverted */
40 { ROP3_DSno, ROP3_DPno }, /* GXorInverted */
41 { ROP3_DSan, ROP3_DPan }, /* GXnand */
42 { ROP3_ONE, ROP3_ONE } /* GXset */
45 #define sd ((struct g45staticdata*)SD(cl))
47 #define POINT_OUTSIDE_CLIP(gc, x, y) \
48 ( (x) < GC_CLIPX1(gc) \
49 || (x) > GC_CLIPX2(gc) \
50 || (y) < GC_CLIPY1(gc) \
51 || (y) > GC_CLIPY2(gc) )
53 static BOOL CanAccelerateBlits(UWORD product_id)
55 return product_id >= 0x2582
56 && product_id <= 0x27ae;
59 OOP_Object *METHOD(GMABM, Root, New)
61 EnterFunc(bug("[GMABitMap] Bitmap::New()\n"));
63 o = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
64 if (o)
66 GMABitMap_t *bm = OOP_INST_DATA(cl, o);
68 IPTR width, height, depth;
69 UBYTE bytesPerPixel;
70 IPTR displayable;
72 OOP_Object *pf;
74 InitSemaphore(&bm->bmLock);
76 D(bug("[GMABitMap] Super called. o=%p\n", o));
78 OOP_GetAttr(o, aHidd_BitMap_Width, &width);
79 OOP_GetAttr(o, aHidd_BitMap_Height, &height);
80 OOP_GetAttr(o, aHidd_BitMap_PixFmt, (APTR)&pf);
81 OOP_GetAttr(pf, aHidd_PixFmt_Depth, &depth);
82 OOP_GetAttr(o, aHidd_BitMap_Displayable, &displayable);
84 bm->onbm = displayable;
86 D(bug("[GMABitmap] width=%d height=%d depth=%d\n", width, height, depth));
88 if (width == 0 || height == 0 || depth == 0)
90 bug("[GMABitMap] size mismatch!\n");
93 if (depth == 24)
94 depth = 32;
96 if (depth <= 8)
97 bytesPerPixel = 1;
98 else if (depth <= 16)
99 bytesPerPixel = 2;
100 else
101 bytesPerPixel = 4;
103 bm->width = width;
104 bm->height = height;
105 bm->pitch = (width * bytesPerPixel + 63) & ~63;
106 bm->depth = depth;
107 bm->bpp = bytesPerPixel;
108 bm->framebuffer = AllocBitmapArea(sd, bm->width, bm->height, bm->bpp);
109 bm->fbgfx = TRUE;
110 bm->state = NULL;
111 bm->bitmap = o;
112 bm->usecount = 0;
113 bm->xoffset = 0;
114 bm->yoffset = 0;
115 bm->fbid = 0; /* Default value */
117 if (displayable) bm->displayable = TRUE; else bm->displayable = FALSE;
118 //bm->compositing = sd->compositing;
119 bm->compositing = (OOP_Object *)
120 GetTagData(aHidd_BitMap_IntelG45_CompositingHidd, 0, msg->attrList);
121 /* FIXME: check if compositing hidd was passed */
123 if (displayable)
125 if ((bm->framebuffer != -1))
127 HIDDT_ModeID modeid;
128 OOP_Object *sync;
130 bm->fbgfx = TRUE;
132 /* We should be able to get modeID from the bitmap */
133 OOP_GetAttr(o, aHidd_BitMap_ModeID, &modeid);
135 D(bug("[GMABitMap] BM_ModeID=%x\n", modeid));
137 if (modeid != vHidd_ModeID_Invalid)
139 IPTR pixel;
140 IPTR hdisp, vdisp, hstart, hend, htotal, vstart, vend, vtotal, flags;
142 /* Get Sync and PixelFormat properties */
143 struct pHidd_Gfx_GetMode __getmodemsg = {
144 modeID: modeid,
145 syncPtr: &sync,
146 pixFmtPtr: &pf,
147 }, *getmodemsg = &__getmodemsg;
149 getmodemsg->mID = OOP_GetMethodID((STRPTR)CLID_Hidd_Gfx, moHidd_Gfx_GetMode);
150 OOP_DoMethod(sd->GMAObject, (OOP_Msg)getmodemsg);
152 OOP_GetAttr(sync, aHidd_Sync_PixelClock, &pixel);
153 OOP_GetAttr(sync, aHidd_Sync_HDisp, &hdisp);
154 OOP_GetAttr(sync, aHidd_Sync_VDisp, &vdisp);
155 OOP_GetAttr(sync, aHidd_Sync_HSyncStart, &hstart);
156 OOP_GetAttr(sync, aHidd_Sync_VSyncStart, &vstart);
157 OOP_GetAttr(sync, aHidd_Sync_HSyncEnd, &hend);
158 OOP_GetAttr(sync, aHidd_Sync_VSyncEnd, &vend);
159 OOP_GetAttr(sync, aHidd_Sync_HTotal, &htotal);
160 OOP_GetAttr(sync, aHidd_Sync_VTotal, &vtotal);
161 OOP_GetAttr(sync, aHidd_Sync_Flags, &flags);
163 bm->state = (GMAState_t *)AllocVecPooled(sd->MemPool,
164 sizeof(GMAState_t));
166 pixel /= 1000;
168 if (bm->state)
170 G45_InitMode(sd, bm->state, width, height, depth, pixel, bm->framebuffer,
171 hdisp, vdisp,
172 hstart, hend, htotal,
173 vstart, vend, vtotal, flags);
175 D(bug("[GMA] displayable Bitmap::new = %p\n", o));
177 return o;
181 else
183 bm->framebuffer = (IPTR)AllocMem(bm->pitch * bm->height,
184 MEMF_PUBLIC | MEMF_CLEAR);
185 bm->fbgfx = FALSE;
187 return o;
190 else
192 if (bm->framebuffer == -1)
194 bm->framebuffer = (IPTR)AllocMem(bm->pitch * bm->height,
195 MEMF_PUBLIC | MEMF_CLEAR);
196 bm->fbgfx = FALSE;
199 if (bm->framebuffer != 0)
201 D(bug("[GMA] not displayable Bitmap::new = %p\n", o));
202 return o;
206 OOP_MethodID disp_mid = OOP_GetMethodID((STRPTR)IID_Root, moRoot_Dispose);
207 OOP_CoerceMethod(cl, o, (OOP_Msg) &disp_mid);
210 return NULL;
214 VOID METHOD(GMABM, Root, Dispose)
216 GMABitMap_t *bm = OOP_INST_DATA(cl, o);
218 LOCK_BITMAP
219 LOCK_HW
221 if (bm->fbgfx)
223 DO_FLUSH();
225 FreeBitmapArea(sd, bm->framebuffer, bm->width, bm->height, bm->bpp);
227 if (sd->VisibleBitmap == bm)
229 sd->VisibleBitmap = NULL;
232 bm->framebuffer = -1;
233 bm->fbgfx = 0;
235 else
236 FreeMem((APTR)bm->framebuffer, bm->pitch * bm->height);
238 if (bm->state)
239 FreeVecPooled(sd->MemPool, bm->state);
241 bm->state = NULL;
243 #if 0
244 RADEONWaitForIdleMMIO(sd);
247 FreeVecPooled(sd->memPool, bm->addresses);
249 #endif
251 UNLOCK_HW
252 UNLOCK_BITMAP
254 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
257 VOID METHOD(GMABM, Root, Get)
259 GMABitMap_t *bm = OOP_INST_DATA(cl, o);
260 ULONG idx;
262 if (IS_GMABM_ATTR(msg->attrID, idx))
264 switch (idx)
266 case aoHidd_GMABitMap_Drawable:
267 if (bm->fbgfx)
268 *msg->storage = bm->framebuffer + (IPTR)sd->Card.Framebuffer;
269 else
270 *msg->storage = bm->framebuffer;
271 break;
272 default:
273 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
276 else
278 if (IS_BM_ATTR(msg->attrID, idx))
280 switch (idx)
282 case aoHidd_BitMap_LeftEdge:
283 *msg->storage = bm->xoffset;
284 return;
285 case aoHidd_BitMap_TopEdge:
286 *msg->storage = bm->yoffset;
287 return;
291 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
295 VOID METHOD(GMABM, Root, Set)
297 struct TagItem *tag, *tstate;
298 GMABitMap_t * bmdata = OOP_INST_DATA(cl, o);
299 ULONG idx;
300 LONG newxoffset = bmdata->xoffset;
301 LONG newyoffset = bmdata->yoffset;
302 tstate = msg->attrList;
303 while((tag = NextTagItem(&tstate)))
305 if(IS_BITMAP_ATTR(tag->ti_Tag, idx))
307 switch(idx)
309 case aoHidd_BitMap_LeftEdge:
310 newxoffset = tag->ti_Data;
311 break;
312 case aoHidd_BitMap_TopEdge:
313 newyoffset = tag->ti_Data;
314 break;
319 /* If there was a change requested, validate it */
320 struct pHidd_Compositing_ValidateBitMapPositionChange vbpcmsg =
322 mID : SD(cl)->mid_ValidateBitMapPositionChange,
323 bm : o,
324 newxoffset : &newxoffset,
325 newyoffset : &newyoffset
328 OOP_DoMethod(bmdata->compositing, (OOP_Msg)&vbpcmsg);
330 if ((newxoffset != bmdata->xoffset) || (newyoffset != bmdata->yoffset))
332 /* If change passed validation, execute it */
333 struct pHidd_Compositing_BitMapPositionChanged bpcmsg =
335 mID : SD(cl)->mid_BitMapPositionChanged,
336 bm : o
339 bmdata->xoffset = newxoffset;
340 bmdata->yoffset = newyoffset;
342 OOP_DoMethod(bmdata->compositing, (OOP_Msg)&bpcmsg);
345 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
349 /* not used?
350 static inline void setup_engine(OOP_Class *cl, OOP_Object *o, GMABitMap_t *bm)
352 if (sd->Engine2DOwner != bm && bm->fbgfx)
354 LOCK_HW
356 START_RING(8);
358 OUT_RING((2 << 29) | (0x11 << 22) | (7)); // BR00
359 if (bm->bpp == 1)
360 OUT_RING(0xff << 16 | bm->pitch/4);
361 else if (bm->bpp == 2)
362 OUT_RING(0xff << 16 | (bm->pitch / 4) | (1 << 24));
363 else
364 OUT_RING(0xff << 16 | (bm->pitch / 4) | (3 << 24));
365 OUT_RING(0);
366 OUT_RING(0);
367 OUT_RING(bm->framebuffer);
368 OUT_RING(0);
370 ADVANCE_RING();
372 sd->Engine2DOwner = bm;
374 UNLOCK_HW
379 VOID METHOD(GMABM, Hidd_BitMap, PutPixel)
381 GMABitMap_t *bm = OOP_INST_DATA(cl, o);
382 void *ptr;
384 // if (msg->x >= 0 && msg->x < bm->width && msg->y >= 0 && msg->y < bm->height)
386 LOCK_BITMAP
388 if (bm->fbgfx)
390 LOCK_HW
391 DO_FLUSH();
392 UNLOCK_HW
395 if (bm->fbgfx)
396 ptr = (void *)(bm->framebuffer + sd->Card.Framebuffer + msg->y * bm->pitch);
397 else
398 ptr = (void *)(bm->framebuffer + msg->y * bm->pitch);
401 switch (bm->bpp)
403 case 1:
404 ((UBYTE *)ptr)[msg->x] = msg->pixel;
405 break;
406 case 2:
407 ((UWORD *)ptr)[msg->x] = msg->pixel;
408 break;
409 case 4:
410 ((ULONG *)ptr)[msg->x] = msg->pixel;
411 break;
414 UNLOCK_BITMAP
418 HIDDT_Pixel METHOD(GMABM, Hidd_BitMap, GetPixel)
420 GMABitMap_t *bm = OOP_INST_DATA(cl, o);
421 void *ptr;
422 HIDDT_Pixel pixel = 0;
424 LOCK_BITMAP
426 if (bm->fbgfx)
428 LOCK_HW
429 DO_FLUSH();
430 UNLOCK_HW
433 if (bm->fbgfx)
434 ptr = sd->Card.Framebuffer;
435 else
436 ptr = NULL;
437 ptr += bm->framebuffer + msg->y * bm->pitch;
439 switch (bm->bpp)
441 case 1:
442 pixel = ((UBYTE *)ptr)[msg->x];
443 break;
444 case 2:
445 pixel = ((UWORD *)ptr)[msg->x];
446 break;
447 case 4:
448 pixel = ((ULONG *)ptr)[msg->x];
449 break;
452 UNLOCK_BITMAP
454 return pixel;
457 VOID METHOD(GMABM, Hidd_BitMap, DrawPixel)
459 GMABitMap_t *bm = OOP_INST_DATA(cl, o);
460 void *ptr;
461 OOP_Object *gc = msg->gc;
463 HIDDT_Pixel src, dest = 0, val;
464 HIDDT_DrawMode mode;
465 HIDDT_Pixel writeMask;
467 if (bm->fbgfx)
468 ptr = sd->Card.Framebuffer;
469 else
470 ptr = NULL;
471 ptr += bm->framebuffer + msg->y * bm->pitch;
473 src = GC_FG(gc);
474 mode = GC_DRMD(gc);
476 LOCK_BITMAP
478 if (bm->fbgfx)
480 LOCK_HW
481 DO_FLUSH();
482 UNLOCK_HW
485 if (vHidd_GC_DrawMode_Copy == mode && GC_COLMASK(gc) == ~0)
487 val = src;
489 else
491 switch (bm->bpp)
493 case 1:
494 dest = ((UBYTE *)ptr)[msg->x];
495 break;
496 case 2:
497 dest = ((UWORD *)ptr)[msg->x];
498 break;
499 case 4:
500 dest = ((ULONG *)ptr)[msg->x];
501 break;
504 writeMask = ~GC_COLMASK(gc) & dest;
506 val = 0;
508 if(mode & 1) val = ( src & dest);
509 if(mode & 2) val = ( src & ~dest) | val;
510 if(mode & 4) val = (~src & dest) | val;
511 if(mode & 8) val = (~src & ~dest) | val;
513 val = (val & (writeMask | GC_COLMASK(gc) )) | writeMask;
516 if (bm->fbgfx)
518 LOCK_HW
519 DO_FLUSH();
520 UNLOCK_HW
523 switch (bm->bpp)
525 case 1:
526 ((UBYTE *)ptr)[msg->x] = val;
527 break;
528 case 2:
529 ((UWORD *)ptr)[msg->x] = val;
530 break;
531 case 4:
532 ((ULONG *)ptr)[msg->x] = val;
533 break;
536 UNLOCK_BITMAP
539 VOID METHOD(GMABM, Hidd_BitMap, DrawEllipse)
541 GMABitMap_t *bm = OOP_INST_DATA(cl, o);
542 OOP_Object *gc = msg->gc;
543 WORD x = msg->rx, y = 0; /* ellipse points */
544 HIDDT_Pixel src;
545 HIDDT_DrawMode mode;
547 /* intermediate terms to speed up loop */
548 LONG t1 = msg->rx * msg->rx, t2 = t1 << 1, t3 = t2 << 1;
549 LONG t4 = msg->ry * msg->ry, t5 = t4 << 1, t6 = t5 << 1;
550 LONG t7 = msg->rx * t5, t8 = t7 << 1, t9 = 0L;
551 LONG d1 = t2 - t7 + (t4 >> 1); /* error terms */
552 LONG d2 = (t1 >> 1) - t8 + t5;
554 APTR doclip = GC_DOCLIP(gc);
556 src = GC_FG(gc);
557 mode = GC_DRMD(gc);
559 void _drawpixel(int x, int y)
561 OUT_RING((2 << 29) | (0x24 << 22) );
562 OUT_RING((y << 16) | x);
565 LOCK_BITMAP
567 if (bm->fbgfx)
570 LOCK_HW
572 uint32_t br00, br01, br24, br25, br09, br05, br06, br07;
574 br00 = (2 << 29) | (0x1 << 22) | 6;
576 if (bm->bpp == 4)
577 br00 |= (3 << 20);
579 br01 = ROP_table[mode].pattern | (bm->pitch);
580 if (bm->bpp == 4)
581 br01 |= 3 << 24;
582 else if (bm->bpp == 2)
583 br01 |= 1 << 24;
585 if (doclip)
586 br01 |= (1 << 30);
588 br24 = GC_CLIPX1(gc) | (GC_CLIPY1(gc) << 16);
589 br25 = (GC_CLIPX2(gc)+1) | ((GC_CLIPY2(gc)+1) << 16);
590 br09 = bm->framebuffer;
591 br05 = src;
592 br06 = 0;
593 br07 = 0;
595 START_RING(8);
597 OUT_RING(br00);
598 OUT_RING(br01);
599 OUT_RING(br24);
600 OUT_RING(br25);
601 OUT_RING(br09);
602 OUT_RING(br05);
603 OUT_RING(br06);
604 OUT_RING(br07);
606 while (d2 < 0) /* til slope = -1 */
608 /* draw 4 points using symmetry */
611 START_RING(2*4);
613 _drawpixel(msg->x + x, msg->y + y);
614 _drawpixel(msg->x + x, msg->y - y);
615 _drawpixel(msg->x - x, msg->y + y);
616 _drawpixel(msg->x - x, msg->y - y);
618 ADVANCE_RING();
621 y++; /* always move up here */
622 t9 = t9 + t3;
623 if (d1 < 0) /* move straight up */
625 d1 = d1 + t9 + t2;
626 d2 = d2 + t9;
628 else /* move up and left */
630 x--;
631 t8 = t8 - t6;
632 d1 = d1 + t9 + t2 - t8;
633 d2 = d2 + t9 + t5 - t8;
637 do /* rest of top right quadrant */
639 /* draw 4 points using symmetry */
641 START_RING(2*4);
643 _drawpixel(msg->x + x, msg->y + y);
644 _drawpixel(msg->x + x, msg->y - y);
645 _drawpixel(msg->x - x, msg->y + y);
646 _drawpixel(msg->x - x, msg->y - y);
648 ADVANCE_RING();
651 x--; /* always move left here */
652 t8 = t8 - t6;
653 if (d2 < 0) /* move up and left */
655 y++;
656 t9 = t9 + t3;
657 d2 = d2 + t9 + t5 - t8;
659 else /* move straight left */
661 d2 = d2 + t5 - t8;
664 } while (x >= 0);
666 UNLOCK_HW
668 else
669 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
671 UNLOCK_BITMAP
674 VOID METHOD(GMABM, Hidd_BitMap, DrawLine)
676 GMABitMap_t *bm = OOP_INST_DATA(cl, o);
677 OOP_Object *gc = msg->gc;
678 HIDDT_Pixel src;
679 HIDDT_DrawMode mode;
681 WORD dx, dy, incrE, incrNE, d, x, y, s1, s2, t, i;
682 LONG x1, y1, x2, y2;
684 APTR doclip = GC_DOCLIP(gc);
686 src = GC_FG(gc);
687 mode = GC_DRMD(gc);
689 void _drawpixel(int x, int y)
691 OUT_RING((2 << 29) | (0x24 << 22) );
692 OUT_RING((y << 16) | x);
695 if (doclip)
697 /* If line is not inside cliprect, then just return */
698 /* Normalize coords */
699 if (msg->x1 > msg->x2)
701 x1 = msg->x2; x2 = msg->x1;
703 else
705 x1 = msg->x1; x2 = msg->x2;
708 if (msg->y1 > msg->y2)
710 y1 = msg->y2; y2 = msg->y1;
712 else
714 y1 = msg->y1; y2 = msg->y2;
717 if ( x1 > GC_CLIPX2(gc)
718 || x2 < GC_CLIPX1(gc)
719 || y1 > GC_CLIPY2(gc)
720 || y2 < GC_CLIPY1(gc) )
723 /* Line is not inside cliprect, so just return */
724 return;
729 x1 = msg->x1;
730 y1 = msg->y1;
731 x2 = msg->x2;
732 y2 = msg->y2;
734 LOCK_BITMAP
736 if ((GC_LINEPAT(gc) != (UWORD)~0) || !bm->fbgfx)
738 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
740 else
742 LOCK_HW
744 uint32_t br00, br01, br24, br25, br09, br05, br06, br07;
745 uint32_t ring_space;
747 br00 = (2 << 29) | (0x1 << 22) | 6;
749 if (bm->bpp == 4)
750 br00 |= (3 << 20);
752 br01 = ROP_table[mode].pattern | (bm->pitch);
753 if (bm->bpp == 4)
754 br01 |= 3 << 24;
755 else if (bm->bpp == 2)
756 br01 |= 1 << 24;
758 if (doclip)
759 br01 |= (1 << 30);
761 br24 = GC_CLIPX1(gc) | (GC_CLIPY1(gc) << 16);
762 br25 = (GC_CLIPX2(gc)+1) | ((GC_CLIPY2(gc)+1) << 16);
763 br09 = bm->framebuffer;
764 br05 = src;
765 br06 = 0;
766 br07 = 0;
768 START_RING(8);
770 OUT_RING(br00);
771 OUT_RING(br01);
772 OUT_RING(br24);
773 OUT_RING(br25);
774 OUT_RING(br09);
775 OUT_RING(br05);
776 OUT_RING(br06);
777 OUT_RING(br07);
779 if (y1 == y2)
782 Horizontal line drawing code.
784 y = y1;
786 /* Don't swap coordinates if x2 < x1! Because of linepattern! */
788 if (x1 < x2)
790 x2++;
791 dx = 1;
793 else
795 x2--;
796 dx = -1;
799 ring_space = x2-x1+1;
800 if (ring_space > 500)
801 ring_space = 500;
803 START_RING(ring_space);
805 for(i = x1; i != x2; i += dx)
807 _drawpixel(i, y);
809 ring_space-=2;
810 if (!ring_space)
812 ADVANCE_RING();
813 ring_space = x2-i+1;
814 if (ring_space > 500)
815 ring_space=500;
816 START_RING(ring_space);
820 else if (x1 == x2)
823 Vertical line drawing code.
825 x = x1;
827 /* Don't swap coordinates if y2 < y1! Because of linepattern! */
829 if (y1 < y2)
831 y2++;
832 dy = 1;
834 else
836 y2--;
837 dy = -1;
840 ring_space = y2-y1+1;
841 if (ring_space > 500)
842 ring_space = 500;
844 START_RING(ring_space);
846 for(i = y1; i != y2; i += dy)
848 _drawpixel(x, i);
850 ring_space-=2;
851 if (!ring_space)
853 ADVANCE_RING();
854 ring_space = y2-i+1;
855 if (ring_space > 500)
856 ring_space=500;
857 START_RING(ring_space);
861 else
864 Generic line drawing code.
866 /* Calculate slope */
867 dx = abs(x2 - x1);
868 dy = abs(y2 - y1);
870 /* which direction? */
871 if((x2 - x1) > 0) s1 = 1; else s1 = - 1;
872 if((y2 - y1) > 0) s2 = 1; else s2 = - 1;
874 /* change axes if dx < dy */
875 if(dx < dy)
877 d = dx;
878 dx = dy;
879 dy = d;
880 t = 0;
882 else
884 t = 1;
887 d = 2 * dy - dx; /* initial value of d */
889 incrE = 2 * dy; /* Increment use for move to E */
890 incrNE = 2 * (dy - dx); /* Increment use for move to NE */
892 x = x1; y = y1;
894 ring_space = dx+1;
895 if (ring_space > 500)
896 ring_space = 500;
898 START_RING(ring_space);
900 for(i = 0; i <= dx; i++)
902 /* Pixel inside ? */
903 _drawpixel(x, y);
905 ring_space-=2;
906 if (!ring_space)
908 ADVANCE_RING();
909 ring_space = dx-i+1;
910 if (ring_space > 500)
911 ring_space=500;
912 START_RING(ring_space);
915 if(d <= 0)
917 if(t == 1)
919 x = x + s1;
921 else
923 y = y + s2;
926 d = d + incrE;
928 else
930 x = x + s1;
931 y = y + s2;
932 d = d + incrNE;
937 ADVANCE_RING();
939 DO_FLUSH();
940 UNLOCK_HW
943 UNLOCK_BITMAP
946 ULONG METHOD(GMABM, Hidd_BitMap, BytesPerLine)
948 GMABitMap_t *bm = OOP_INST_DATA(cl, o);
950 return (bm->pitch);
953 BOOL METHOD(GMABM, Hidd_BitMap, ObtainDirectAccess)
955 GMABitMap_t *bm = OOP_INST_DATA(cl, o);
956 LOCK_BITMAP
957 IPTR VideoData = bm->framebuffer;
958 if (bm->fbgfx)
960 VideoData += (IPTR)sd->Card.Framebuffer;
961 LOCK_HW
962 DO_FLUSH();
963 UNLOCK_HW
965 *msg->addressReturn = (UBYTE*)VideoData;
966 *msg->widthReturn = bm->pitch / bm->bpp;
967 *msg->heightReturn = bm->height;
968 *msg->bankSizeReturn = *msg->memSizeReturn = bm->pitch * bm->height;
969 return TRUE;
972 VOID METHOD(GMABM, Hidd_BitMap, ReleaseDirectAccess)
975 GMABitMap_t *bm = OOP_INST_DATA(cl, o);
976 UNLOCK_BITMAP
978 if (bm->displayable)
980 struct pHidd_Compositing_BitMapRectChanged brcmsg =
982 mID : SD(cl)->mid_BitMapRectChanged,
983 bm : o,
984 x : 0,
985 y : 0,
986 width : bm->width,
987 height : bm->height
989 OOP_DoMethod(bm->compositing, (OOP_Msg)&brcmsg);
994 #define pHidd_BitMap_FillRect pHidd_BitMap_DrawRect
996 VOID METHOD(GMABM, Hidd_BitMap, FillRect)
998 GMABitMap_t *bm = OOP_INST_DATA(cl, o);
1000 LOCK_BITMAP
1002 if (bm->fbgfx)
1004 LOCK_HW
1006 uint32_t br00,br13,br14,br09,br16;
1008 br00 = (2 << 29) | (0x40 << 22) | 3;
1010 if (bm->bpp == 4)
1011 br00 |= 3 << 20;
1013 br13 = (ROP_table[GC_DRMD(msg->gc)].pattern) | (bm->pitch);
1014 switch (bm->bpp)
1016 case 4:
1017 br13 |= (3 << 24);
1018 break;
1019 case 2:
1020 br13 |= 1 << 24;
1021 break;
1022 default:
1023 break;
1026 br14 = ((msg->maxY - msg->minY+1) << 16) | ((msg->maxX - msg->minX+1) * bm->bpp);
1028 br09 = bm->framebuffer + msg->minX * bm->bpp + msg->minY * bm->pitch;
1029 br16 = GC_FG(msg->gc);
1031 START_RING(6);
1032 OUT_RING(br00);
1033 OUT_RING(br13);
1034 OUT_RING(br14);
1035 OUT_RING(br09);
1036 OUT_RING(br16);
1037 OUT_RING(0);
1038 ADVANCE_RING();
1040 DO_FLUSH();
1041 UNLOCK_HW
1043 else
1044 OOP_DoSuperMethod(cl, o, (OOP_Msg) msg);
1046 UNLOCK_BITMAP
1049 /* Unaccelerated functions */
1051 static inline int do_alpha(int a, int v)
1053 int tmp = a*v;
1054 return ((tmp << 8) + tmp + 32768) >> 16;
1058 the BLT engine (the blitter) can not do alpha blending,
1059 however we may utilise the 3d engine in future ..
1061 VOID METHOD(GMABM, Hidd_BitMap, PutAlphaImage)
1063 GMABitMap_t *bm = OOP_INST_DATA(cl, o);
1064 IPTR VideoData;
1066 LOCK_BITMAP
1068 VideoData = bm->framebuffer;
1070 if ((bm->fbgfx) && ((bm->bpp == 2) || (bm->bpp == 4)))
1072 ULONG *pixarray, *pasrc = (ULONG *)msg->pixels;
1073 ULONG srcpix, x, y = msg->y;
1074 LONG src_red, src_green, src_blue, src_alpha;
1075 LONG dst_red, dst_green, dst_blue;
1076 UWORD height = msg->height;
1077 UWORD bw = msg->width;
1079 /* Since we wont use the BLT engine now, flush the chip */
1080 LOCK_HW
1081 DO_FLUSH();
1082 UNLOCK_HW
1085 * Treat each depth case separately
1087 if (bm->bpp == 4)
1089 ULONG *xbuf = (ULONG *)(VideoData + sd->Card.Framebuffer + (msg->x << 2) + (y * bm->pitch));
1090 ULONG destpix;
1092 while(height--)
1094 pixarray = pasrc;
1095 for (x=0; x < bw; x++)
1097 /* Read RGBA pixel from input array */
1098 srcpix = *pixarray++;
1099 #if AROS_BIG_ENDIAN
1100 src_red = (srcpix & 0x00FF0000) >> 16;
1101 src_green = (srcpix & 0x0000FF00) >> 8;
1102 src_blue = (srcpix & 0x000000FF);
1103 src_alpha = (srcpix & 0xFF000000) >> 24;
1104 #else
1105 src_red = (srcpix & 0x0000FF00) >> 8;
1106 src_green = (srcpix & 0x00FF0000) >> 16;
1107 src_blue = (srcpix & 0xFF000000) >> 24;
1108 src_alpha = (srcpix & 0x000000FF);
1109 #endif
1111 * If the pixel is Opaque (alpha=0), skip unnecessary
1112 * reads and writes to VRAM.
1114 if (src_alpha != 0)
1116 if (src_alpha == 0xff)
1118 /* Fully Transparent, just copy the source pixel */
1119 dst_red = src_red;
1120 dst_green = src_green;
1121 dst_blue = src_blue;
1123 else
1125 /* Alpha blend the source and destination pixels */
1126 destpix = xbuf[x];
1127 //#if AROS_BIG_ENDIAN
1128 // dst_red = (destpix & 0x0000FF00) >> 8;
1129 // dst_green = (destpix & 0x00FF0000) >> 16;
1130 // dst_blue = (destpix & 0xFF000000) >> 24;
1131 //#else
1132 dst_red = (destpix & 0x00FF0000) >> 16;
1133 dst_green = (destpix & 0x0000FF00) >> 8;
1134 dst_blue = (destpix & 0x000000FF);
1135 //#endif
1137 dst_red += do_alpha(src_alpha, src_red - dst_red);
1138 dst_green += do_alpha(src_alpha, src_green - dst_green);
1139 dst_blue += do_alpha(src_alpha, src_blue - dst_blue);
1142 //#if AROS_BIG_ENDIAN
1143 // destpix = (dst_blue << 24) + (dst_green << 16) + (dst_red << 8);
1144 //#else
1145 destpix = (dst_red << 16) + (dst_green << 8) + (dst_blue);
1146 //#endif
1147 /* Store the new pixel */
1148 xbuf[x] = destpix;
1152 y++;
1153 pasrc = (ULONG *)((IPTR)pasrc + msg->modulo);
1154 xbuf = (ULONG *)((IPTR)xbuf + bm->pitch);
1157 else
1159 UWORD *xbuf = (UWORD *)(VideoData + sd->Card.Framebuffer + (msg->x << 1) + (y * bm->pitch));
1160 UWORD destpix;
1162 while(height--)
1164 pixarray = pasrc;
1165 for (x=0; x < bw; x++)
1167 srcpix = *pixarray++;
1168 #if AROS_BIG_ENDIAN
1169 src_red = (srcpix & 0x00FF0000) >> 16;
1170 src_green = (srcpix & 0x0000FF00) >> 8;
1171 src_blue = (srcpix & 0x000000FF);
1172 src_alpha = (srcpix & 0xFF000000) >> 24;
1173 #else
1174 src_red = (srcpix & 0x0000FF00) >> 8;
1175 src_green = (srcpix & 0x00FF0000) >> 16;
1176 src_blue = (srcpix & 0xFF000000) >> 24;
1177 src_alpha = (srcpix & 0x000000FF);
1178 #endif
1179 /* If Opaque, skip unnecessary reads and writes to VRAM. */
1180 if (src_alpha != 0)
1182 if (src_alpha == 0xff)
1184 /* Fully Transparent */
1185 dst_red = src_red;
1186 dst_green = src_green;
1187 dst_blue = src_blue;
1189 else
1191 /* Alpha blend */
1193 destpix = xbuf[x];
1195 dst_red = (destpix & 0x0000F800) >> 8;
1196 dst_green = (destpix & 0x000007e0) >> 3;
1197 dst_blue = (destpix & 0x0000001f) << 3;
1199 dst_red += do_alpha(src_alpha, src_red - dst_red);
1200 dst_green += do_alpha(src_alpha, src_green - dst_green);
1201 dst_blue += do_alpha(src_alpha, src_blue - dst_blue);
1204 destpix = (((dst_red << 8) & 0xf800) | ((dst_green << 3) & 0x07e0) | ((dst_blue >> 3) & 0x001f));
1206 xbuf[x] = destpix;
1209 y++;
1210 pasrc = (ULONG *)((IPTR)pasrc + msg->modulo);
1211 xbuf = (UWORD *)((IPTR)xbuf + bm->pitch);
1215 else
1216 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
1218 UNLOCK_BITMAP
1221 VOID METHOD(GMABM, Hidd_BitMap, PutImage)
1223 GMABitMap_t *bm = OOP_INST_DATA(cl, o);
1224 BOOL done = FALSE;
1226 LOCK_BITMAP
1228 IPTR VideoData = bm->framebuffer;
1230 /* In 32bpp mode the StdPixFmt_Native format bitmap can be drawn using the 2D engine.
1231 * This is done by mapping the source range via GTT into video space and issuing the blit.
1233 * Unfortunately, AROS likes to re-use the same scratch line many times during one single bitmap
1234 * draw (many blits of height=1 instead of one single blit).
1235 * Therefore, many many the cache flushes kill the expected performance significantly. */
1237 if (CanAccelerateBlits(sd->ProductID) && bm->fbgfx && bm->bpp == 4
1238 && (msg->pixFmt == vHidd_StdPixFmt_Native
1239 || msg->pixFmt == vHidd_StdPixFmt_Native32
1240 || msg->pixFmt == vHidd_StdPixFmt_BGRA32
1241 || msg->pixFmt == vHidd_StdPixFmt_BGR032))
1243 UBYTE *src = msg->pixels;
1244 ULONG x_add = msg->modulo;
1245 UWORD height = msg->height;
1247 if (x_add == 0)
1248 x_add = bm->pitch;
1250 LOCK_HW
1252 intptr_t length = x_add * height;
1253 intptr_t phys = ((intptr_t)src) & 0xfffff000;
1254 length += (intptr_t)src - phys;
1256 length = (length + 4095) & ~4095;
1258 if (length <= 16*1024*1024)
1260 intptr_t virt = sd->ScratchArea + ((intptr_t)src - phys);
1261 done = TRUE;
1263 //D(bug("[GMA] PutImage(%d, %d, fmt=%d) with buffer at %p\n", msg->width, msg->height, msg->pixFmt,phys));
1265 if (sd->AttachedMemory != phys || sd->AttachedSize != length)
1267 G45_AttachCacheableMemory(sd, phys, sd->ScratchArea, length);
1268 sd->AttachedMemory = phys;
1269 sd->AttachedSize = length;
1272 writel(0, &sd->HardwareStatusPage[16]);
1274 uint32_t br00, br13, br14, br09, br11, br12;
1276 br00 = (2 << 29) | (0x43 << 22) | (4);
1277 br00 |= 3 << 20;
1279 br13 = bm->pitch | ROP3_S;
1280 br13 |= 3 << 24;
1282 br14 = (msg->width * bm->bpp) | (msg->height) << 16;
1283 br09 = bm->framebuffer + bm->pitch * msg->y + bm->bpp * msg->x;
1284 br11 = x_add;
1285 br12 = virt;
1287 START_RING(12);
1289 OUT_RING(br00);
1290 OUT_RING(br13);
1291 OUT_RING(br14);
1292 OUT_RING(br09);
1293 OUT_RING(br11);
1294 OUT_RING(br12);
1296 OUT_RING((4 << 23));
1297 OUT_RING(0);
1299 OUT_RING((0x21 << 23) | 1);
1300 OUT_RING(16 << 2);
1301 OUT_RING(1);
1302 OUT_RING(0);
1304 ADVANCE_RING();
1306 UNLOCK_HW
1308 /* Wait until HW is ready with blit and flush */
1309 while(readl(&sd->HardwareStatusPage[16]) == 0);
1312 if (!done)
1314 D(bug("[GMA] PutImage on unknown pixfmt %d\n",msg->pixFmt));
1316 if (bm->fbgfx)
1318 VideoData += (IPTR)sd->Card.Framebuffer;
1320 LOCK_HW
1321 DO_FLUSH();
1322 UNLOCK_HW
1325 switch(msg->pixFmt)
1327 case vHidd_StdPixFmt_Native:
1328 switch(bm->bpp)
1330 case 1:
1332 struct pHidd_BitMap_CopyMemBox8 __m = {
1333 sd->mid_CopyMemBox8,
1334 msg->pixels,
1337 (APTR)VideoData,
1338 msg->x,
1339 msg->y,
1340 msg->width,
1341 msg->height,
1342 msg->modulo,
1343 bm->pitch
1344 }, *m = &__m;
1346 OOP_DoMethod(o, (OOP_Msg)m);
1348 break;
1350 case 2:
1352 struct pHidd_BitMap_CopyMemBox16 __m = {
1353 sd->mid_CopyMemBox16,
1354 msg->pixels,
1357 (APTR)VideoData,
1358 msg->x,
1359 msg->y,
1360 msg->width,
1361 msg->height,
1362 msg->modulo,
1363 bm->pitch
1364 }, *m = &__m;
1366 OOP_DoMethod(o, (OOP_Msg)m);
1368 break;
1370 case 4:
1372 struct pHidd_BitMap_CopyMemBox32 __m = {
1373 sd->mid_CopyMemBox32,
1374 msg->pixels,
1377 (APTR)VideoData,
1378 msg->x,
1379 msg->y,
1380 msg->width,
1381 msg->height,
1382 msg->modulo,
1383 bm->pitch
1384 }, *m = &__m;
1386 OOP_DoMethod(o, (OOP_Msg)m);
1388 break;
1390 } /* switch(data->bytesperpix) */
1391 break;
1393 case vHidd_StdPixFmt_Native32:
1394 switch(bm->bpp)
1396 case 1:
1398 struct pHidd_BitMap_PutMem32Image8 __m = {
1399 sd->mid_PutMem32Image8,
1400 msg->pixels,
1401 (APTR)VideoData,
1402 msg->x,
1403 msg->y,
1404 msg->width,
1405 msg->height,
1406 msg->modulo,
1407 bm->pitch
1408 }, *m = &__m;
1409 OOP_DoMethod(o, (OOP_Msg)m);
1411 break;
1413 case 2:
1415 struct pHidd_BitMap_PutMem32Image16 __m = {
1416 sd->mid_PutMem32Image16,
1417 msg->pixels,
1418 (APTR)VideoData,
1419 msg->x,
1420 msg->y,
1421 msg->width,
1422 msg->height,
1423 msg->modulo,
1424 bm->pitch
1425 }, *m = &__m;
1426 OOP_DoMethod(o, (OOP_Msg)m);
1428 break;
1430 case 4:
1432 struct pHidd_BitMap_CopyMemBox32 __m = {
1433 sd->mid_CopyMemBox32,
1434 msg->pixels,
1437 (APTR)VideoData,
1438 msg->x,
1439 msg->y,
1440 msg->width,
1441 msg->height,
1442 msg->modulo,
1443 bm->pitch
1444 }, *m = &__m;
1446 OOP_DoMethod(o, (OOP_Msg)m);
1448 break;
1450 } /* switch(data->bytesperpix) */
1451 break;
1453 default:
1454 if (CanAccelerateBlits(sd->ProductID) && bm->bpp == 4)
1456 /* Get image width aligned to 4K page boundary */
1457 uint32_t line_width = (msg->width * bm->bpp + 4095) & ~4095;
1458 void *pages = AllocVecPooled(sd->MemPool, line_width * 5);
1460 if (pages)
1462 LOCK_HW
1464 /* Get two buffers in different GTT regions and _surely_ in different CPU cache lines */
1465 uint32_t *buffer_1 = (uint32_t *)(((intptr_t)pages + 4095) & ~4095);
1466 uint32_t *buffer_2 = &buffer_1[line_width / 4];
1467 uint32_t *buffer_3 = &buffer_2[line_width / 4];
1468 uint32_t *buffer_4 = &buffer_3[line_width / 4];
1470 uint32_t y;
1471 const uint32_t height = msg->height;
1472 uint8_t *src = msg->pixels;
1473 uint32_t x_add = msg->modulo;
1475 D(bug("[GMA] Unknown PutImage(%d, %d) with buffers at %p\n", msg->width, msg->height, buffer_1));
1477 uint32_t *buffer[4] = { buffer_1, buffer_2, buffer_3, buffer_4 };
1478 intptr_t virt[4] = { sd->ScratchArea, sd->ScratchArea + line_width,
1479 sd->ScratchArea + 2*line_width, sd->ScratchArea + 3*line_width };
1481 HIDDT_PixelFormat *srcpf, *dstpf;
1483 srcpf = (HIDDT_PixelFormat *)HIDD_Gfx_GetPixFmt(
1484 sd->GMAObject, msg->pixFmt);
1485 OOP_GetAttr(o, aHidd_BitMap_PixFmt, (APTR)&dstpf);
1487 /* Attach memory, if necessary */
1488 if (sd->AttachedMemory != (intptr_t)buffer_1 || sd->AttachedSize != 4 * line_width)
1490 G45_AttachCacheableMemory(sd, (intptr_t)buffer_1, sd->ScratchArea, 4 * line_width);
1491 sd->AttachedMemory = (intptr_t)buffer_1;
1492 sd->AttachedSize = 4 * line_width;
1495 /* Both buffers are not busy */
1496 writel(1, &sd->HardwareStatusPage[17]);
1497 writel(1, &sd->HardwareStatusPage[18]);
1498 writel(1, &sd->HardwareStatusPage[19]);
1499 writel(1, &sd->HardwareStatusPage[20]);
1501 for (y=0; y < height; y++)
1503 const uint8_t current = y & 3;
1504 uint32_t *dst = buffer[current];
1505 APTR _src = src;
1507 /* Wait until dst buffer is ready */
1508 while(readl(&sd->HardwareStatusPage[17 + current]) == 0);
1510 /* Convert! */
1511 HIDD_BM_ConvertPixels(o, &_src, srcpf,
1512 msg->modulo, (APTR *)&dst, dstpf,
1513 msg->modulo, msg->width, 1, NULL);
1515 /* Mark buffer as busy */
1516 writel(0, &sd->HardwareStatusPage[17 + current]);
1518 /* Prepare the Blit command */
1519 uint32_t br00, br13, br14, br09, br11, br12;
1521 br00 = (2 << 29) | (0x43 << 22) | (4);
1522 br00 |= 3 << 20;
1524 br13 = bm->pitch | ROP3_S;
1525 br13 |= 3 << 24;
1527 br14 = (msg->width * bm->bpp) | (1) << 16;
1528 br09 = bm->framebuffer + bm->pitch * (msg->y + y) + bm->bpp * msg->x;
1529 br11 = msg->width * bm->bpp;
1530 br12 = virt[current];
1532 START_RING(12);
1534 OUT_RING(br00);
1535 OUT_RING(br13);
1536 OUT_RING(br14);
1537 OUT_RING(br09);
1538 OUT_RING(br11);
1539 OUT_RING(br12);
1541 OUT_RING((4 << 23));
1542 OUT_RING(0);
1544 OUT_RING((0x21 << 23) | 1);
1545 OUT_RING((17 + current) << 2);
1546 OUT_RING(1);
1547 OUT_RING(0);
1549 ADVANCE_RING();
1552 * Right now the buffer is busy. The commands will flush buffer and set the proper flag (17+current) back to 1.
1553 * During that time it is fully safe to advance the loop and work on another buffer with CPU.
1555 src += x_add;
1558 /* Wait until both buffer are ready */
1559 while(readl(&sd->HardwareStatusPage[17]) == 0);
1560 while(readl(&sd->HardwareStatusPage[18]) == 0);
1561 while(readl(&sd->HardwareStatusPage[19]) == 0);
1562 while(readl(&sd->HardwareStatusPage[20]) == 0);
1564 UNLOCK_HW
1566 FreeVecPooled(sd->MemPool, pages);
1568 else
1569 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
1571 else
1572 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
1573 break;
1574 } /* switch(msg->pixFmt) */
1577 UNLOCK_BITMAP
1580 VOID METHOD(GMABM, Hidd_BitMap, PutImageLUT)
1582 GMABitMap_t *bm = OOP_INST_DATA(cl, o);
1584 LOCK_BITMAP
1586 if (bm->fbgfx)
1588 /* Get image width aligned to 4K page boundary */
1589 uint32_t line_width = (msg->width * bm->bpp + 4095) & ~4095;
1590 void *pages = AllocVecPooled(sd->MemPool, line_width * 3);
1591 HIDDT_Pixel *colmap = msg->pixlut->pixels;
1593 if (pages)
1595 LOCK_HW
1597 if (bm->bpp == 4 && CanAccelerateBlits(sd->ProductID))
1599 /* Get two buffers in different GTT regions and _surely_ in different CPU cache lines */
1600 uint32_t *buffer_1 = (uint32_t *)(((intptr_t)pages + 4095) & ~4095);
1601 uint32_t *buffer_2 = &buffer_1[line_width / 4];
1602 uint32_t y;
1603 const uint32_t height = msg->height;
1604 uint8_t *src = msg->pixels;
1605 uint32_t x_add = msg->modulo;
1607 D(bug("[GMA] PutImageLUT(%d, %d) with buffers at %p\n", msg->width, msg->height, buffer_1));
1609 uint32_t *buffer[2] = { buffer_1, buffer_2};
1610 intptr_t virt[2] = { sd->ScratchArea, sd->ScratchArea + line_width };
1612 /* Attach memory, if necessary */
1613 if (sd->AttachedMemory != (intptr_t)buffer_1 || sd->AttachedSize != 2 * line_width)
1615 G45_AttachCacheableMemory(sd, (intptr_t)buffer_1, sd->ScratchArea, 2 * line_width);
1616 sd->AttachedMemory = (intptr_t)buffer_1;
1617 sd->AttachedSize = 2 * line_width;
1620 /* Both buffers are not busy */
1621 writel(1, &sd->HardwareStatusPage[17]);
1622 writel(1, &sd->HardwareStatusPage[18]);
1624 for (y=0; y < height; y++)
1626 const uint8_t current = y & 1;
1627 uint32_t *dst = buffer[current];
1628 uint32_t x;
1629 uint8_t *line = (uint8_t *)src;
1630 const uint32_t width = msg->width;
1632 /* Wait until dst buffer is ready */
1633 while(readl(&sd->HardwareStatusPage[17 + current]) == 0);
1635 /* Do LUT lookup */
1636 for (x=0; x < width; x++)
1637 dst[x] = colmap[*line++];
1639 /* Mark buffer as busy */
1640 writel(0, &sd->HardwareStatusPage[17 + current]);
1642 /* Prepare the Blit command */
1643 uint32_t br00, br13, br14, br09, br11, br12;
1645 br00 = (2 << 29) | (0x43 << 22) | (4);
1646 if (bm->bpp == 4)
1647 br00 |= 3 << 20;
1649 br13 = bm->pitch | ROP3_S;
1650 if (bm->bpp == 4)
1651 br13 |= 3 << 24;
1652 else if (bm->bpp == 2)
1653 br13 |= 1 << 24;
1655 br14 = (msg->width * bm->bpp) | (1) << 16;
1656 br09 = bm->framebuffer + bm->pitch * (msg->y + y) + bm->bpp * msg->x;
1657 br11 = msg->width * bm->bpp;
1658 br12 = virt[current];
1660 START_RING(12);
1662 OUT_RING(br00);
1663 OUT_RING(br13);
1664 OUT_RING(br14);
1665 OUT_RING(br09);
1666 OUT_RING(br11);
1667 OUT_RING(br12);
1669 OUT_RING((4 << 23));
1670 OUT_RING(0);
1672 OUT_RING((0x21 << 23) | 1);
1673 OUT_RING((17 + current) << 2);
1674 OUT_RING(1);
1675 OUT_RING(0);
1677 ADVANCE_RING();
1680 * Right now the buffer is busy. The commands will flush buffer and set the proper flag (17+current) back to 1.
1681 * During that time it is fully safe to advance the loop and work on another buffer with CPU.
1683 src += x_add;
1686 /* Wait until both buffer are ready */
1687 while(readl(&sd->HardwareStatusPage[17]) == 0);
1688 while(readl(&sd->HardwareStatusPage[18]) == 0);
1690 else
1691 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
1693 UNLOCK_HW
1695 FreeVecPooled(sd->MemPool, pages);
1697 else
1698 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
1700 else
1701 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
1703 UNLOCK_BITMAP
1706 VOID METHOD(GMABM, Hidd_BitMap, GetImage)
1708 GMABitMap_t *bm = OOP_INST_DATA(cl, o);
1709 int done = 0;
1711 LOCK_BITMAP
1713 // bug("[GMA] GetImage(%d, %d, fmt %d)\n", msg->width, msg->height, msg->pixFmt);
1715 IPTR VideoData = bm->framebuffer;
1717 if (bm->fbgfx)
1719 LOCK_HW
1720 DO_FLUSH();
1721 UNLOCK_HW
1723 if (bm->bpp == 4 && CanAccelerateBlits(sd->ProductID)
1724 && (msg->pixFmt == vHidd_StdPixFmt_Native
1725 || msg->pixFmt == vHidd_StdPixFmt_Native32))
1727 UBYTE *dst = msg->pixels;
1728 ULONG x_add = msg->modulo;
1729 UWORD height = msg->height;
1731 if (x_add == 0)
1732 x_add = bm->bpp * msg->width;
1734 LOCK_HW
1736 intptr_t length = x_add * height;
1737 intptr_t phys = ((intptr_t)dst) & 0xfffff000;
1738 length += (intptr_t)dst - phys;
1740 length = (length + 4095) & ~4095;
1742 if (length <= 16*1024*1024)
1744 intptr_t virt = sd->ScratchArea + ((intptr_t)dst - phys);
1745 done = 1;
1747 D(bug("[GMA] GetImage(%d, %d) with buffer at %p\n", msg->width, msg->height, phys));
1749 if (sd->AttachedMemory != phys || sd->AttachedSize != length)
1751 G45_AttachCacheableMemory(sd, phys, sd->ScratchArea, length);
1752 sd->AttachedMemory = phys;
1753 sd->AttachedSize = length;
1756 writel(0, &sd->HardwareStatusPage[16]);
1758 uint32_t br00, br13, br14, br09, br11, br12;
1760 br00 = (2 << 29) | (0x43 << 22) | (4);
1761 if (bm->bpp == 4)
1762 br00 |= 3 << 20;
1764 br13 = x_add | ROP3_S;
1765 if (bm->bpp == 4)
1766 br13 |= 3 << 24;
1767 else if (bm->bpp == 2)
1768 br13 |= 1 << 24;
1770 br14 = (x_add) | (msg->height << 16);
1771 br09 = virt;
1772 br11 = bm->pitch;
1773 br12 = bm->framebuffer + bm->pitch * msg->y + bm->bpp * msg->x;
1775 D(bug("[GMA] %08x %08x %08x %08x %08x %08x\n", br00, br13, br14, br09, br11, br12));
1777 START_RING(12);
1779 OUT_RING(br00);
1780 OUT_RING(br13);
1781 OUT_RING(br14);
1782 OUT_RING(br09);
1783 OUT_RING(br11);
1784 OUT_RING(br12);
1786 OUT_RING((4 << 23));
1787 OUT_RING(0);
1789 OUT_RING((0x21 << 23) | 1);
1790 OUT_RING(16 << 2);
1791 OUT_RING(1);
1792 OUT_RING(0);
1794 ADVANCE_RING();
1797 UNLOCK_HW
1799 /* Wait until HW is ready with blit and flush */
1800 while(readl(&sd->HardwareStatusPage[16]) == 0);
1803 else
1804 VideoData += (IPTR)sd->Card.Framebuffer;
1807 if (!done)
1809 switch(msg->pixFmt)
1811 case vHidd_StdPixFmt_Native:
1812 switch(bm->bpp)
1814 case 1:
1816 struct pHidd_BitMap_CopyMemBox8 __m = {
1817 sd->mid_CopyMemBox8,
1818 (APTR)VideoData,
1819 msg->x,
1820 msg->y,
1821 msg->pixels,
1824 msg->width,
1825 msg->height,
1826 bm->pitch,
1827 msg->modulo
1828 }, *m = &__m;
1830 OOP_DoMethod(o, (OOP_Msg)m);
1832 break;
1834 case 2:
1836 struct pHidd_BitMap_CopyMemBox16 __m = {
1837 sd->mid_CopyMemBox16,
1838 (APTR)VideoData,
1839 msg->x,
1840 msg->y,
1841 msg->pixels,
1844 msg->width,
1845 msg->height,
1846 bm->pitch,
1847 msg->modulo
1848 }, *m = &__m;
1850 OOP_DoMethod(o, (OOP_Msg)m);
1852 break;
1854 case 4:
1855 // D(bug("[GMA] Native GetImage(%d, %d)\n", msg->width, msg->height));
1857 struct pHidd_BitMap_CopyMemBox32 __m = {
1858 sd->mid_CopyMemBox32,
1859 (APTR)VideoData,
1860 msg->x,
1861 msg->y,
1862 msg->pixels,
1865 msg->width,
1866 msg->height,
1867 bm->pitch,
1868 msg->modulo
1869 }, *m = &__m;
1871 OOP_DoMethod(o, (OOP_Msg)m);
1873 break;
1875 } /* switch(data->bytesperpix) */
1876 break;
1878 case vHidd_StdPixFmt_Native32:
1879 switch(bm->bpp)
1881 case 1:
1883 struct pHidd_BitMap_GetMem32Image8 __m = {
1884 sd->mid_GetMem32Image8,
1885 (APTR)VideoData,
1886 msg->x,
1887 msg->y,
1888 msg->pixels,
1889 msg->width,
1890 msg->height,
1891 bm->pitch,
1892 msg->modulo
1893 }, *m = &__m;
1895 OOP_DoMethod(o, (OOP_Msg)m);
1897 break;
1899 case 2:
1901 struct pHidd_BitMap_GetMem32Image16 __m = {
1902 sd->mid_GetMem32Image16,
1903 (APTR)VideoData,
1904 msg->x,
1905 msg->y,
1906 msg->pixels,
1907 msg->width,
1908 msg->height,
1909 bm->pitch,
1910 msg->modulo
1911 }, *m = &__m;
1913 OOP_DoMethod(o, (OOP_Msg)m);
1915 break;
1917 case 4:
1919 struct pHidd_BitMap_CopyMemBox32 __m = {
1920 sd->mid_CopyMemBox32,
1921 (APTR)VideoData,
1922 msg->x,
1923 msg->y,
1924 msg->pixels,
1927 msg->width,
1928 msg->height,
1929 bm->pitch,
1930 msg->modulo
1931 }, *m = &__m;
1933 OOP_DoMethod(o, (OOP_Msg)m);
1935 break;
1937 } /* switch(data->bytesperpix) */
1938 break;
1940 default:
1941 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
1942 break;
1944 } /* switch(msg->pixFmt) */
1948 UNLOCK_BITMAP
1953 VOID METHOD(GMABM, Hidd_BitMap, PutTemplate)
1955 GMABitMap_t *bm = OOP_INST_DATA(cl, o);
1957 D(bug("[GMA] NO-ACCEL: BitMap::PutTemplate\n"));
1959 LOCK_BITMAP
1961 IPTR VideoData = bm->framebuffer;
1963 if (bm->fbgfx)
1965 VideoData += (IPTR)sd->Card.Framebuffer;
1966 LOCK_HW
1967 DO_FLUSH();
1968 UNLOCK_HW
1970 // if (sd->Card.Busy)
1971 // {
1972 // LOCK_HW
1973 //#warning TODO: NVSync(sd)
1974 // RADEONWaitForIdleMMIO(sd);
1975 // DO_FLUSH();
1976 //UNLOCK_HW
1977 // }
1981 switch(bm->bpp)
1983 case 1:
1985 struct pHidd_BitMap_PutMemTemplate8 __m = {
1986 sd->mid_PutMemTemplate8,
1987 msg->gc,
1988 msg->masktemplate,
1989 msg->modulo,
1990 msg->srcx,
1991 (APTR)VideoData,
1992 bm->pitch,
1993 msg->x,
1994 msg->y,
1995 msg->width,
1996 msg->height,
1997 msg->inverttemplate
1998 }, *m = &__m;
2000 OOP_DoMethod(o, (OOP_Msg)m);
2002 break;
2004 case 2:
2006 struct pHidd_BitMap_PutMemTemplate16 __m = {
2007 sd->mid_PutMemTemplate16,
2008 msg->gc,
2009 msg->masktemplate,
2010 msg->modulo,
2011 msg->srcx,
2012 (APTR)VideoData,
2013 bm->pitch,
2014 msg->x,
2015 msg->y,
2016 msg->width,
2017 msg->height,
2018 msg->inverttemplate
2019 }, *m = &__m;
2021 OOP_DoMethod(o, (OOP_Msg)m);
2023 break;
2025 case 4:
2027 struct pHidd_BitMap_PutMemTemplate32 __m = {
2028 sd->mid_PutMemTemplate32,
2029 msg->gc,
2030 msg->masktemplate,
2031 msg->modulo,
2032 msg->srcx,
2033 (APTR)VideoData,
2034 bm->pitch,
2035 msg->x,
2036 msg->y,
2037 msg->width,
2038 msg->height,
2039 msg->inverttemplate
2040 }, *m = &__m;
2042 OOP_DoMethod(o, (OOP_Msg)m);
2044 break;
2045 } /* switch(bm->bpp) */
2047 UNLOCK_BITMAP
2050 VOID METHOD(GMABM, Hidd_BitMap, PutPattern)
2052 GMABitMap_t *bm = OOP_INST_DATA(cl, o);
2054 D(bug("[GMA] NO-ACCEL: BitMap::PutPattern\n"));
2056 LOCK_BITMAP
2058 IPTR VideoData = bm->framebuffer;
2060 if (bm->fbgfx)
2062 VideoData += (IPTR)sd->Card.Framebuffer;
2063 LOCK_HW
2064 DO_FLUSH();
2065 UNLOCK_HW
2067 // if (sd->Card.Busy)
2068 // {
2069 // LOCK_HW
2070 //#warning TODO: NVSync(sd)
2071 // RADEONWaitForIdleMMIO(sd);
2072 //DO_FLUSH();
2073 // UNLOCK_HW
2074 // }
2078 switch(bm->bpp)
2080 case 1:
2082 struct pHidd_BitMap_PutMemPattern8 __m = {
2083 sd->mid_PutMemPattern8,
2084 msg->gc,
2085 msg->pattern,
2086 msg->patternsrcx,
2087 msg->patternsrcy,
2088 msg->patternheight,
2089 msg->patterndepth,
2090 msg->patternlut,
2091 msg->invertpattern,
2092 msg->mask,
2093 msg->maskmodulo,
2094 msg->masksrcx,
2095 (APTR)VideoData,
2096 bm->pitch,
2097 msg->x,
2098 msg->y,
2099 msg->width,
2100 msg->height
2101 }, *m = &__m;
2103 OOP_DoMethod(o, (OOP_Msg)m);
2105 break;
2107 case 2:
2109 struct pHidd_BitMap_PutMemPattern16 __m = {
2110 sd->mid_PutMemPattern16,
2111 msg->gc,
2112 msg->pattern,
2113 msg->patternsrcx,
2114 msg->patternsrcy,
2115 msg->patternheight,
2116 msg->patterndepth,
2117 msg->patternlut,
2118 msg->invertpattern,
2119 msg->mask,
2120 msg->maskmodulo,
2121 msg->masksrcx,
2122 (APTR)VideoData,
2123 bm->pitch,
2124 msg->x,
2125 msg->y,
2126 msg->width,
2127 msg->height
2128 }, *m = &__m;
2130 OOP_DoMethod(o, (OOP_Msg)m);
2132 break;
2134 case 4:
2136 struct pHidd_BitMap_PutMemPattern32 __m = {
2137 sd->mid_PutMemPattern32,
2138 msg->gc,
2139 msg->pattern,
2140 msg->patternsrcx,
2141 msg->patternsrcy,
2142 msg->patternheight,
2143 msg->patterndepth,
2144 msg->patternlut,
2145 msg->invertpattern,
2146 msg->mask,
2147 msg->maskmodulo,
2148 msg->masksrcx,
2149 (APTR)VideoData,
2150 bm->pitch,
2151 msg->x,
2152 msg->y,
2153 msg->width,
2154 msg->height
2155 }, *m = &__m;
2157 OOP_DoMethod(o, (OOP_Msg)m);
2159 break;
2160 } /* switch(bm->bpp) */
2162 UNLOCK_BITMAP
2165 VOID METHOD(GMABM, Hidd_BitMap, UpdateRect)
2167 GMABitMap_t * bmdata = OOP_INST_DATA(cl, o);
2168 D(bug("[GMA]BitMap::UpdateRect %d,%d-%d,%d o=%p\n",msg->x,msg->y,msg->width,msg->height,o));
2169 if (bmdata->displayable)
2171 struct pHidd_Compositing_BitMapRectChanged brcmsg =
2173 mID : SD(cl)->mid_BitMapRectChanged,
2174 bm : o,
2175 x : msg->x,
2176 y : msg->y,
2177 width : msg->width,
2178 height : msg->height
2180 OOP_DoMethod(bmdata->compositing, (OOP_Msg)&brcmsg);
2185 static const struct OOP_MethodDescr GMABM_Root_descr[] =
2187 {(OOP_MethodFunc)GMABM__Root__New , moRoot_New },
2188 {(OOP_MethodFunc)GMABM__Root__Dispose, moRoot_Dispose},
2189 {(OOP_MethodFunc)GMABM__Root__Get , moRoot_Get },
2190 {(OOP_MethodFunc)GMABM__Root__Set , moRoot_Set },
2191 {NULL , 0 }
2193 #define NUM_GMABM_Root_METHODS 4
2195 static const struct OOP_MethodDescr GMABM_Hidd_BitMap_descr[] =
2197 {(OOP_MethodFunc)GMABM__Hidd_BitMap__PutPixel , moHidd_BitMap_PutPixel },
2198 {(OOP_MethodFunc)GMABM__Hidd_BitMap__GetPixel , moHidd_BitMap_GetPixel },
2199 {(OOP_MethodFunc)GMABM__Hidd_BitMap__DrawPixel , moHidd_BitMap_DrawPixel },
2200 {(OOP_MethodFunc)GMABM__Hidd_BitMap__DrawLine , moHidd_BitMap_DrawLine },
2201 {(OOP_MethodFunc)GMABM__Hidd_BitMap__DrawEllipse , moHidd_BitMap_DrawEllipse },
2202 {(OOP_MethodFunc)GMABM__Hidd_BitMap__FillRect , moHidd_BitMap_FillRect },
2203 {(OOP_MethodFunc)GMABM__Hidd_BitMap__BytesPerLine , moHidd_BitMap_BytesPerLine },
2204 {(OOP_MethodFunc)GMABM__Hidd_BitMap__ObtainDirectAccess , moHidd_BitMap_ObtainDirectAccess },
2205 {(OOP_MethodFunc)GMABM__Hidd_BitMap__ReleaseDirectAccess, moHidd_BitMap_ReleaseDirectAccess},
2206 {(OOP_MethodFunc)GMABM__Hidd_BitMap__PutImage , moHidd_BitMap_PutImage },
2207 {(OOP_MethodFunc)GMABM__Hidd_BitMap__PutImageLUT , moHidd_BitMap_PutImageLUT },
2208 {(OOP_MethodFunc)GMABM__Hidd_BitMap__PutAlphaImage , moHidd_BitMap_PutAlphaImage },
2209 {(OOP_MethodFunc)GMABM__Hidd_BitMap__GetImage , moHidd_BitMap_GetImage },
2210 {(OOP_MethodFunc)GMABM__Hidd_BitMap__PutTemplate , moHidd_BitMap_PutTemplate },
2211 {(OOP_MethodFunc)GMABM__Hidd_BitMap__PutPattern , moHidd_BitMap_PutPattern },
2212 {(OOP_MethodFunc)GMABM__Hidd_BitMap__UpdateRect , moHidd_BitMap_UpdateRect },
2213 {NULL , 0 }
2215 #define NUM_GMABM_Hidd_BitMap_METHODS 16
2217 const struct OOP_InterfaceDescr GMABM_ifdescr[] =
2219 {GMABM_Root_descr , IID_Root , NUM_GMABM_Root_METHODS },
2220 {GMABM_Hidd_BitMap_descr, IID_Hidd_BitMap, NUM_GMABM_Hidd_BitMap_METHODS},
2221 {NULL , NULL , 0 }