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
24 #include "nouveau_intern.h"
25 #include "nouveau_class.h"
26 #include <proto/oop.h>
28 #undef HiddBitMapAttrBase
29 #define HiddBitMapAttrBase (SD(cl)->bitMapAttrBase)
31 static inline int do_alpha(int a
, int v
)
34 return ((tmp
<< 8) + tmp
+ 32768) >> 16;
37 /* NOTE: Assumes lock on bitmap is already made */
38 /* NOTE: Assumes buffer is mapped */
39 VOID
HIDDNouveauBitMapPutAlphaImage32(struct HIDDNouveauBitMapData
* bmdata
,
40 APTR srcbuff
, ULONG srcpitch
, LONG destX
, LONG destY
, LONG width
, LONG height
)
44 for(y
= 0; y
< height
; y
++)
46 /* Calculate line start addresses */
47 IPTR srcaddr
= (srcpitch
* y
) + (IPTR
)srcbuff
;
48 IPTR destaddr
= (destX
* 4) + (bmdata
->pitch
* (destY
+ y
)) + (IPTR
)bmdata
->bo
->map
;
50 for (x
= 0; x
< width
; x
++)
54 LONG src_red
, src_green
, src_blue
, src_alpha
;
55 LONG dst_red
, dst_green
, dst_blue
;
57 /* Read RGBA pixel from input array */
58 srcpix
= *(ULONG
*)srcaddr
;
60 src_red
= (srcpix
& 0x00FF0000) >> 16;
61 src_green
= (srcpix
& 0x0000FF00) >> 8;
62 src_blue
= (srcpix
& 0x000000FF);
63 src_alpha
= (srcpix
& 0xFF000000) >> 24;
65 src_red
= (srcpix
& 0x0000FF00) >> 8;
66 src_green
= (srcpix
& 0x00FF0000) >> 16;
67 src_blue
= (srcpix
& 0xFF000000) >> 24;
68 src_alpha
= (srcpix
& 0x000000FF);
72 * If alpha=0, do not change the destination pixel at all.
73 * This saves us unnecessary reads and writes to VRAM.
78 * Full opacity. Do not read the destination pixel, as
79 * it's value does not matter anyway.
81 if (src_alpha
== 0xff)
84 dst_green
= src_green
;
90 * Alpha blending with source and destination pixels.
93 destpix
= readl(destaddr
);
95 dst_red
= (destpix
& 0x00FF0000) >> 16;
96 dst_green
= (destpix
& 0x0000FF00) >> 8;
97 dst_blue
= (destpix
& 0x000000FF);
99 dst_red
+= do_alpha(src_alpha
, src_red
- dst_red
);
100 dst_green
+= do_alpha(src_alpha
, src_green
- dst_green
);
101 dst_blue
+= do_alpha(src_alpha
, src_blue
- dst_blue
);
104 destpix
= (dst_red
<< 16) + (dst_green
<< 8) + (dst_blue
);
106 /* Store the new pixel */
107 writel(destpix
, destaddr
);
110 /* Advance pointers */
117 /* NOTE: Assumes lock on bitmap is already made */
118 /* NOTE: Assumes buffer is mapped */
119 VOID
HIDDNouveauBitMapPutAlphaImage16(struct HIDDNouveauBitMapData
* bmdata
,
120 APTR srcbuff
, ULONG srcpitch
, LONG destX
, LONG destY
, LONG width
, LONG height
)
124 for(y
= 0; y
< height
; y
++)
126 /* Calculate line start addresses */
127 IPTR srcaddr
= (srcpitch
* y
) + (IPTR
)srcbuff
;
128 IPTR destaddr
= (destX
* 2) + (bmdata
->pitch
* (destY
+ y
)) + (IPTR
)bmdata
->bo
->map
;
130 for (x
= 0; x
< width
; x
++)
134 LONG src_red
, src_green
, src_blue
, src_alpha
;
135 LONG dst_red
, dst_green
, dst_blue
;
137 /* Read RGBA pixel from input array */
138 srcpix
= *(ULONG
*)srcaddr
;
140 src_red
= (srcpix
& 0x00FF0000) >> 16;
141 src_green
= (srcpix
& 0x0000FF00) >> 8;
142 src_blue
= (srcpix
& 0x000000FF);
143 src_alpha
= (srcpix
& 0xFF000000) >> 24;
145 src_red
= (srcpix
& 0x0000FF00) >> 8;
146 src_green
= (srcpix
& 0x00FF0000) >> 16;
147 src_blue
= (srcpix
& 0xFF000000) >> 24;
148 src_alpha
= (srcpix
& 0x000000FF);
152 * If alpha=0, do not change the destination pixel at all.
153 * This saves us unnecessary reads and writes to VRAM.
158 * Full opacity. Do not read the destination pixel, as
159 * it's value does not matter anyway.
161 if (src_alpha
== 0xff)
164 dst_green
= src_green
;
170 * Alpha blending with source and destination pixels.
174 destpix
= readw(destaddr
);
176 dst_red
= (destpix
& 0x0000F800) >> 8;
177 dst_green
= (destpix
& 0x000007e0) >> 3;
178 dst_blue
= (destpix
& 0x0000001f) << 3;
180 dst_red
+= do_alpha(src_alpha
, src_red
- dst_red
);
181 dst_green
+= do_alpha(src_alpha
, src_green
- dst_green
);
182 dst_blue
+= do_alpha(src_alpha
, src_blue
- dst_blue
);
185 destpix
= (((dst_red
<< 8) & 0xf800) | ((dst_green
<< 3) & 0x07e0) | ((dst_blue
>> 3) & 0x001f));
187 writew(destpix
, destaddr
);
190 /* Advance pointers */
197 /* NOTE: Assumes lock on bitmap is already made */
198 /* NOTE: Assumes buffer is mapped */
199 VOID
HIDDNouveauBitMapPutAlphaTemplate32(struct HIDDNouveauBitMapData
* bmdata
,
200 OOP_Object
* gc
, OOP_Object
* bm
, BOOL invertalpha
,
201 UBYTE
* srcalpha
, ULONG srcpitch
, LONG destX
, LONG destY
, LONG width
, LONG height
)
204 UBYTE
*pixarray
= srcalpha
;
206 LONG fg_red
, fg_green
, fg_blue
;
207 LONG bg_red
= 0, bg_green
= 0, bg_blue
= 0;
210 if (width
<= 0 || height
<= 0)
213 HIDD_BM_UnmapPixel(bm
, GC_FG(gc
), &color
);
215 fg_red
= color
.red
>> 8;
216 fg_green
= color
.green
>> 8;
217 fg_blue
= color
.blue
>> 8;
219 if (GC_COLEXP(gc
) == vHidd_GC_ColExp_Transparent
)
223 else if (GC_DRMD(gc
) == vHidd_GC_DrawMode_Invert
)
231 HIDD_BM_UnmapPixel(bm
, GC_BG(gc
), &color
);
232 bg_red
= color
.red
>> 8;
233 bg_green
= color
.green
>> 8;
234 bg_blue
= color
.blue
>> 8;
237 if (invertalpha
) type
++;
240 for(y
= 0; y
< height
; y
++)
242 IPTR destaddr
= (destX
* 4) + ((destY
+ y
) * bmdata
->pitch
) + (IPTR
)bmdata
->bo
->map
;
247 for(x
= 0; x
< width
; x
++)
250 LONG dst_red
, dst_green
, dst_blue
, alpha
;
255 if (alpha
!= 0) /* If alpha=0, do not change the destination pixel at all. */
257 if (alpha
== 0xff) /* Full opacity. Do not read the destination pixel. */
260 dst_green
= fg_green
;
265 destpix
= readl(destaddr
);
267 dst_red
= (destpix
& 0x00FF0000) >> 16;
268 dst_green
= (destpix
& 0x0000FF00) >> 8;
269 dst_blue
= (destpix
& 0x000000FF);
271 dst_red
+= do_alpha(alpha
, fg_red
- dst_red
);
272 dst_green
+= do_alpha(alpha
, fg_green
- dst_green
);
273 dst_blue
+= do_alpha(alpha
, fg_blue
- dst_blue
);
276 destpix
= (dst_red
<< 16) + (dst_green
<< 8) + (dst_blue
);
277 writel(destpix
, destaddr
);
282 } /* for(x = 0; x < msg->width; x++) */
285 case 1: /* JAM1 | INVERSVID */
286 for(x
= 0; x
< width
; x
++)
289 LONG dst_red
, dst_green
, dst_blue
, alpha
;
291 alpha
= (*pixarray
++) ^ 255;
294 if (alpha
!= 0) /* If alpha=0, do not change the destination pixel at all. */
296 if (alpha
== 0xff) /* Full opacity. Do not read the destination pixel. */
299 dst_green
= fg_green
;
304 destpix
= readl(destaddr
);
306 dst_red
= (destpix
& 0x00FF0000) >> 16;
307 dst_green
= (destpix
& 0x0000FF00) >> 8;
308 dst_blue
= (destpix
& 0x000000FF);
310 dst_red
+= do_alpha(alpha
, fg_red
- dst_red
);
311 dst_green
+= do_alpha(alpha
, fg_green
- dst_green
);
312 dst_blue
+= do_alpha(alpha
, fg_blue
- dst_blue
);
315 destpix
= (dst_red
<< 16) + (dst_green
<< 8) + (dst_blue
);
316 writel(destpix
, destaddr
);
321 } /* for(x = 0; x < width; x++) */
324 case 2: /* COMPLEMENT */
325 for(x
= 0; x
< width
; x
++)
335 destpix
= readl(destaddr
);
337 writel(destpix
, destaddr
);
342 } /* for(x = 0; x < width; x++) */
345 case 3: /* COMPLEMENT | INVERSVID*/
346 for(x
= 0; x
< width
; x
++)
356 destpix
= readl(destaddr
);
358 writel(destpix
, destaddr
);
363 } /* for(x = 0; x < width; x++) */
367 for(x
= 0; x
< width
; x
++)
370 LONG dst_red
, dst_green
, dst_blue
, alpha
;
375 dst_red
= bg_red
+ ((fg_red
- bg_red
) * alpha
) / 256;
376 dst_green
= bg_green
+ ((fg_green
- bg_green
) * alpha
) / 256;
377 dst_blue
= bg_blue
+ ((fg_blue
- bg_blue
) * alpha
) / 256;
379 destpix
= (dst_red
<< 16) + (dst_green
<< 8) + (dst_blue
);
381 writel(destpix
, destaddr
);
384 } /* for(x = 0; x < width; x++) */
387 case 5: /* JAM2 | INVERSVID */
388 for(x
= 0; x
< width
; x
++)
391 LONG dst_red
, dst_green
, dst_blue
, alpha
;
393 alpha
= (*pixarray
++) ^ 255;
396 dst_red
= bg_red
+ ((fg_red
- bg_red
) * alpha
) / 256;
397 dst_green
= bg_green
+ ((fg_green
- bg_green
) * alpha
) / 256;
398 dst_blue
= bg_blue
+ ((fg_blue
- bg_blue
) * alpha
) / 256;
400 destpix
= (dst_red
<< 16) + (dst_green
<< 8) + (dst_blue
);
401 writel(destpix
, destaddr
);
405 } /* for(x = 0; x < width; x++) */
410 pixarray
+= srcpitch
- width
;
412 } /* for(y = 0; y < height; y++) */
415 /* NOTE: Assumes lock on bitmap is already made */
416 /* NOTE: Assumes buffer is mapped */
417 VOID
HIDDNouveauBitMapPutAlphaTemplate16(struct HIDDNouveauBitMapData
* bmdata
,
418 OOP_Object
* gc
, OOP_Object
* bm
, BOOL invertalpha
,
419 UBYTE
* srcalpha
, ULONG srcpitch
, LONG destX
, LONG destY
, LONG width
, LONG height
)
422 UBYTE
*pixarray
= srcalpha
;
424 LONG fg_red
, fg_green
, fg_blue
;
425 LONG bg_red
= 0, bg_green
= 0, bg_blue
= 0;
428 if (width
<= 0 || height
<= 0)
431 HIDD_BM_UnmapPixel(bm
, GC_FG(gc
), &color
);
433 fg_red
= color
.red
>> 8;
434 fg_green
= color
.green
>> 8;
435 fg_blue
= color
.blue
>> 8;
437 if (GC_COLEXP(gc
) == vHidd_GC_ColExp_Transparent
)
441 else if (GC_DRMD(gc
) == vHidd_GC_DrawMode_Invert
)
449 HIDD_BM_UnmapPixel(bm
, GC_BG(gc
), &color
);
450 bg_red
= color
.red
>> 8;
451 bg_green
= color
.green
>> 8;
452 bg_blue
= color
.blue
>> 8;
455 if (invertalpha
) type
++;
458 for(y
= 0; y
< height
; y
++)
460 IPTR destaddr
= (destX
* 2) + ((destY
+ y
) * bmdata
->pitch
) + (IPTR
)bmdata
->bo
->map
;
465 for(x
= 0; x
< width
; x
++)
468 LONG dst_red
, dst_green
, dst_blue
, alpha
;
473 if (alpha
!= 0) /* If alpha=0, do not change the destination pixel at all. */
475 if (alpha
== 0xff) /* Full opacity. Do not read the destination pixel. */
478 dst_green
= fg_green
;
483 destpix
= readw(destaddr
);
485 dst_red
= (destpix
& 0x0000F800) >> 8;
486 dst_green
= (destpix
& 0x000007e0) >> 3;
487 dst_blue
= (destpix
& 0x0000001f) << 3;
489 dst_red
+= do_alpha(alpha
, fg_red
- dst_red
);
490 dst_green
+= do_alpha(alpha
, fg_green
- dst_green
);
491 dst_blue
+= do_alpha(alpha
, fg_blue
- dst_blue
);
494 destpix
= (((dst_red
<< 8) & 0xf800) | ((dst_green
<< 3) & 0x07e0) | ((dst_blue
>> 3) & 0x001f));
495 writew(destpix
, destaddr
);
500 } /* for(x = 0; x < msg->width; x++) */
503 case 1: /* JAM1 | INVERSVID */
504 for(x
= 0; x
< width
; x
++)
507 LONG dst_red
, dst_green
, dst_blue
, alpha
;
509 alpha
= (*pixarray
++) ^ 255;
512 if (alpha
!= 0) /* If alpha=0, do not change the destination pixel at all. */
514 if (alpha
== 0xff) /* Full opacity. Do not read the destination pixel. */
517 dst_green
= fg_green
;
522 destpix
= readw(destaddr
);
524 dst_red
= (destpix
& 0x0000F800) >> 8;
525 dst_green
= (destpix
& 0x000007e0) >> 3;
526 dst_blue
= (destpix
& 0x0000001f) << 3;
528 dst_red
+= do_alpha(alpha
, fg_red
- dst_red
);
529 dst_green
+= do_alpha(alpha
, fg_green
- dst_green
);
530 dst_blue
+= do_alpha(alpha
, fg_blue
- dst_blue
);
533 destpix
= (((dst_red
<< 8) & 0xf800) | ((dst_green
<< 3) & 0x07e0) | ((dst_blue
>> 3) & 0x001f));
534 writew(destpix
, destaddr
);
539 } /* for(x = 0; x < width; x++) */
542 case 2: /* COMPLEMENT */
543 for(x
= 0; x
< width
; x
++)
553 destpix
= readw(destaddr
);
555 writew(destpix
, destaddr
);
560 } /* for(x = 0; x < width; x++) */
563 case 3: /* COMPLEMENT | INVERSVID*/
564 for(x
= 0; x
< width
; x
++)
574 destpix
= readw(destaddr
);
576 writew(destpix
, destaddr
);
581 } /* for(x = 0; x < width; x++) */
585 for(x
= 0; x
< width
; x
++)
588 LONG dst_red
, dst_green
, dst_blue
, alpha
;
593 dst_red
= bg_red
+ ((fg_red
- bg_red
) * alpha
) / 256;
594 dst_green
= bg_green
+ ((fg_green
- bg_green
) * alpha
) / 256;
595 dst_blue
= bg_blue
+ ((fg_blue
- bg_blue
) * alpha
) / 256;
597 destpix
= (((dst_red
<< 8) & 0xf800) | ((dst_green
<< 3) & 0x07e0) | ((dst_blue
>> 3) & 0x001f));
598 writew(destpix
, destaddr
);
602 } /* for(x = 0; x < width; x++) */
605 case 5: /* JAM2 | INVERSVID */
606 for(x
= 0; x
< width
; x
++)
609 LONG dst_red
, dst_green
, dst_blue
, alpha
;
611 alpha
= (*pixarray
++) ^ 255;
614 dst_red
= bg_red
+ ((fg_red
- bg_red
) * alpha
) / 256;
615 dst_green
= bg_green
+ ((fg_green
- bg_green
) * alpha
) / 256;
616 dst_blue
= bg_blue
+ ((fg_blue
- bg_blue
) * alpha
) / 256;
618 destpix
= (((dst_red
<< 8) & 0xf800) | ((dst_green
<< 3) & 0x07e0) | ((dst_blue
>> 3) & 0x001f));
619 writew(destpix
, destaddr
);
623 } /* for(x = 0; x < width; x++) */
628 pixarray
+= srcpitch
- width
;
630 } /* for(y = 0; y < height; y++) */
633 /* Assumes input and output buffers are lock-protected */
634 /* Takes pixels from RAM buffer, converts them and puts them into destination
635 buffer. The destination buffer can be in VRAM or GART or RAM */
636 BOOL
HiddNouveauWriteFromRAM(
637 APTR src
, ULONG srcPitch
, HIDDT_StdPixFmt srcPixFmt
,
638 APTR dst
, ULONG dstPitch
,
639 ULONG width
, ULONG height
,
640 OOP_Class
*cl
, OOP_Object
*o
)
642 struct HIDDNouveauBitMapData
* bmdata
= OOP_INST_DATA(cl
, o
);
643 UBYTE dstBpp
= bmdata
->bytesperpixel
;
647 case vHidd_StdPixFmt_Native
:
656 struct pHidd_BitMap_CopyMemBox16 __m
=
658 SD(cl
)->mid_CopyMemBox16
, src
, 0, 0, dst
,
659 0, 0, width
, height
, srcPitch
, dstPitch
661 OOP_DoMethod(o
, (OOP_Msg
)m
);
667 struct pHidd_BitMap_CopyMemBox32 __m
=
669 SD(cl
)->mid_CopyMemBox32
, src
, 0, 0, dst
,
670 0, 0, width
, height
, srcPitch
, dstPitch
672 OOP_DoMethod(o
, (OOP_Msg
)m
);
676 } /* switch(data->bytesperpixel) */
679 case vHidd_StdPixFmt_Native32
:
688 struct pHidd_BitMap_PutMem32Image16 __m
=
690 SD(cl
)->mid_PutMem32Image16
, src
, dst
,
691 0, 0, width
, height
, srcPitch
, dstPitch
693 OOP_DoMethod(o
, (OOP_Msg
)m
);
699 struct pHidd_BitMap_CopyMemBox32 __m
=
701 SD(cl
)->mid_CopyMemBox32
, src
, 0, 0, dst
,
702 0, 0, width
, height
, srcPitch
, dstPitch
704 OOP_DoMethod(o
, (OOP_Msg
)m
);
708 } /* switch(data->bytesperpixel) */
712 /* Use ConvertPixels to convert that data to destination format */
717 OOP_Object
* dstPF
= NULL
;
718 OOP_Object
* srcPF
= NULL
;
719 OOP_Object
* gfxHidd
= NULL
;
720 struct pHidd_Gfx_GetPixFmt __gpf
=
722 SD(cl
)->mid_GetPixFmt
, srcPixFmt
725 OOP_GetAttr(o
, aHidd_BitMap_PixFmt
, (APTR
)&dstPF
);
726 OOP_GetAttr(o
, aHidd_BitMap_GfxHidd
, (APTR
)&gfxHidd
);
727 srcPF
= (OOP_Object
*)OOP_DoMethod(gfxHidd
, (OOP_Msg
)gpf
);
730 struct pHidd_BitMap_ConvertPixels __m
=
732 SD(cl
)->mid_ConvertPixels
,
733 psrc
, (HIDDT_PixelFormat
*)srcPF
, srcPitch
,
734 pdst
, (HIDDT_PixelFormat
*)dstPF
, dstPitch
,
737 OOP_DoMethod(o
, (OOP_Msg
)m
);
747 /* Assumes input and output buffers are lock-protected */
748 /* Takes pixels from source buffer, converts them and puts them into RAM
749 buffer. The source buffer can be in VRAM or GART or RAM */
750 BOOL
HiddNouveauReadIntoRAM(
751 APTR src
, ULONG srcPitch
,
752 APTR dst
, ULONG dstPitch
, HIDDT_StdPixFmt dstPixFmt
,
753 ULONG width
, ULONG height
,
754 OOP_Class
*cl
, OOP_Object
*o
)
756 struct HIDDNouveauBitMapData
* bmdata
= OOP_INST_DATA(cl
, o
);
757 UBYTE srcBpp
= bmdata
->bytesperpixel
;
761 case vHidd_StdPixFmt_Native
:
770 struct pHidd_BitMap_CopyMemBox16 __m
=
772 SD(cl
)->mid_CopyMemBox16
, src
, 0, 0, dst
,
773 0, 0, width
, height
, srcPitch
, dstPitch
775 OOP_DoMethod(o
, (OOP_Msg
)m
);
781 struct pHidd_BitMap_CopyMemBox32 __m
=
783 SD(cl
)->mid_CopyMemBox32
, src
, 0, 0, dst
,
784 0, 0, width
, height
, srcPitch
, dstPitch
786 OOP_DoMethod(o
, (OOP_Msg
)m
);
790 } /* switch(data->bytesperpixel) */
793 case vHidd_StdPixFmt_Native32
:
802 struct pHidd_BitMap_GetMem32Image16 __m
=
804 SD(cl
)->mid_GetMem32Image16
, src
, 0, 0, dst
,
805 width
, height
, srcPitch
, dstPitch
807 OOP_DoMethod(o
, (OOP_Msg
)m
);
813 struct pHidd_BitMap_CopyMemBox32 __m
=
815 SD(cl
)->mid_CopyMemBox32
, src
, 0, 0, dst
,
816 0, 0, width
, height
, srcPitch
, dstPitch
818 OOP_DoMethod(o
, (OOP_Msg
)m
);
822 } /* switch(data->bytesperpixel) */
826 /* Use ConvertPixels to convert that data to destination format */
831 OOP_Object
* dstPF
= NULL
;
832 OOP_Object
* srcPF
= NULL
;
833 OOP_Object
* gfxHidd
= NULL
;
834 struct pHidd_Gfx_GetPixFmt __gpf
=
836 SD(cl
)->mid_GetPixFmt
, dstPixFmt
839 OOP_GetAttr(o
, aHidd_BitMap_PixFmt
, (APTR
)&srcPF
);
840 OOP_GetAttr(o
, aHidd_BitMap_GfxHidd
, (APTR
)&gfxHidd
);
841 dstPF
= (OOP_Object
*)OOP_DoMethod(gfxHidd
, (OOP_Msg
)gpf
);
844 struct pHidd_BitMap_ConvertPixels __m
=
846 SD(cl
)->mid_ConvertPixels
,
847 psrc
, (HIDDT_PixelFormat
*)srcPF
, srcPitch
,
848 pdst
, (HIDDT_PixelFormat
*)dstPF
, dstPitch
,
851 OOP_DoMethod(o
, (OOP_Msg
)m
);
861 static inline VOID
HiddNouveau3DCopyBoxFromGART(struct CardData
* carddata
,
862 struct HIDDNouveauBitMapData
* dstdata
, ULONG gartpitch
,
863 LONG x
, LONG y
, LONG width
, LONG height
)
865 struct HIDDNouveauBitMapData srcdata
;
868 srcdata
.bo
= carddata
->GART
;
869 srcdata
.width
= width
;
870 srcdata
.height
= height
;
872 srcdata
.bytesperpixel
= 4;
873 srcdata
.pitch
= gartpitch
;
875 /* Render using 3D engine */
876 switch(carddata
->architecture
)
879 HIDDNouveauNV403DCopyBox(carddata
,
881 0, 0, x
, y
, width
, height
, BLENDOP_ALPHA
);
884 HIDDNouveauNV303DCopyBox(carddata
,
886 0, 0, x
, y
, width
, height
, BLENDOP_ALPHA
);
890 HIDDNouveauNV103DCopyBox(carddata
,
892 0, 0, x
, y
, width
, height
, BLENDOP_ALPHA
);
897 /* NOTE: Assumes lock on bitmap is already made */
898 /* NOTE: Assumes lock on GART object is already made */
899 /* NOTE: Assumes buffer is not mapped */
900 BOOL
HiddNouveauAccelARGBUpload3D(
901 UBYTE
* srcpixels
, ULONG srcpitch
,
902 LONG x
, LONG y
, LONG width
, LONG height
,
903 OOP_Class
*cl
, OOP_Object
*o
)
905 struct HIDDNouveauBitMapData
* dstdata
= OOP_INST_DATA(cl
, o
);
906 struct CardData
* carddata
= &(SD(cl
)->carddata
);
907 unsigned cpp
= 4; /* We are always getting ARGB buffer */
908 unsigned line_len
= width
* cpp
;
909 /* Maximum DMA transfer */
910 unsigned line_count
= carddata
->GART
->size
/ line_len
;
911 char *src
= (char *)srcpixels
;
914 if (line_count
> 2047)
920 if (line_count
> height
)
924 if (nouveau_bo_map(carddata
->GART
, NOUVEAU_BO_WR
))
926 dst
= carddata
->GART
->map
;
930 /* Just use copy. Memory formats match */
931 struct pHidd_BitMap_CopyMemBox32 __m
=
933 SD(cl
)->mid_CopyMemBox32
, src
, 0, 0, dst
,
934 0, 0, width
, height
, srcpitch
, line_len
936 OOP_DoMethod(o
, (OOP_Msg
)m
);
940 /* Use ConvertPixels to convert that data to destination format */
945 OOP_Object
* dstPF
= NULL
;
946 OOP_Object
* srcPF
= NULL
;
947 OOP_Object
* gfxHidd
= NULL
;
948 struct pHidd_Gfx_GetPixFmt __gpfsrc
=
950 SD(cl
)->mid_GetPixFmt
, vHidd_StdPixFmt_BGRA32
951 }, *gpfsrc
= &__gpfsrc
;
952 struct pHidd_Gfx_GetPixFmt __gpfdst
=
954 SD(cl
)->mid_GetPixFmt
, vHidd_StdPixFmt_ARGB32
955 }, *gpfdst
= &__gpfdst
;
957 OOP_GetAttr(o
, aHidd_BitMap_GfxHidd
, (APTR
)&gfxHidd
);
958 srcPF
= (OOP_Object
*)OOP_DoMethod(gfxHidd
, (OOP_Msg
)gpfsrc
);
959 dstPF
= (OOP_Object
*)OOP_DoMethod(gfxHidd
, (OOP_Msg
)gpfdst
);
962 struct pHidd_BitMap_ConvertPixels __m
=
964 SD(cl
)->mid_ConvertPixels
,
965 psrc
, (HIDDT_PixelFormat
*)srcPF
, srcpitch
,
966 pdst
, (HIDDT_PixelFormat
*)dstPF
, line_len
,
969 OOP_DoMethod(o
, (OOP_Msg
)m
);
974 src
+= srcpitch
* line_count
;
975 nouveau_bo_unmap(carddata
->GART
);
977 HiddNouveau3DCopyBoxFromGART(carddata
, dstdata
, line_len
, x
, y
, width
, line_count
);
979 height
-= line_count
;
986 /* NOTE: Assumes lock on bitmap is already made */
987 /* NOTE: Assumes lock on GART object is already made */
988 /* NOTE: Assumes buffer is not mapped */
989 BOOL
HiddNouveauAccelAPENUpload3D(
990 UBYTE
* srcalpha
, BOOL srcinvertalpha
, ULONG srcpitch
, ULONG srcpenrgb
,
991 LONG x
, LONG y
, LONG width
, LONG height
,
992 OOP_Class
*cl
, OOP_Object
*o
)
994 struct HIDDNouveauBitMapData
* dstdata
= OOP_INST_DATA(cl
, o
);
995 struct CardData
* carddata
= &(SD(cl
)->carddata
);
996 unsigned cpp
= 4; /* We are always getting ARGB buffer */
997 unsigned line_len
= width
* cpp
;
998 /* Maximum DMA transfer */
999 unsigned line_count
= carddata
->GART
->size
/ line_len
;
1000 char *src
= (char *)srcalpha
;
1002 /* HW limitations */
1003 if (line_count
> 2047)
1010 if (line_count
> height
)
1011 line_count
= height
;
1013 /* Upload to GART */
1014 if (nouveau_bo_map(carddata
->GART
, NOUVEAU_BO_WR
))
1016 dst
= carddata
->GART
->map
;
1018 /* Draw data into GART */
1019 if (srcinvertalpha
) /* Keep condition outside loop to improve performance */
1021 for (srcy
= 0; srcy
< line_count
; srcy
++)
1023 for (srcx
= 0; srcx
< width
; srcx
++)
1025 ULONG
* pos
= (ULONG
*)(dst
+ (srcx
* cpp
));
1026 *pos
= srcpenrgb
| ((src
[srcx
] << 24) ^ 255);
1034 for (srcy
= 0; srcy
< line_count
; srcy
++)
1036 for (srcx
= 0; srcx
< width
; srcx
++)
1038 ULONG
* pos
= (ULONG
*)(dst
+ (srcx
* cpp
));
1039 *pos
= srcpenrgb
| (src
[srcx
] << 24);
1046 nouveau_bo_unmap(carddata
->GART
);
1048 HiddNouveau3DCopyBoxFromGART(carddata
, dstdata
, line_len
, x
, y
, width
, line_count
);
1050 height
-= line_count
;
1057 #define POINT_OUTSIDE_CLIP(gc, x, y) \
1058 ( (x) < GC_CLIPX1(gc) \
1059 || (x) > GC_CLIPX2(gc) \
1060 || (y) < GC_CLIPY1(gc) \
1061 || (y) > GC_CLIPY2(gc) )
1063 /* NOTE: Assumes lock on bitmap is already made */
1064 /* NOTE: Assumes buffer is mapped */
1065 VOID
HIDDNouveauBitMapDrawSolidLine(struct HIDDNouveauBitMapData
* bmdata
,
1066 OOP_Object
* gc
, LONG destX1
, LONG destY1
, LONG destX2
, LONG destY2
)
1069 LONG x1
, y1
, x2
, y2
;
1070 ULONG fg
; /* foreground pen */
1073 IPTR map
= (IPTR
)bmdata
->bo
->map
;
1075 doclip
= GC_DOCLIP(gc
);
1078 /* Normalize coords */
1079 if (destX1
> destX2
)
1081 x1
= destX2
; x2
= destX1
;
1085 x1
= destX1
; x2
= destX2
;
1088 if (destY1
> destY2
)
1090 y1
= destY2
; y2
= destY1
;
1094 y1
= destY1
; y2
= destY2
;
1099 /* If line is not inside cliprect, then just return */
1100 if ( x1
> GC_CLIPX2(gc
)
1101 || x2
< GC_CLIPX1(gc
)
1102 || y1
> GC_CLIPY2(gc
)
1103 || y2
< GC_CLIPY1(gc
) )
1106 /* Line is not inside cliprect, so just return */
1114 Horizontal line drawing code.
1116 IPTR addr
= map
+ (bmdata
->pitch
* y1
) + (x1
* bmdata
->bytesperpixel
);
1118 for(i
= x1
; i
!= x2
; i
++)
1120 /* Pixel inside ? */
1121 if ((!doclip
) || (!POINT_OUTSIDE_CLIP(gc
, i
, y1
)))
1123 if (bmdata
->bytesperpixel
== 2)
1124 writew(fg
, (APTR
)addr
);
1126 writel(fg
, (APTR
)addr
);
1128 addr
+= bmdata
->bytesperpixel
;
1134 Vertical line drawing code.
1136 IPTR addr
= map
+ (bmdata
->pitch
* y1
) + (x1
* bmdata
->bytesperpixel
);
1138 for(i
= y1
; i
!= y2
; i
++)
1140 /* Pixel inside ? */
1141 if (!doclip
|| !POINT_OUTSIDE_CLIP(gc
, x1
, i
))
1143 if (bmdata
->bytesperpixel
== 2)
1144 writew(fg
, (APTR
)addr
);
1146 writel(fg
, (APTR
)addr
);
1148 addr
+= bmdata
->pitch
;
1154 Generic line drawing code.
1156 WORD dx
, dy
, x
, y
, incrE
, incrNE
, d
, s1
, s2
, t
;
1159 /* Restore original coordinates - important for non-straight lines as
1160 normalization might have switched them */
1166 /* Calculate slope */
1170 /* which direction? */
1171 if((x2
- x1
) > 0) s1
= 1; else s1
= - 1;
1172 if((y2
- y1
) > 0) s2
= 1; else s2
= - 1;
1174 /* change axes if dx < dy */
1187 d
= 2 * dy
- dx
; /* initial value of d */
1189 incrE
= 2 * dy
; /* Increment use for move to E */
1190 incrNE
= 2 * (dy
- dx
); /* Increment use for move to NE */
1194 for(i
= 0; i
<= dx
; i
++)
1196 /* Pixel inside ? */
1197 if (!doclip
|| !POINT_OUTSIDE_CLIP(gc
, x
, y
))
1199 addr
= map
+ (x
* bmdata
->bytesperpixel
) + (bmdata
->pitch
* y
);
1200 if (bmdata
->bytesperpixel
== 2)
1201 writew(fg
, (APTR
)addr
);
1203 writel(fg
, (APTR
)addr
);