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>
27 #include <proto/exec.h>
29 #undef HiddBitMapAttrBase
30 #define HiddBitMapAttrBase (SD(cl)->bitMapAttrBase)
32 static inline int do_alpha(int a
, int 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
)
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
++)
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
;
61 src_red
= (srcpix
& 0x00FF0000) >> 16;
62 src_green
= (srcpix
& 0x0000FF00) >> 8;
63 src_blue
= (srcpix
& 0x000000FF);
64 src_alpha
= (srcpix
& 0xFF000000) >> 24;
66 src_red
= (srcpix
& 0x0000FF00) >> 8;
67 src_green
= (srcpix
& 0x00FF0000) >> 16;
68 src_blue
= (srcpix
& 0xFF000000) >> 24;
69 src_alpha
= (srcpix
& 0x000000FF);
73 * If alpha=0, do not change the destination pixel at all.
74 * This saves us unnecessary reads and writes to VRAM.
79 * Full opacity. Do not read the destination pixel, as
80 * it's value does not matter anyway.
82 if (src_alpha
== 0xff)
85 dst_green
= src_green
;
91 * Alpha blending with source and destination pixels.
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 */
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
)
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
++)
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
;
141 src_red
= (srcpix
& 0x00FF0000) >> 16;
142 src_green
= (srcpix
& 0x0000FF00) >> 8;
143 src_blue
= (srcpix
& 0x000000FF);
144 src_alpha
= (srcpix
& 0xFF000000) >> 24;
146 src_red
= (srcpix
& 0x0000FF00) >> 8;
147 src_green
= (srcpix
& 0x00FF0000) >> 16;
148 src_blue
= (srcpix
& 0xFF000000) >> 24;
149 src_alpha
= (srcpix
& 0x000000FF);
153 * If alpha=0, do not change the destination pixel at all.
154 * This saves us unnecessary reads and writes to VRAM.
159 * Full opacity. Do not read the destination pixel, as
160 * it's value does not matter anyway.
162 if (src_alpha
== 0xff)
165 dst_green
= src_green
;
171 * Alpha blending with source and destination pixels.
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 */
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
)
205 UBYTE
*pixarray
= srcalpha
;
207 LONG fg_red
, fg_green
, fg_blue
;
208 LONG bg_red
= 0, bg_green
= 0, bg_blue
= 0;
211 if (width
<= 0 || height
<= 0)
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
)
224 else if (GC_DRMD(gc
) == vHidd_GC_DrawMode_Invert
)
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
;
248 for(x
= 0; x
< width
; x
++)
251 LONG dst_red
, dst_green
, dst_blue
, alpha
;
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. */
261 dst_green
= fg_green
;
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
);
283 } /* for(x = 0; x < msg->width; x++) */
286 case 1: /* JAM1 | INVERSVID */
287 for(x
= 0; x
< width
; x
++)
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. */
300 dst_green
= fg_green
;
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
);
322 } /* for(x = 0; x < width; x++) */
325 case 2: /* COMPLEMENT */
326 for(x
= 0; x
< width
; x
++)
336 destpix
= readl(destaddr
);
338 writel(destpix
, destaddr
);
343 } /* for(x = 0; x < width; x++) */
346 case 3: /* COMPLEMENT | INVERSVID*/
347 for(x
= 0; x
< width
; x
++)
357 destpix
= readl(destaddr
);
359 writel(destpix
, destaddr
);
364 } /* for(x = 0; x < width; x++) */
368 for(x
= 0; x
< width
; x
++)
371 LONG dst_red
, dst_green
, dst_blue
, alpha
;
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
);
385 } /* for(x = 0; x < width; x++) */
388 case 5: /* JAM2 | INVERSVID */
389 for(x
= 0; x
< width
; x
++)
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
);
406 } /* for(x = 0; x < width; x++) */
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
)
423 UBYTE
*pixarray
= srcalpha
;
425 LONG fg_red
, fg_green
, fg_blue
;
426 LONG bg_red
= 0, bg_green
= 0, bg_blue
= 0;
429 if (width
<= 0 || height
<= 0)
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
)
442 else if (GC_DRMD(gc
) == vHidd_GC_DrawMode_Invert
)
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
;
466 for(x
= 0; x
< width
; x
++)
469 LONG dst_red
, dst_green
, dst_blue
, alpha
;
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. */
479 dst_green
= fg_green
;
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
);
501 } /* for(x = 0; x < msg->width; x++) */
504 case 1: /* JAM1 | INVERSVID */
505 for(x
= 0; x
< width
; x
++)
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. */
518 dst_green
= fg_green
;
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
);
540 } /* for(x = 0; x < width; x++) */
543 case 2: /* COMPLEMENT */
544 for(x
= 0; x
< width
; x
++)
554 destpix
= readw(destaddr
);
556 writew(destpix
, destaddr
);
561 } /* for(x = 0; x < width; x++) */
564 case 3: /* COMPLEMENT | INVERSVID*/
565 for(x
= 0; x
< width
; x
++)
575 destpix
= readw(destaddr
);
577 writew(destpix
, destaddr
);
582 } /* for(x = 0; x < width; x++) */
586 for(x
= 0; x
< width
; x
++)
589 LONG dst_red
, dst_green
, dst_blue
, alpha
;
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
);
603 } /* for(x = 0; x < width; x++) */
606 case 5: /* JAM2 | INVERSVID */
607 for(x
= 0; x
< width
; x
++)
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
);
624 } /* for(x = 0; x < width; x++) */
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
;
648 case vHidd_StdPixFmt_Native
:
657 struct pHidd_BitMap_CopyMemBox16 __m
=
659 SD(cl
)->mid_CopyMemBox16
, src
, 0, 0, dst
,
660 0, 0, width
, height
, srcPitch
, dstPitch
662 OOP_DoMethod(o
, (OOP_Msg
)m
);
668 struct pHidd_BitMap_CopyMemBox32 __m
=
670 SD(cl
)->mid_CopyMemBox32
, src
, 0, 0, dst
,
671 0, 0, width
, height
, srcPitch
, dstPitch
673 OOP_DoMethod(o
, (OOP_Msg
)m
);
677 } /* switch(data->bytesperpixel) */
680 case vHidd_StdPixFmt_Native32
:
689 struct pHidd_BitMap_PutMem32Image16 __m
=
691 SD(cl
)->mid_PutMem32Image16
, src
, dst
,
692 0, 0, width
, height
, srcPitch
, dstPitch
694 OOP_DoMethod(o
, (OOP_Msg
)m
);
700 struct pHidd_BitMap_CopyMemBox32 __m
=
702 SD(cl
)->mid_CopyMemBox32
, src
, 0, 0, dst
,
703 0, 0, width
, height
, srcPitch
, dstPitch
705 OOP_DoMethod(o
, (OOP_Msg
)m
);
709 } /* switch(data->bytesperpixel) */
713 /* Use ConvertPixels to convert that data to destination format */
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
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
,
738 OOP_DoMethod(o
, (OOP_Msg
)m
);
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
;
762 case vHidd_StdPixFmt_Native
:
771 struct pHidd_BitMap_CopyMemBox16 __m
=
773 SD(cl
)->mid_CopyMemBox16
, src
, 0, 0, dst
,
774 0, 0, width
, height
, srcPitch
, dstPitch
776 OOP_DoMethod(o
, (OOP_Msg
)m
);
782 struct pHidd_BitMap_CopyMemBox32 __m
=
784 SD(cl
)->mid_CopyMemBox32
, src
, 0, 0, dst
,
785 0, 0, width
, height
, srcPitch
, dstPitch
787 OOP_DoMethod(o
, (OOP_Msg
)m
);
791 } /* switch(data->bytesperpixel) */
794 case vHidd_StdPixFmt_Native32
:
803 struct pHidd_BitMap_GetMem32Image16 __m
=
805 SD(cl
)->mid_GetMem32Image16
, src
, 0, 0, dst
,
806 width
, height
, srcPitch
, dstPitch
808 OOP_DoMethod(o
, (OOP_Msg
)m
);
814 struct pHidd_BitMap_CopyMemBox32 __m
=
816 SD(cl
)->mid_CopyMemBox32
, src
, 0, 0, dst
,
817 0, 0, width
, height
, srcPitch
, dstPitch
819 OOP_DoMethod(o
, (OOP_Msg
)m
);
823 } /* switch(data->bytesperpixel) */
827 /* Use ConvertPixels to convert that data to destination format */
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
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
,
852 OOP_DoMethod(o
, (OOP_Msg
)m
);
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
;
869 srcdata
.bo
= carddata
->GART
;
870 srcdata
.width
= width
;
871 srcdata
.height
= height
;
873 srcdata
.bytesperpixel
= 4;
874 srcdata
.pitch
= gartpitch
;
878 /* Render using 3D engine */
879 switch(carddata
->architecture
)
882 HIDDNouveauNV403DCopyBox(carddata
,
884 0, 0, x
, y
, width
, height
, BLENDOP_ALPHA
);
887 HIDDNouveauNV303DCopyBox(carddata
,
889 0, 0, x
, y
, width
, height
, BLENDOP_ALPHA
);
893 HIDDNouveauNV103DCopyBox(carddata
,
895 0, 0, x
, y
, width
, height
, BLENDOP_ALPHA
);
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
;
919 if (line_count
> 2047)
925 if (line_count
> height
)
929 if (nouveau_bo_map(carddata
->GART
, NOUVEAU_BO_WR
))
931 dst
= carddata
->GART
->map
;
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
941 OOP_DoMethod(o
, (OOP_Msg
)m
);
945 /* Use ConvertPixels to convert that data to destination format */
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
,
974 OOP_DoMethod(o
, (OOP_Msg
)m
);
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
;
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)
1015 if (line_count
> height
)
1016 line_count
= height
;
1018 /* Upload to GART */
1019 if (nouveau_bo_map(carddata
->GART
, NOUVEAU_BO_WR
))
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);
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);
1051 nouveau_bo_unmap(carddata
->GART
);
1053 HiddNouveau3DCopyBoxFromGART(carddata
, dstdata
, line_len
, x
, y
, width
, line_count
);
1055 height
-= line_count
;
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
)
1074 LONG x1
, y1
, x2
, y2
;
1075 ULONG fg
; /* foreground pen */
1078 IPTR map
= (IPTR
)bmdata
->bo
->map
;
1080 doclip
= GC_DOCLIP(gc
);
1083 /* Normalize coords */
1084 if (destX1
> destX2
)
1086 x1
= destX2
; x2
= destX1
;
1090 x1
= destX1
; x2
= destX2
;
1093 if (destY1
> destY2
)
1095 y1
= destY2
; y2
= destY1
;
1099 y1
= destY1
; y2
= destY2
;
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 */
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
);
1131 writel(fg
, (APTR
)addr
);
1133 addr
+= bmdata
->bytesperpixel
;
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
);
1151 writel(fg
, (APTR
)addr
);
1153 addr
+= bmdata
->pitch
;
1159 Generic line drawing code.
1161 WORD dx
, dy
, x
, y
, incrE
, incrNE
, d
, s1
, s2
, t
;
1164 /* Restore original coordinates - important for non-straight lines as
1165 normalization might have switched them */
1171 /* Calculate slope */
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 */
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 */
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
);
1208 writel(fg
, (APTR
)addr
);