fix __AROS_SETVECADDR invocations.
[AROS.git] / workbench / hidds / nouveau / nouveau_accel.c
blob7ba804489b7572881d4ebbbdf7e7b043d41e4f05
1 /*
2 * Copyright 2009 Nouveau Project
3 * Copyright (C) 2010-2013, The AROS Development Team. All rights reserved.
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
20 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
24 #include "nouveau_intern.h"
25 #include "nouveau_class.h"
26 #include <proto/oop.h>
27 #include <proto/exec.h>
29 #undef HiddBitMapAttrBase
30 #define HiddBitMapAttrBase (SD(cl)->bitMapAttrBase)
32 static inline int do_alpha(int a, int v)
34 int tmp = a*v;
35 return ((tmp << 8) + tmp + 32768) >> 16;
38 /* NOTE: Assumes lock on bitmap is already made */
39 /* NOTE: Assumes buffer is mapped */
40 VOID HIDDNouveauBitMapPutAlphaImage32(struct HIDDNouveauBitMapData * bmdata,
41 APTR srcbuff, ULONG srcpitch, LONG destX, LONG destY, LONG width, LONG height)
43 LONG x,y;
45 for(y = 0; y < height; y++)
47 /* Calculate line start addresses */
48 IPTR srcaddr = (srcpitch * y) + (IPTR)srcbuff;
49 IPTR destaddr = (destX * 4) + (bmdata->pitch * (destY + y)) + (IPTR)bmdata->bo->map;
51 for (x = 0; x < width; x++)
53 ULONG destpix;
54 ULONG srcpix;
55 LONG src_red, src_green, src_blue, src_alpha;
56 LONG dst_red, dst_green, dst_blue;
58 /* Read RGBA pixel from input array */
59 srcpix = *(ULONG *)srcaddr;
60 #if AROS_BIG_ENDIAN
61 src_red = (srcpix & 0x00FF0000) >> 16;
62 src_green = (srcpix & 0x0000FF00) >> 8;
63 src_blue = (srcpix & 0x000000FF);
64 src_alpha = (srcpix & 0xFF000000) >> 24;
65 #else
66 src_red = (srcpix & 0x0000FF00) >> 8;
67 src_green = (srcpix & 0x00FF0000) >> 16;
68 src_blue = (srcpix & 0xFF000000) >> 24;
69 src_alpha = (srcpix & 0x000000FF);
70 #endif
73 * If alpha=0, do not change the destination pixel at all.
74 * This saves us unnecessary reads and writes to VRAM.
76 if (src_alpha != 0)
79 * Full opacity. Do not read the destination pixel, as
80 * it's value does not matter anyway.
82 if (src_alpha == 0xff)
84 dst_red = src_red;
85 dst_green = src_green;
86 dst_blue = src_blue;
88 else
91 * Alpha blending with source and destination pixels.
92 * Get destination.
94 destpix = readl(destaddr);
96 dst_red = (destpix & 0x00FF0000) >> 16;
97 dst_green = (destpix & 0x0000FF00) >> 8;
98 dst_blue = (destpix & 0x000000FF);
100 dst_red += do_alpha(src_alpha, src_red - dst_red);
101 dst_green += do_alpha(src_alpha, src_green - dst_green);
102 dst_blue += do_alpha(src_alpha, src_blue - dst_blue);
105 destpix = (dst_red << 16) + (dst_green << 8) + (dst_blue);
107 /* Store the new pixel */
108 writel(destpix, destaddr);
111 /* Advance pointers */
112 srcaddr += 4;
113 destaddr += 4;
118 /* NOTE: Assumes lock on bitmap is already made */
119 /* NOTE: Assumes buffer is mapped */
120 VOID HIDDNouveauBitMapPutAlphaImage16(struct HIDDNouveauBitMapData * bmdata,
121 APTR srcbuff, ULONG srcpitch, LONG destX, LONG destY, LONG width, LONG height)
123 LONG x,y;
125 for(y = 0; y < height; y++)
127 /* Calculate line start addresses */
128 IPTR srcaddr = (srcpitch * y) + (IPTR)srcbuff;
129 IPTR destaddr = (destX * 2) + (bmdata->pitch * (destY + y)) + (IPTR)bmdata->bo->map;
131 for (x = 0; x < width; x++)
133 UWORD destpix;
134 ULONG srcpix;
135 LONG src_red, src_green, src_blue, src_alpha;
136 LONG dst_red, dst_green, dst_blue;
138 /* Read RGBA pixel from input array */
139 srcpix = *(ULONG *)srcaddr;
140 #if AROS_BIG_ENDIAN
141 src_red = (srcpix & 0x00FF0000) >> 16;
142 src_green = (srcpix & 0x0000FF00) >> 8;
143 src_blue = (srcpix & 0x000000FF);
144 src_alpha = (srcpix & 0xFF000000) >> 24;
145 #else
146 src_red = (srcpix & 0x0000FF00) >> 8;
147 src_green = (srcpix & 0x00FF0000) >> 16;
148 src_blue = (srcpix & 0xFF000000) >> 24;
149 src_alpha = (srcpix & 0x000000FF);
150 #endif
153 * If alpha=0, do not change the destination pixel at all.
154 * This saves us unnecessary reads and writes to VRAM.
156 if (src_alpha != 0)
159 * Full opacity. Do not read the destination pixel, as
160 * it's value does not matter anyway.
162 if (src_alpha == 0xff)
164 dst_red = src_red;
165 dst_green = src_green;
166 dst_blue = src_blue;
168 else
171 * Alpha blending with source and destination pixels.
172 * Get destination.
175 destpix = readw(destaddr);
177 dst_red = (destpix & 0x0000F800) >> 8;
178 dst_green = (destpix & 0x000007e0) >> 3;
179 dst_blue = (destpix & 0x0000001f) << 3;
181 dst_red += do_alpha(src_alpha, src_red - dst_red);
182 dst_green += do_alpha(src_alpha, src_green - dst_green);
183 dst_blue += do_alpha(src_alpha, src_blue - dst_blue);
186 destpix = (((dst_red << 8) & 0xf800) | ((dst_green << 3) & 0x07e0) | ((dst_blue >> 3) & 0x001f));
188 writew(destpix, destaddr);
191 /* Advance pointers */
192 srcaddr += 4;
193 destaddr += 2;
198 /* NOTE: Assumes lock on bitmap is already made */
199 /* NOTE: Assumes buffer is mapped */
200 VOID HIDDNouveauBitMapPutAlphaTemplate32(struct HIDDNouveauBitMapData * bmdata,
201 OOP_Object * gc, OOP_Object * bm, BOOL invertalpha,
202 UBYTE * srcalpha, ULONG srcpitch, LONG destX, LONG destY, LONG width, LONG height)
204 WORD x, y;
205 UBYTE *pixarray = srcalpha;
206 HIDDT_Color color;
207 LONG fg_red, fg_green, fg_blue;
208 LONG bg_red = 0, bg_green = 0, bg_blue = 0;
209 WORD type = 0;
211 if (width <= 0 || height <= 0)
212 return;
214 HIDD_BM_UnmapPixel(bm, GC_FG(gc), &color);
216 fg_red = color.red >> 8;
217 fg_green = color.green >> 8;
218 fg_blue = color.blue >> 8;
220 if (GC_COLEXP(gc) == vHidd_GC_ColExp_Transparent)
222 type = 0;
224 else if (GC_DRMD(gc) == vHidd_GC_DrawMode_Invert)
226 type = 2;
228 else
230 type = 4;
232 HIDD_BM_UnmapPixel(bm, GC_BG(gc), &color);
233 bg_red = color.red >> 8;
234 bg_green = color.green >> 8;
235 bg_blue = color.blue >> 8;
238 if (invertalpha) type++;
241 for(y = 0; y < height; y++)
243 IPTR destaddr = (destX * 4) + ((destY + y) * bmdata->pitch) + (IPTR)bmdata->bo->map;
245 switch(type)
247 case 0: /* JAM1 */
248 for(x = 0; x < width; x++)
250 ULONG destpix;
251 LONG dst_red, dst_green, dst_blue, alpha;
253 alpha = *pixarray++;
256 if (alpha != 0) /* If alpha=0, do not change the destination pixel at all. */
258 if (alpha == 0xff) /* Full opacity. Do not read the destination pixel. */
260 dst_red = fg_red;
261 dst_green = fg_green;
262 dst_blue = fg_blue;
264 else
266 destpix = readl(destaddr);
268 dst_red = (destpix & 0x00FF0000) >> 16;
269 dst_green = (destpix & 0x0000FF00) >> 8;
270 dst_blue = (destpix & 0x000000FF);
272 dst_red += do_alpha(alpha, fg_red - dst_red);
273 dst_green += do_alpha(alpha, fg_green - dst_green);
274 dst_blue += do_alpha(alpha, fg_blue - dst_blue);
277 destpix = (dst_red << 16) + (dst_green << 8) + (dst_blue);
278 writel(destpix, destaddr);
281 destaddr += 4;
283 } /* for(x = 0; x < msg->width; x++) */
284 break;
286 case 1: /* JAM1 | INVERSVID */
287 for(x = 0; x < width; x++)
289 ULONG destpix;
290 LONG dst_red, dst_green, dst_blue, alpha;
292 alpha = (*pixarray++) ^ 255;
295 if (alpha != 0) /* If alpha=0, do not change the destination pixel at all. */
297 if (alpha == 0xff) /* Full opacity. Do not read the destination pixel. */
299 dst_red = fg_red;
300 dst_green = fg_green;
301 dst_blue = fg_blue;
303 else
305 destpix = readl(destaddr);
307 dst_red = (destpix & 0x00FF0000) >> 16;
308 dst_green = (destpix & 0x0000FF00) >> 8;
309 dst_blue = (destpix & 0x000000FF);
311 dst_red += do_alpha(alpha, fg_red - dst_red);
312 dst_green += do_alpha(alpha, fg_green - dst_green);
313 dst_blue += do_alpha(alpha, fg_blue - dst_blue);
316 destpix = (dst_red << 16) + (dst_green << 8) + (dst_blue);
317 writel(destpix, destaddr);
320 destaddr += 4;
322 } /* for(x = 0; x < width; x++) */
323 break;
325 case 2: /* COMPLEMENT */
326 for(x = 0; x < width; x++)
328 ULONG destpix;
329 UBYTE alpha;
331 alpha = *pixarray++;
334 if (alpha >= 0x80)
336 destpix = readl(destaddr);
337 destpix = ~destpix;
338 writel(destpix, destaddr);
341 destaddr += 4;
343 } /* for(x = 0; x < width; x++) */
344 break;
346 case 3: /* COMPLEMENT | INVERSVID*/
347 for(x = 0; x < width; x++)
349 ULONG destpix;
350 UBYTE alpha;
352 alpha = *pixarray++;
355 if (alpha < 0x80)
357 destpix = readl(destaddr);
358 destpix = ~destpix;
359 writel(destpix, destaddr);
362 destaddr += 4;
364 } /* for(x = 0; x < width; x++) */
365 break;
367 case 4: /* JAM2 */
368 for(x = 0; x < width; x++)
370 ULONG destpix;
371 LONG dst_red, dst_green, dst_blue, alpha;
373 alpha = *pixarray++;
376 dst_red = bg_red + ((fg_red - bg_red) * alpha) / 256;
377 dst_green = bg_green + ((fg_green - bg_green) * alpha) / 256;
378 dst_blue = bg_blue + ((fg_blue - bg_blue) * alpha) / 256;
380 destpix = (dst_red << 16) + (dst_green << 8) + (dst_blue);
382 writel(destpix, destaddr);
383 destaddr += 4;
385 } /* for(x = 0; x < width; x++) */
386 break;
388 case 5: /* JAM2 | INVERSVID */
389 for(x = 0; x < width; x++)
391 ULONG destpix;
392 LONG dst_red, dst_green, dst_blue, alpha;
394 alpha = (*pixarray++) ^ 255;
397 dst_red = bg_red + ((fg_red - bg_red) * alpha) / 256;
398 dst_green = bg_green + ((fg_green - bg_green) * alpha) / 256;
399 dst_blue = bg_blue + ((fg_blue - bg_blue) * alpha) / 256;
401 destpix = (dst_red << 16) + (dst_green << 8) + (dst_blue);
402 writel(destpix, destaddr);
404 destaddr += 4;
406 } /* for(x = 0; x < width; x++) */
407 break;
409 } /* switch(type) */
411 pixarray += srcpitch - width;
413 } /* for(y = 0; y < height; y++) */
416 /* NOTE: Assumes lock on bitmap is already made */
417 /* NOTE: Assumes buffer is mapped */
418 VOID HIDDNouveauBitMapPutAlphaTemplate16(struct HIDDNouveauBitMapData * bmdata,
419 OOP_Object * gc, OOP_Object * bm, BOOL invertalpha,
420 UBYTE * srcalpha, ULONG srcpitch, LONG destX, LONG destY, LONG width, LONG height)
422 WORD x, y;
423 UBYTE *pixarray = srcalpha;
424 HIDDT_Color color;
425 LONG fg_red, fg_green, fg_blue;
426 LONG bg_red = 0, bg_green = 0, bg_blue = 0;
427 WORD type = 0;
429 if (width <= 0 || height <= 0)
430 return;
432 HIDD_BM_UnmapPixel(bm, GC_FG(gc), &color);
434 fg_red = color.red >> 8;
435 fg_green = color.green >> 8;
436 fg_blue = color.blue >> 8;
438 if (GC_COLEXP(gc) == vHidd_GC_ColExp_Transparent)
440 type = 0;
442 else if (GC_DRMD(gc) == vHidd_GC_DrawMode_Invert)
444 type = 2;
446 else
448 type = 4;
450 HIDD_BM_UnmapPixel(bm, GC_BG(gc), &color);
451 bg_red = color.red >> 8;
452 bg_green = color.green >> 8;
453 bg_blue = color.blue >> 8;
456 if (invertalpha) type++;
459 for(y = 0; y < height; y++)
461 IPTR destaddr = (destX * 2) + ((destY + y) * bmdata->pitch) + (IPTR)bmdata->bo->map;
463 switch(type)
465 case 0: /* JAM1 */
466 for(x = 0; x < width; x++)
468 UWORD destpix;
469 LONG dst_red, dst_green, dst_blue, alpha;
471 alpha = *pixarray++;
474 if (alpha != 0) /* If alpha=0, do not change the destination pixel at all. */
476 if (alpha == 0xff) /* Full opacity. Do not read the destination pixel. */
478 dst_red = fg_red;
479 dst_green = fg_green;
480 dst_blue = fg_blue;
482 else
484 destpix = readw(destaddr);
486 dst_red = (destpix & 0x0000F800) >> 8;
487 dst_green = (destpix & 0x000007e0) >> 3;
488 dst_blue = (destpix & 0x0000001f) << 3;
490 dst_red += do_alpha(alpha, fg_red - dst_red);
491 dst_green += do_alpha(alpha, fg_green - dst_green);
492 dst_blue += do_alpha(alpha, fg_blue - dst_blue);
495 destpix = (((dst_red << 8) & 0xf800) | ((dst_green << 3) & 0x07e0) | ((dst_blue >> 3) & 0x001f));
496 writew(destpix, destaddr);
499 destaddr += 2;
501 } /* for(x = 0; x < msg->width; x++) */
502 break;
504 case 1: /* JAM1 | INVERSVID */
505 for(x = 0; x < width; x++)
507 UWORD destpix;
508 LONG dst_red, dst_green, dst_blue, alpha;
510 alpha = (*pixarray++) ^ 255;
513 if (alpha != 0) /* If alpha=0, do not change the destination pixel at all. */
515 if (alpha == 0xff) /* Full opacity. Do not read the destination pixel. */
517 dst_red = fg_red;
518 dst_green = fg_green;
519 dst_blue = fg_blue;
521 else
523 destpix = readw(destaddr);
525 dst_red = (destpix & 0x0000F800) >> 8;
526 dst_green = (destpix & 0x000007e0) >> 3;
527 dst_blue = (destpix & 0x0000001f) << 3;
529 dst_red += do_alpha(alpha, fg_red - dst_red);
530 dst_green += do_alpha(alpha, fg_green - dst_green);
531 dst_blue += do_alpha(alpha, fg_blue - dst_blue);
534 destpix = (((dst_red << 8) & 0xf800) | ((dst_green << 3) & 0x07e0) | ((dst_blue >> 3) & 0x001f));
535 writew(destpix, destaddr);
538 destaddr += 2;
540 } /* for(x = 0; x < width; x++) */
541 break;
543 case 2: /* COMPLEMENT */
544 for(x = 0; x < width; x++)
546 UWORD destpix;
547 UBYTE alpha;
549 alpha = *pixarray++;
552 if (alpha >= 0x80)
554 destpix = readw(destaddr);
555 destpix = ~destpix;
556 writew(destpix, destaddr);
559 destaddr += 2;
561 } /* for(x = 0; x < width; x++) */
562 break;
564 case 3: /* COMPLEMENT | INVERSVID*/
565 for(x = 0; x < width; x++)
567 UWORD destpix;
568 UBYTE alpha;
570 alpha = *pixarray++;
573 if (alpha < 0x80)
575 destpix = readw(destaddr);
576 destpix = ~destpix;
577 writew(destpix, destaddr);
580 destaddr += 2;
582 } /* for(x = 0; x < width; x++) */
583 break;
585 case 4: /* JAM2 */
586 for(x = 0; x < width; x++)
588 UWORD destpix;
589 LONG dst_red, dst_green, dst_blue, alpha;
591 alpha = *pixarray++;
594 dst_red = bg_red + ((fg_red - bg_red) * alpha) / 256;
595 dst_green = bg_green + ((fg_green - bg_green) * alpha) / 256;
596 dst_blue = bg_blue + ((fg_blue - bg_blue) * alpha) / 256;
598 destpix = (((dst_red << 8) & 0xf800) | ((dst_green << 3) & 0x07e0) | ((dst_blue >> 3) & 0x001f));
599 writew(destpix, destaddr);
601 destaddr += 2;
603 } /* for(x = 0; x < width; x++) */
604 break;
606 case 5: /* JAM2 | INVERSVID */
607 for(x = 0; x < width; x++)
609 UWORD destpix;
610 LONG dst_red, dst_green, dst_blue, alpha;
612 alpha = (*pixarray++) ^ 255;
615 dst_red = bg_red + ((fg_red - bg_red) * alpha) / 256;
616 dst_green = bg_green + ((fg_green - bg_green) * alpha) / 256;
617 dst_blue = bg_blue + ((fg_blue - bg_blue) * alpha) / 256;
619 destpix = (((dst_red << 8) & 0xf800) | ((dst_green << 3) & 0x07e0) | ((dst_blue >> 3) & 0x001f));
620 writew(destpix, destaddr);
622 destaddr += 2;
624 } /* for(x = 0; x < width; x++) */
625 break;
627 } /* switch(type) */
629 pixarray += srcpitch - width;
631 } /* for(y = 0; y < height; y++) */
634 /* Assumes input and output buffers are lock-protected */
635 /* Takes pixels from RAM buffer, converts them and puts them into destination
636 buffer. The destination buffer can be in VRAM or GART or RAM */
637 BOOL HiddNouveauWriteFromRAM(
638 APTR src, ULONG srcPitch, HIDDT_StdPixFmt srcPixFmt,
639 APTR dst, ULONG dstPitch,
640 ULONG width, ULONG height,
641 OOP_Class *cl, OOP_Object *o)
643 struct HIDDNouveauBitMapData * bmdata = OOP_INST_DATA(cl, o);
644 UBYTE dstBpp = bmdata->bytesperpixel;
646 switch(srcPixFmt)
648 case vHidd_StdPixFmt_Native:
649 switch(dstBpp)
651 case 1:
652 /* Not supported */
653 break;
655 case 2:
657 struct pHidd_BitMap_CopyMemBox16 __m =
659 SD(cl)->mid_CopyMemBox16, src, 0, 0, dst,
660 0, 0, width, height, srcPitch, dstPitch
661 }, *m = &__m;
662 OOP_DoMethod(o, (OOP_Msg)m);
664 break;
666 case 4:
668 struct pHidd_BitMap_CopyMemBox32 __m =
670 SD(cl)->mid_CopyMemBox32, src, 0, 0, dst,
671 0, 0, width, height, srcPitch, dstPitch
672 }, *m = &__m;
673 OOP_DoMethod(o, (OOP_Msg)m);
675 break;
677 } /* switch(data->bytesperpixel) */
678 break;
680 case vHidd_StdPixFmt_Native32:
681 switch(dstBpp)
683 case 1:
684 /* Not supported */
685 break;
687 case 2:
689 struct pHidd_BitMap_PutMem32Image16 __m =
691 SD(cl)->mid_PutMem32Image16, src, dst,
692 0, 0, width, height, srcPitch, dstPitch
693 }, *m = &__m;
694 OOP_DoMethod(o, (OOP_Msg)m);
696 break;
698 case 4:
700 struct pHidd_BitMap_CopyMemBox32 __m =
702 SD(cl)->mid_CopyMemBox32, src, 0, 0, dst,
703 0, 0, width, height, srcPitch, dstPitch
704 }, *m = &__m;
705 OOP_DoMethod(o, (OOP_Msg)m);
707 break;
709 } /* switch(data->bytesperpixel) */
710 break;
711 default:
713 /* Use ConvertPixels to convert that data to destination format */
714 APTR csrc = src;
715 APTR * psrc = &csrc;
716 APTR cdst = dst;
717 APTR * pdst = &cdst;
718 OOP_Object * dstPF = NULL;
719 OOP_Object * srcPF = NULL;
720 OOP_Object * gfxHidd = NULL;
721 struct pHidd_Gfx_GetPixFmt __gpf =
723 SD(cl)->mid_GetPixFmt, srcPixFmt
724 }, *gpf = &__gpf;
726 OOP_GetAttr(o, aHidd_BitMap_PixFmt, (APTR)&dstPF);
727 OOP_GetAttr(o, aHidd_BitMap_GfxHidd, (APTR)&gfxHidd);
728 srcPF = (OOP_Object *)OOP_DoMethod(gfxHidd, (OOP_Msg)gpf);
731 struct pHidd_BitMap_ConvertPixels __m =
733 SD(cl)->mid_ConvertPixels,
734 psrc, (HIDDT_PixelFormat *)srcPF, srcPitch,
735 pdst, (HIDDT_PixelFormat *)dstPF, dstPitch,
736 width, height, NULL
737 }, *m = &__m;
738 OOP_DoMethod(o, (OOP_Msg)m);
742 break;
745 return TRUE;
748 /* Assumes input and output buffers are lock-protected */
749 /* Takes pixels from source buffer, converts them and puts them into RAM
750 buffer. The source buffer can be in VRAM or GART or RAM */
751 BOOL HiddNouveauReadIntoRAM(
752 APTR src, ULONG srcPitch,
753 APTR dst, ULONG dstPitch, HIDDT_StdPixFmt dstPixFmt,
754 ULONG width, ULONG height,
755 OOP_Class *cl, OOP_Object *o)
757 struct HIDDNouveauBitMapData * bmdata = OOP_INST_DATA(cl, o);
758 UBYTE srcBpp = bmdata->bytesperpixel;
760 switch(dstPixFmt)
762 case vHidd_StdPixFmt_Native:
763 switch(srcBpp)
765 case 1:
766 /* Not supported */
767 break;
769 case 2:
771 struct pHidd_BitMap_CopyMemBox16 __m =
773 SD(cl)->mid_CopyMemBox16, src, 0, 0, dst,
774 0, 0, width, height, srcPitch, dstPitch
775 }, *m = &__m;
776 OOP_DoMethod(o, (OOP_Msg)m);
778 break;
780 case 4:
782 struct pHidd_BitMap_CopyMemBox32 __m =
784 SD(cl)->mid_CopyMemBox32, src, 0, 0, dst,
785 0, 0, width, height, srcPitch, dstPitch
786 }, *m = &__m;
787 OOP_DoMethod(o, (OOP_Msg)m);
789 break;
791 } /* switch(data->bytesperpixel) */
792 break;
794 case vHidd_StdPixFmt_Native32:
795 switch(srcBpp)
797 case 1:
798 /* Not supported */
799 break;
801 case 2:
803 struct pHidd_BitMap_GetMem32Image16 __m =
805 SD(cl)->mid_GetMem32Image16, src, 0, 0, dst,
806 width, height, srcPitch, dstPitch
807 }, *m = &__m;
808 OOP_DoMethod(o, (OOP_Msg)m);
810 break;
812 case 4:
814 struct pHidd_BitMap_CopyMemBox32 __m =
816 SD(cl)->mid_CopyMemBox32, src, 0, 0, dst,
817 0, 0, width, height, srcPitch, dstPitch
818 }, *m = &__m;
819 OOP_DoMethod(o, (OOP_Msg)m);
821 break;
823 } /* switch(data->bytesperpixel) */
824 break;
825 default:
827 /* Use ConvertPixels to convert that data to destination format */
828 APTR csrc = src;
829 APTR * psrc = &csrc;
830 APTR cdst = dst;
831 APTR * pdst = &cdst;
832 OOP_Object * dstPF = NULL;
833 OOP_Object * srcPF = NULL;
834 OOP_Object * gfxHidd = NULL;
835 struct pHidd_Gfx_GetPixFmt __gpf =
837 SD(cl)->mid_GetPixFmt, dstPixFmt
838 }, *gpf = &__gpf;
840 OOP_GetAttr(o, aHidd_BitMap_PixFmt, (APTR)&srcPF);
841 OOP_GetAttr(o, aHidd_BitMap_GfxHidd, (APTR)&gfxHidd);
842 dstPF = (OOP_Object *)OOP_DoMethod(gfxHidd, (OOP_Msg)gpf);
845 struct pHidd_BitMap_ConvertPixels __m =
847 SD(cl)->mid_ConvertPixels,
848 psrc, (HIDDT_PixelFormat *)srcPF, srcPitch,
849 pdst, (HIDDT_PixelFormat *)dstPF, dstPitch,
850 width, height, NULL
851 }, *m = &__m;
852 OOP_DoMethod(o, (OOP_Msg)m);
856 break;
859 return TRUE;
862 static inline VOID HiddNouveau3DCopyBoxFromGART(struct CardData * carddata,
863 struct HIDDNouveauBitMapData * dstdata, ULONG gartpitch,
864 LONG x, LONG y, LONG width, LONG height)
866 struct HIDDNouveauBitMapData srcdata;
868 /* Wrap GART */
869 srcdata.bo = carddata->GART;
870 srcdata.width = width;
871 srcdata.height = height;
872 srcdata.depth = 32;
873 srcdata.bytesperpixel = 4;
874 srcdata.pitch = gartpitch;
876 LOCK_ENGINE
878 /* Render using 3D engine */
879 switch(carddata->architecture)
881 case(NV_ARCH_40):
882 HIDDNouveauNV403DCopyBox(carddata,
883 &srcdata, dstdata,
884 0, 0, x, y, width, height, BLENDOP_ALPHA);
885 break;
886 case(NV_ARCH_30):
887 HIDDNouveauNV303DCopyBox(carddata,
888 &srcdata, dstdata,
889 0, 0, x, y, width, height, BLENDOP_ALPHA);
890 break;
891 case(NV_ARCH_20):
892 case(NV_ARCH_10):
893 HIDDNouveauNV103DCopyBox(carddata,
894 &srcdata, dstdata,
895 0, 0, x, y, width, height, BLENDOP_ALPHA);
896 break;
899 UNLOCK_ENGINE
902 /* NOTE: Assumes lock on bitmap is already made */
903 /* NOTE: Assumes lock on GART object is already made */
904 /* NOTE: Assumes buffer is not mapped */
905 BOOL HiddNouveauAccelARGBUpload3D(
906 UBYTE * srcpixels, ULONG srcpitch,
907 LONG x, LONG y, LONG width, LONG height,
908 OOP_Class *cl, OOP_Object *o)
910 struct HIDDNouveauBitMapData * dstdata = OOP_INST_DATA(cl, o);
911 struct CardData * carddata = &(SD(cl)->carddata);
912 unsigned cpp = 4; /* We are always getting ARGB buffer */
913 unsigned line_len = width * cpp;
914 /* Maximum DMA transfer */
915 unsigned line_count = carddata->GART->size / line_len;
916 char *src = (char *)srcpixels;
918 /* HW limitations */
919 if (line_count > 2047)
920 line_count = 2047;
922 while (height) {
923 char *dst;
925 if (line_count > height)
926 line_count = height;
928 /* Upload to GART */
929 if (nouveau_bo_map(carddata->GART, NOUVEAU_BO_WR))
930 return FALSE;
931 dst = carddata->GART->map;
933 #if AROS_BIG_ENDIAN
935 /* Just use copy. Memory formats match */
936 struct pHidd_BitMap_CopyMemBox32 __m =
938 SD(cl)->mid_CopyMemBox32, src, 0, 0, dst,
939 0, 0, width, height, srcpitch, line_len
940 }, *m = &__m;
941 OOP_DoMethod(o, (OOP_Msg)m);
943 #else
945 /* Use ConvertPixels to convert that data to destination format */
946 APTR csrc = src;
947 APTR * psrc = &csrc;
948 APTR cdst = dst;
949 APTR * pdst = &cdst;
950 OOP_Object * dstPF = NULL;
951 OOP_Object * srcPF = NULL;
952 OOP_Object * gfxHidd = NULL;
953 struct pHidd_Gfx_GetPixFmt __gpfsrc =
955 SD(cl)->mid_GetPixFmt, vHidd_StdPixFmt_BGRA32
956 }, *gpfsrc = &__gpfsrc;
957 struct pHidd_Gfx_GetPixFmt __gpfdst =
959 SD(cl)->mid_GetPixFmt, vHidd_StdPixFmt_ARGB32
960 }, *gpfdst = &__gpfdst;
962 OOP_GetAttr(o, aHidd_BitMap_GfxHidd, (APTR)&gfxHidd);
963 srcPF = (OOP_Object *)OOP_DoMethod(gfxHidd, (OOP_Msg)gpfsrc);
964 dstPF = (OOP_Object *)OOP_DoMethod(gfxHidd, (OOP_Msg)gpfdst);
967 struct pHidd_BitMap_ConvertPixels __m =
969 SD(cl)->mid_ConvertPixels,
970 psrc, (HIDDT_PixelFormat *)srcPF, srcpitch,
971 pdst, (HIDDT_PixelFormat *)dstPF, line_len,
972 width, height, NULL
973 }, *m = &__m;
974 OOP_DoMethod(o, (OOP_Msg)m);
977 #endif
979 src += srcpitch * line_count;
980 nouveau_bo_unmap(carddata->GART);
982 HiddNouveau3DCopyBoxFromGART(carddata, dstdata, line_len, x, y, width, line_count);
984 height -= line_count;
985 y += line_count;
988 return TRUE;
991 /* NOTE: Assumes lock on bitmap is already made */
992 /* NOTE: Assumes lock on GART object is already made */
993 /* NOTE: Assumes buffer is not mapped */
994 BOOL HiddNouveauAccelAPENUpload3D(
995 UBYTE * srcalpha, BOOL srcinvertalpha, ULONG srcpitch, ULONG srcpenrgb,
996 LONG x, LONG y, LONG width, LONG height,
997 OOP_Class *cl, OOP_Object *o)
999 struct HIDDNouveauBitMapData * dstdata = OOP_INST_DATA(cl, o);
1000 struct CardData * carddata = &(SD(cl)->carddata);
1001 unsigned cpp = 4; /* We are always getting ARGB buffer */
1002 unsigned line_len = width * cpp;
1003 /* Maximum DMA transfer */
1004 unsigned line_count = carddata->GART->size / line_len;
1005 char *src = (char *)srcalpha;
1007 /* HW limitations */
1008 if (line_count > 2047)
1009 line_count = 2047;
1011 while (height) {
1012 char *dst;
1013 ULONG srcy, srcx;
1015 if (line_count > height)
1016 line_count = height;
1018 /* Upload to GART */
1019 if (nouveau_bo_map(carddata->GART, NOUVEAU_BO_WR))
1020 return FALSE;
1021 dst = carddata->GART->map;
1023 /* Draw data into GART */
1024 if (srcinvertalpha) /* Keep condition outside loop to improve performance */
1026 for (srcy = 0; srcy < line_count; srcy++)
1028 for (srcx = 0; srcx < width; srcx++)
1030 ULONG * pos = (ULONG *)(dst + (srcx * cpp));
1031 *pos = srcpenrgb | ((src[srcx] << 24) ^ 255);
1033 src += srcpitch;
1034 dst += line_len;
1037 else
1039 for (srcy = 0; srcy < line_count; srcy++)
1041 for (srcx = 0; srcx < width; srcx++)
1043 ULONG * pos = (ULONG *)(dst + (srcx * cpp));
1044 *pos = srcpenrgb | (src[srcx] << 24);
1046 src += srcpitch;
1047 dst += line_len;
1051 nouveau_bo_unmap(carddata->GART);
1053 HiddNouveau3DCopyBoxFromGART(carddata, dstdata, line_len, x, y, width, line_count);
1055 height -= line_count;
1056 y += line_count;
1059 return TRUE;
1062 #define POINT_OUTSIDE_CLIP(gc, x, y) \
1063 ( (x) < GC_CLIPX1(gc) \
1064 || (x) > GC_CLIPX2(gc) \
1065 || (y) < GC_CLIPY1(gc) \
1066 || (y) > GC_CLIPY2(gc) )
1068 /* NOTE: Assumes lock on bitmap is already made */
1069 /* NOTE: Assumes buffer is mapped */
1070 VOID HIDDNouveauBitMapDrawSolidLine(struct HIDDNouveauBitMapData * bmdata,
1071 OOP_Object * gc, LONG destX1, LONG destY1, LONG destX2, LONG destY2)
1073 WORD i;
1074 LONG x1, y1, x2, y2;
1075 ULONG fg; /* foreground pen */
1076 APTR doclip;
1078 IPTR map = (IPTR)bmdata->bo->map;
1080 doclip = GC_DOCLIP(gc);
1081 fg = GC_FG(gc);
1083 /* Normalize coords */
1084 if (destX1 > destX2)
1086 x1 = destX2; x2 = destX1;
1088 else
1090 x1 = destX1; x2 = destX2;
1093 if (destY1 > destY2)
1095 y1 = destY2; y2 = destY1;
1097 else
1099 y1 = destY1; y2 = destY2;
1102 if (doclip)
1104 /* If line is not inside cliprect, then just return */
1105 if ( x1 > GC_CLIPX2(gc)
1106 || x2 < GC_CLIPX1(gc)
1107 || y1 > GC_CLIPY2(gc)
1108 || y2 < GC_CLIPY1(gc) )
1111 /* Line is not inside cliprect, so just return */
1112 return;
1116 if (y1 == y2)
1119 Horizontal line drawing code.
1121 IPTR addr = map + (bmdata->pitch * y1) + (x1 * bmdata->bytesperpixel);
1123 for(i = x1; i != x2; i++)
1125 /* Pixel inside ? */
1126 if ((!doclip) || (!POINT_OUTSIDE_CLIP(gc, i, y1)))
1128 if (bmdata->bytesperpixel == 2)
1129 writew(fg, (APTR)addr);
1130 else
1131 writel(fg, (APTR)addr);
1133 addr += bmdata->bytesperpixel;
1136 else if (x1 == x2)
1139 Vertical line drawing code.
1141 IPTR addr = map + (bmdata->pitch * y1) + (x1 * bmdata->bytesperpixel);
1143 for(i = y1; i != y2; i++)
1145 /* Pixel inside ? */
1146 if (!doclip || !POINT_OUTSIDE_CLIP(gc, x1, i ))
1148 if (bmdata->bytesperpixel == 2)
1149 writew(fg, (APTR)addr);
1150 else
1151 writel(fg, (APTR)addr);
1153 addr += bmdata->pitch;
1156 else
1159 Generic line drawing code.
1161 WORD dx, dy, x, y, incrE, incrNE, d, s1, s2, t;
1162 IPTR addr;
1164 /* Restore original coordinates - important for non-straight lines as
1165 normalization might have switched them */
1166 x1 = destX1;
1167 y1 = destY1;
1168 x2 = destX2;
1169 y2 = destY2;
1171 /* Calculate slope */
1172 dx = abs(x2 - x1);
1173 dy = abs(y2 - y1);
1175 /* which direction? */
1176 if((x2 - x1) > 0) s1 = 1; else s1 = - 1;
1177 if((y2 - y1) > 0) s2 = 1; else s2 = - 1;
1179 /* change axes if dx < dy */
1180 if(dx < dy)
1182 d = dx;
1183 dx = dy;
1184 dy = d;
1185 t = 0;
1187 else
1189 t = 1;
1192 d = 2 * dy - dx; /* initial value of d */
1194 incrE = 2 * dy; /* Increment use for move to E */
1195 incrNE = 2 * (dy - dx); /* Increment use for move to NE */
1197 x = x1; y = y1;
1199 for(i = 0; i <= dx; i++)
1201 /* Pixel inside ? */
1202 if (!doclip || !POINT_OUTSIDE_CLIP(gc, x, y ))
1204 addr = map + (x * bmdata->bytesperpixel) + (bmdata->pitch * y);
1205 if (bmdata->bytesperpixel == 2)
1206 writew(fg, (APTR)addr);
1207 else
1208 writel(fg, (APTR)addr);
1211 if(d <= 0)
1213 if(t == 1)
1215 x = x + s1;
1217 else
1219 y = y + s2;
1222 d = d + incrE;
1224 else
1226 x = x + s1;
1227 y = y + s2;
1228 d = d + incrNE;