2 * Copyright 2007 Stephane Marchesin
3 * Copyright 2007 Arthur Huillet
4 * Copyright 2007 Peter Winters
5 * Copyright 2009 Francisco Jerez
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
22 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 #include "nv_include.h"
31 #include "nv04_pushbuf.h"
33 /* Texture/Render target formats. */
34 static struct pict_format
{
37 } nv10_tex_format_pot
[] = {
39 { PICT_r5g6b5
, 0x280 },
40 { PICT_x8r8g8b8
, 0x300 },
41 { PICT_a8r8g8b8
, 0x300 },
44 }, nv10_tex_format_rect
[] = {
46 { PICT_r5g6b5
, 0x880 },
47 { PICT_x8r8g8b8
, 0x900 },
48 { PICT_a8r8g8b8
, 0x900 },
51 }, nv20_tex_format_rect
[] = {
53 { PICT_r5g6b5
, 0x880 },
54 { PICT_x8r8g8b8
, 0x900 },
55 { PICT_a8r8g8b8
, 0x900 },
58 }, nv10_rt_format
[] = {
59 { PICT_r5g6b5
, 0x103 },
60 { PICT_x8r8g8b8
, 0x108 },
61 { PICT_a8r8g8b8
, 0x108 },
66 get_tex_format(PicturePtr pict
)
68 #if !defined(__AROS__)
69 ScrnInfoPtr pScrn
= xf86Screens
[pict
->pDrawable
->pScreen
->myNum
];
71 ScrnInfoPtr pScrn
= globalcarddataptr
;
73 NVPtr pNv
= NVPTR(pScrn
);
75 /* If repeat is set we're always handling a 1x1 texture with
76 * ARGB/XRGB destination, in that case we change the format to
77 * use the POT (swizzled) matching format.
79 struct pict_format
*format
=
80 pict
->repeat
!= RepeatNone
? nv10_tex_format_pot
:
81 pNv
->Architecture
== NV_ARCH_20
? nv20_tex_format_rect
:
84 for (; format
->hw
; format
++) {
85 if (format
->exa
== pict
->format
)
93 get_rt_format(PicturePtr pict
)
95 struct pict_format
*format
= nv10_rt_format
;
97 for (; format
->hw
; format
++) {
98 if (format
->exa
== pict
->format
)
105 /* Blending functions. */
106 #define SF(x) NV10TCL_BLEND_FUNC_SRC_##x
107 #define DF(x) NV10TCL_BLEND_FUNC_DST_##x
109 static struct pict_op
{
114 { SF(ZERO
), DF(ZERO
) }, /* Clear */
115 { SF(ONE
), DF(ZERO
) }, /* Src */
116 { SF(ZERO
), DF(ONE
) }, /* Dst */
117 { SF(ONE
), DF(ONE_MINUS_SRC_ALPHA
) }, /* Over */
118 { SF(ONE_MINUS_DST_ALPHA
), DF(ONE
) }, /* OverReverse */
119 { SF(DST_ALPHA
), DF(ZERO
) }, /* In */
120 { SF(ZERO
), DF(SRC_ALPHA
) }, /* InReverse */
121 { SF(ONE_MINUS_DST_ALPHA
), DF(ZERO
) }, /* Out */
122 { SF(ZERO
), DF(ONE_MINUS_SRC_ALPHA
) }, /* OutReverse */
123 { SF(DST_ALPHA
), DF(ONE_MINUS_SRC_ALPHA
) }, /* Atop */
124 { SF(ONE_MINUS_DST_ALPHA
), DF(SRC_ALPHA
) }, /* AtopReverse */
125 { SF(ONE_MINUS_DST_ALPHA
), DF(ONE_MINUS_SRC_ALPHA
) }, /* Xor */
126 { SF(ONE
), DF(ONE
) }, /* Add */
127 { SF(SRC_ALPHA
), DF(ONE_MINUS_SRC_ALPHA
) }, /* OverAlpha */
131 needs_src_alpha(int op
)
133 return nv10_pict_op
[op
].dst
== DF(ONE_MINUS_SRC_ALPHA
)
134 || nv10_pict_op
[op
].dst
== DF(SRC_ALPHA
);
140 return nv10_pict_op
[op
].src
!= DF(ZERO
);
144 effective_component_alpha(PicturePtr mask
)
146 return mask
&& mask
->componentAlpha
&& PICT_FORMAT_RGB(mask
->format
);
149 #if !defined(__AROS__)
151 check_texture(PicturePtr pict
)
155 if (!pict
->pDrawable
)
156 NOUVEAU_FALLBACK("Solid and gradient pictures unsupported\n");
158 w
= pict
->pDrawable
->width
;
159 h
= pict
->pDrawable
->height
;
161 if (w
> 2046 || h
> 2046)
162 NOUVEAU_FALLBACK("picture too large, %dx%d\n", w
, h
);
164 if (!get_tex_format(pict
))
167 if (pict
->filter
!= PictFilterNearest
&&
168 pict
->filter
!= PictFilterBilinear
)
171 /* We cannot repeat on NV10 because NPOT textures do not
172 * support this. unfortunately. */
173 if (pict
->repeat
!= RepeatNone
)
174 /* we can repeat 1x1 textures */
175 if (!(w
== 1 && h
== 1))
182 check_render_target(PicturePtr pict
)
184 int w
= pict
->pDrawable
->width
;
185 int h
= pict
->pDrawable
->height
;
187 if (w
> 4096 || h
> 4096)
190 if (!get_rt_format(pict
))
197 check_pict_op(int op
)
199 /* We do no saturate, disjoint, conjoint, though we
200 * could do e.g. DisjointClear which really is
202 return op
< PictOpSaturate
;
207 print_fallback_info(char *reason
, int op
, PicturePtr src
, PicturePtr mask
,
213 sprintf(out
, "%s ", reason
);
218 sprintf(out
, "PictOpClear ");
221 sprintf(out
, "PictOpSrc ");
224 sprintf(out
, "PictOpDst ");
227 sprintf(out
, "PictOpOver ");
229 case PictOpOutReverse
:
230 sprintf(out
, "PictOpOutReverse ");
233 sprintf(out
, "PictOpAdd ");
236 sprintf(out
, "PictOp%d ", op
);
240 switch (src
->format
) {
242 sprintf(out
, "A8R8G8B8 ");
245 sprintf(out
, "X8R8G8B8 ");
248 sprintf(out
, "X8B8G8R8 ");
251 sprintf(out
, "R5G6B5 ");
260 sprintf(out
, "%x ", src
->format
);
264 sprintf(out
, "(%dx%d) ", src
->pDrawable
->width
,
265 src
->pDrawable
->height
);
266 if (src
->repeat
!= RepeatNone
)
271 switch (dst
->format
) {
273 sprintf(out
, "A8R8G8B8 ");
276 sprintf(out
, "X8R8G8B8 ");
279 sprintf(out
, "X8B8G8R8 ");
282 sprintf(out
, "R5G6B5 ");
291 sprintf(out
, "%x ", dst
->format
);
295 sprintf(out
, "(%dx%d) ", dst
->pDrawable
->width
,
296 dst
->pDrawable
->height
);
297 if (dst
->repeat
!= RepeatNone
)
302 sprintf(out
, "& NONE");
304 switch (mask
->format
) {
306 sprintf(out
, "& A8R8G8B8 ");
309 sprintf(out
, "& X8R8G8B8 ");
312 sprintf(out
, "& X8B8G8R8 ");
315 sprintf(out
, "& A8 ");
318 sprintf(out
, "& A1 ");
321 sprintf(out
, "& %x ", mask
->format
);
325 sprintf(out
, "(%dx%d) ", mask
->pDrawable
->width
,
326 mask
->pDrawable
->height
);
327 if (mask
->repeat
!= RepeatNone
)
329 if (mask
->componentAlpha
)
335 xf86DrvMsg(0, X_INFO
, "%s", out2
);
338 #define print_fallback_info(...)
342 NV10EXACheckComposite(int op
, PicturePtr src
, PicturePtr mask
, PicturePtr dst
)
344 if (!check_pict_op(op
)) {
345 print_fallback_info("pictop", op
, src
, mask
, dst
);
349 if (!check_render_target(dst
)) {
350 print_fallback_info("dst", op
, src
, mask
, dst
);
354 if (!check_texture(src
)) {
355 print_fallback_info("src", op
, src
, mask
, dst
);
360 if (!check_texture(mask
)) {
361 print_fallback_info("mask", op
, src
,
366 if (effective_component_alpha(mask
) &&
367 needs_src(op
) && needs_src_alpha(op
)) {
368 print_fallback_info("ca-mask", op
, src
,
374 print_fallback_info("Accelerating", op
, src
, mask
, dst
);
380 setup_texture(NVPtr pNv
, int unit
, PicturePtr pict
, PixmapPtr pixmap
)
382 struct nouveau_channel
*chan
= pNv
->chan
;
383 struct nouveau_grobj
*celsius
= pNv
->Nv3D
;
384 struct nouveau_bo
*bo
= nouveau_pixmap_bo(pixmap
);
385 unsigned tex_reloc
= NOUVEAU_BO_VRAM
| NOUVEAU_BO_GART
| NOUVEAU_BO_RD
;
386 #if !defined(__AROS__)
387 long w
= pict
->pDrawable
->width
,
388 h
= pict
->pDrawable
->height
;
390 long w
= pixmap
->width
,
394 NV10TCL_TX_FORMAT_WRAP_T_CLAMP_TO_EDGE
|
395 NV10TCL_TX_FORMAT_WRAP_S_CLAMP_TO_EDGE
|
396 log2i(w
) << 20 | log2i(h
) << 16 |
397 1 << 12 | /* lod == 1 */
398 get_tex_format(pict
) |
401 BEGIN_RING(chan
, celsius
, NV10TCL_TX_OFFSET(unit
), 1);
402 if (OUT_RELOCl(chan
, bo
, 0, tex_reloc
))
405 if (pict
->repeat
== RepeatNone
) {
406 /* NPOT_SIZE expects an even number for width, we can
407 * round up uneven numbers here because EXA always
408 * gives 64 byte aligned pixmaps and for all formats
409 * we support 64 bytes represents an even number of
414 BEGIN_RING(chan
, celsius
, NV10TCL_TX_NPOT_PITCH(unit
), 1);
415 OUT_RING (chan
, exaGetPixmapPitch(pixmap
) << 16);
417 BEGIN_RING(chan
, celsius
, NV10TCL_TX_NPOT_SIZE(unit
), 1);
418 OUT_RING (chan
, w
<< 16 | h
);
421 BEGIN_RING(chan
, celsius
, NV10TCL_TX_FORMAT(unit
), 1 );
422 if (OUT_RELOCd(chan
, bo
, txfmt
, tex_reloc
| NOUVEAU_BO_OR
,
423 NV10TCL_TX_FORMAT_DMA0
, NV10TCL_TX_FORMAT_DMA1
))
426 BEGIN_RING(chan
, celsius
, NV10TCL_TX_ENABLE(unit
), 1 );
427 OUT_RING (chan
, NV10TCL_TX_ENABLE_ENABLE
);
429 BEGIN_RING(chan
, celsius
, NV10TCL_TX_FILTER(unit
), 1);
430 if (pict
->filter
== PictFilterNearest
)
431 OUT_RING(chan
, (NV10TCL_TX_FILTER_MAGNIFY_NEAREST
|
432 NV10TCL_TX_FILTER_MINIFY_NEAREST
));
434 OUT_RING(chan
, (NV10TCL_TX_FILTER_MAGNIFY_LINEAR
|
435 NV10TCL_TX_FILTER_MINIFY_LINEAR
));
441 setup_render_target(NVPtr pNv
, PicturePtr pict
, PixmapPtr pixmap
)
443 struct nouveau_channel
*chan
= pNv
->chan
;
444 struct nouveau_grobj
*celsius
= pNv
->Nv3D
;
445 struct nouveau_bo
*bo
= nouveau_pixmap_bo(pixmap
);
447 BEGIN_RING(chan
, celsius
, NV10TCL_RT_FORMAT
, 2);
448 OUT_RING (chan
, get_rt_format(pict
));
449 OUT_RING (chan
, (exaGetPixmapPitch(pixmap
) << 16 |
450 exaGetPixmapPitch(pixmap
)));
452 BEGIN_RING(chan
, celsius
, NV10TCL_COLOR_OFFSET
, 1);
453 if (OUT_RELOCl(chan
, bo
, 0, NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
))
460 * This can be a bit difficult to understand at first glance. Reg
461 * combiners are described here:
462 * http://icps.u-strasbg.fr/~marchesin/perso/extensions/NV/register_combiners.html
464 * Single texturing setup, without honoring vertex colors (non default
465 * setup) is: Alpha RC 0 : a_0 * 1 + 0 * 0 RGB RC 0 : rgb_0 * 1 + 0 *
466 * 0 RC 1s are unused Final combiner uses default setup
468 * Default setup uses vertex rgb/alpha in place of 1s above, but we
469 * don't need that in 2D.
471 * Multi texturing setup, where we do TEX0 in TEX1 (masking) is:
472 * Alpha RC 0 : a_0 * a_1 + 0 * 0
473 * RGB RC0 : rgb_0 * a_1 + 0 * 0
475 * Final combiner uses default setup
478 /* Bind the combiner variable <input> to a constant 1. */
479 #define RC_IN_ONE(input) \
480 (NV10TCL_RC_IN_RGB_##input##_INPUT_ZERO | \
481 NV10TCL_RC_IN_RGB_##input##_COMPONENT_USAGE_ALPHA | \
482 NV10TCL_RC_IN_RGB_##input##_MAPPING_UNSIGNED_INVERT)
484 /* Bind the combiner variable <input> to the specified channel from
485 * the texture unit <unit>. */
486 #define RC_IN_TEX(input, chan, unit) \
487 (NV10TCL_RC_IN_RGB_##input##_INPUT_TEXTURE##unit | \
488 NV10TCL_RC_IN_RGB_##input##_COMPONENT_USAGE_##chan)
490 /* Bind the combiner variable <input> to the specified channel from
491 * the constant color <unit>. */
492 #define RC_IN_COLOR(input, chan, unit) \
493 (NV10TCL_RC_IN_RGB_##input##_INPUT_CONSTANT_COLOR##unit | \
494 NV10TCL_RC_IN_RGB_##input##_COMPONENT_USAGE_##chan)
496 #if !defined(__AROS__)
498 setup_combiners(NVPtr pNv
, PicturePtr src
, PicturePtr mask
)
501 setup_combiners(NVPtr pNv
, PicturePtr src
, PicturePtr mask
, int op
)
504 struct nouveau_channel
*chan
= pNv
->chan
;
505 struct nouveau_grobj
*celsius
= pNv
->Nv3D
;
506 uint32_t rc_in_alpha
= 0, rc_in_rgb
= 0;
508 if (PICT_FORMAT_A(src
->format
))
509 rc_in_alpha
|= RC_IN_TEX(A
, ALPHA
, 0);
511 rc_in_alpha
|= RC_IN_ONE(A
);
513 if (mask
&& PICT_FORMAT_A(mask
->format
))
514 rc_in_alpha
|= RC_IN_TEX(B
, ALPHA
, 1);
516 rc_in_alpha
|= RC_IN_ONE(B
);
518 if (effective_component_alpha(mask
)) {
519 #if !defined(__AROS__)
520 if (!needs_src_alpha(pNv
->alu
)) {
522 if (!needs_src_alpha(op
)) {
524 /* The alpha channels won't be used for blending. Drop
525 * them, as our pixels only have 4 components...
526 * output_i = src_i * mask_i
528 if (PICT_FORMAT_RGB(src
->format
))
529 rc_in_rgb
|= RC_IN_TEX(A
, RGB
, 0);
531 /* The RGB channels won't be used for blending. Drop
533 * output_i = src_alpha * mask_i
535 if (PICT_FORMAT_A(src
->format
))
536 rc_in_rgb
|= RC_IN_TEX(A
, ALPHA
, 0);
538 rc_in_rgb
|= RC_IN_ONE(A
);
541 rc_in_rgb
|= RC_IN_TEX(B
, RGB
, 1);
544 if (PICT_FORMAT_RGB(src
->format
))
545 rc_in_rgb
|= RC_IN_TEX(A
, RGB
, 0);
547 if (mask
&& PICT_FORMAT_A(mask
->format
))
548 rc_in_rgb
|= RC_IN_TEX(B
, ALPHA
, 1);
550 rc_in_rgb
|= RC_IN_ONE(B
);
553 BEGIN_RING(chan
, celsius
, NV10TCL_RC_IN_ALPHA(0), 1);
554 OUT_RING (chan
, rc_in_alpha
);
555 BEGIN_RING(chan
, celsius
, NV10TCL_RC_IN_RGB(0), 1);
556 OUT_RING (chan
, rc_in_rgb
);
559 #if !defined(__AROS__)
561 setup_blend_function(NVPtr pNv
)
564 setup_blend_function(NVPtr pNv
, PicturePtr dst
, PicturePtr mask
, int blendop
)
567 struct nouveau_channel
*chan
= pNv
->chan
;
568 struct nouveau_grobj
*celsius
= pNv
->Nv3D
;
569 #if !defined(__AROS__)
570 struct pict_op
*op
= &nv10_pict_op
[pNv
->alu
];
572 struct pict_op
*op
= &nv10_pict_op
[blendop
];
574 int src_factor
= op
->src
;
575 int dst_factor
= op
->dst
;
577 if (src_factor
== SF(ONE_MINUS_DST_ALPHA
) &&
578 #if !defined(__AROS__)
579 !PICT_FORMAT_A(pNv
->pdpict
->format
))
581 !PICT_FORMAT_A(dst
->format
))
583 /* ONE_MINUS_DST_ALPHA doesn't always do the right thing for
584 * framebuffers without alpha channel. But it's the same as
587 src_factor
= SF(ZERO
);
589 #if !defined(__AROS__)
590 if (effective_component_alpha(pNv
->pmpict
)) {
592 if (effective_component_alpha(mask
)) {
594 if (dst_factor
== DF(SRC_ALPHA
))
595 dst_factor
= DF(SRC_COLOR
);
596 else if (dst_factor
== DF(ONE_MINUS_SRC_ALPHA
))
597 dst_factor
= DF(ONE_MINUS_SRC_COLOR
);
600 BEGIN_RING(chan
, celsius
, NV10TCL_BLEND_FUNC_SRC
, 2);
601 OUT_RING (chan
, src_factor
);
602 OUT_RING (chan
, dst_factor
);
603 BEGIN_RING(chan
, celsius
, NV10TCL_BLEND_FUNC_ENABLE
, 1);
607 #if !defined(__AROS__)
609 NV10StateCompositeReemit(struct nouveau_channel
*chan
)
611 ScrnInfoPtr pScrn
= chan
->user_private
;
612 NVPtr pNv
= NVPTR(pScrn
);
614 NV10EXAPrepareComposite(pNv
->alu
, pNv
->pspict
, pNv
->pmpict
, pNv
->pdpict
,
615 pNv
->pspix
, pNv
->pmpix
, pNv
->pdpix
);
620 NV10EXAPrepareComposite(int op
,
622 PicturePtr pict_mask
,
628 #if !defined(__AROS__)
629 ScrnInfoPtr pScrn
= xf86Screens
[dst
->drawable
.pScreen
->myNum
];
631 ScrnInfoPtr pScrn
= globalcarddataptr
;
633 NVPtr pNv
= NVPTR(pScrn
);
634 struct nouveau_channel
*chan
= pNv
->chan
;
636 if (MARK_RING(chan
, 128, 5))
639 #if !defined(__AROS__)
641 pNv
->pspict
= pict_src
;
642 pNv
->pmpict
= pict_mask
;
643 pNv
->pdpict
= pict_dst
;
650 if (!setup_render_target(pNv
, pict_dst
, dst
))
654 if (!setup_texture(pNv
, 0, pict_src
, src
))
657 /* Set mask format */
659 !setup_texture(pNv
, 1, pict_mask
, mask
))
662 #if !defined(__AROS__)
663 /* Set the register combiners up. */
664 setup_combiners(pNv
, pict_src
, pict_mask
);
667 setup_blend_function(pNv
);
669 chan
->flush_notify
= NV10StateCompositeReemit
;
671 /* Set the register combiners up. */
672 setup_combiners(pNv
, pict_src
, pict_mask
, op
);
675 setup_blend_function(pNv
, pict_dst
, pict_mask
, op
);
677 chan
->flush_notify
= NULL
;
688 #if defined(__AROS__)
689 /* WARNING: These defines are only used to hack QUAD/MAP/OUT_RINGi defines
690 in this use case. They WILL NOT work in generic case. DO NOT reuse them. */
695 typedef struct _PictVector PictVector
;
697 #define xFixedFrac(x) 0
698 #define xFixedToInt(x) (x)
699 #define IntToxFixed(x) (float)(x)
702 #define QUAD(x, y, w, h) \
703 {{{ IntToxFixed(x), IntToxFixed(y), xFixed1 }}, \
704 {{ IntToxFixed(x + w), IntToxFixed(y), xFixed1 }}, \
705 {{ IntToxFixed(x + w), IntToxFixed(y + h), xFixed1 }}, \
706 {{ IntToxFixed(x), IntToxFixed(y + h), xFixed1 }}}
708 #define MAP(f, p, v, ...) do { \
710 for (__i = 0; __i < sizeof(v)/sizeof((v)[0]); __i++) \
711 f(p, __i, v, ## __VA_ARGS__); \
714 #define xFixedToFloat(v) \
715 ((float)xFixedToInt((v)) + ((float)xFixedFrac(v) / 65536.0))
717 #define OUT_RINGi(chan, v, i) \
718 OUT_RINGf(chan, xFixedToFloat((v).vector[i]))
721 emit_vertex(NVPtr pNv
, int i
, PictVector pos
[],
722 PictVector tex0
[], PictVector tex1
[])
724 struct nouveau_channel
*chan
= pNv
->chan
;
725 struct nouveau_grobj
*celsius
= pNv
->Nv3D
;
727 BEGIN_RING(chan
, celsius
, NV10TCL_VERTEX_TX0_2F_S
, 2);
728 OUT_RINGi (chan
, tex0
[i
], 0);
729 OUT_RINGi (chan
, tex0
[i
], 1);
732 BEGIN_RING(chan
, celsius
, NV10TCL_VERTEX_TX1_2F_S
, 2);
733 OUT_RINGi (chan
, tex1
[i
], 0);
734 OUT_RINGi (chan
, tex1
[i
], 1);
737 BEGIN_RING(chan
, celsius
, NV10TCL_VERTEX_POS_3F_X
, 3);
738 OUT_RINGi (chan
, pos
[i
], 0);
739 OUT_RINGi (chan
, pos
[i
], 1);
743 #if !defined(__AROS__)
745 transform_vertex(PictTransformPtr t
, int i
, PictVector vs
[])
748 PictureTransformPoint(t
, &vs
[i
]);
752 NV10EXAComposite(PixmapPtr pix_dst
,
754 int maskX
, int maskY
,
756 int width
, int height
)
758 ScrnInfoPtr pScrn
= xf86Screens
[pix_dst
->drawable
.pScreen
->myNum
];
761 NV10EXAComposite(PixmapPtr pix_dst
,
763 int maskX
, int maskY
,
765 int width
, int height
,
766 PicturePtr src
, PicturePtr mask
)
768 ScrnInfoPtr pScrn
= globalcarddataptr
;
770 NVPtr pNv
= NVPTR(pScrn
);
771 struct nouveau_channel
*chan
= pNv
->chan
;
772 struct nouveau_grobj
*celsius
= pNv
->Nv3D
;
773 #if !defined(__AROS__)
774 PicturePtr mask
= pNv
->pmpict
,
777 PictVector dstq
[4] = QUAD(dstX
, dstY
, width
, height
),
778 maskq
[4] = QUAD(maskX
, maskY
, width
, height
),
779 srcq
[4] = QUAD(srcX
, srcY
, width
, height
);
781 #if !defined(__AROS__)
782 /* We are not doing any transformations */
783 MAP(transform_vertex
, src
->transform
, srcq
);
785 MAP(transform_vertex
, mask
->transform
, maskq
);
788 WAIT_RING (chan
, 64);
789 BEGIN_RING(chan
, celsius
, NV10TCL_VERTEX_BEGIN_END
, 1);
790 OUT_RING (chan
, NV10TCL_VERTEX_BEGIN_END_QUADS
);
792 MAP(emit_vertex
, pNv
, dstq
, srcq
, mask
? maskq
: NULL
);
794 BEGIN_RING(chan
, celsius
, NV10TCL_VERTEX_BEGIN_END
, 1);
795 OUT_RING (chan
, NV10TCL_VERTEX_BEGIN_END_STOP
);
798 #if !defined(__AROS__)
800 NV10EXADoneComposite(PixmapPtr dst
)
802 ScrnInfoPtr pScrn
= xf86Screens
[dst
->drawable
.pScreen
->myNum
];
803 NVPtr pNv
= NVPTR(pScrn
);
804 struct nouveau_channel
*chan
= pNv
->chan
;
806 chan
->flush_notify
= NULL
;
811 NVAccelInitNV10TCL(ScrnInfoPtr pScrn
)
813 NVPtr pNv
= NVPTR(pScrn
);
814 struct nouveau_channel
*chan
= pNv
->chan
;
815 struct nouveau_grobj
*celsius
;
819 if (((pNv
->dev
->chipset
& 0xf0) != NV_ARCH_10
) &&
820 ((pNv
->dev
->chipset
& 0xf0) != NV_ARCH_20
))
823 if (pNv
->dev
->chipset
>= 0x20 || pNv
->dev
->chipset
== 0x1a)
825 else if (pNv
->dev
->chipset
>= 0x17)
827 else if (pNv
->dev
->chipset
>= 0x11)
833 if (nouveau_grobj_alloc(pNv
->chan
, Nv3D
, class, &pNv
->Nv3D
))
838 BEGIN_RING(chan
, celsius
, NV10TCL_DMA_NOTIFY
, 1);
839 OUT_RING (chan
, chan
->nullobj
->handle
);
841 BEGIN_RING(chan
, celsius
, NV10TCL_DMA_IN_MEMORY0
, 2);
842 OUT_RING (chan
, pNv
->chan
->vram
->handle
);
843 OUT_RING (chan
, pNv
->chan
->gart
->handle
);
845 BEGIN_RING(chan
, celsius
, NV10TCL_DMA_IN_MEMORY2
, 2);
846 OUT_RING (chan
, pNv
->chan
->vram
->handle
);
847 OUT_RING (chan
, pNv
->chan
->vram
->handle
);
849 BEGIN_RING(chan
, celsius
, NV10TCL_NOP
, 1);
852 BEGIN_RING(chan
, celsius
, NV10TCL_RT_HORIZ
, 2);
853 OUT_RING (chan
, 2048 << 16 | 0);
854 OUT_RING (chan
, 2048 << 16 | 0);
856 BEGIN_RING(chan
, celsius
, NV10TCL_ZETA_OFFSET
, 1);
859 BEGIN_RING(chan
, celsius
, NV10TCL_VIEWPORT_CLIP_MODE
, 1);
862 BEGIN_RING(chan
, celsius
, NV10TCL_VIEWPORT_CLIP_HORIZ(0), 1);
863 OUT_RING (chan
, 0x7ff << 16 | 0x800800);
864 BEGIN_RING(chan
, celsius
, NV10TCL_VIEWPORT_CLIP_VERT(0), 1);
865 OUT_RING (chan
, 0x7ff << 16 | 0x800800);
867 for (i
= 1; i
< 8; i
++) {
868 BEGIN_RING(chan
, celsius
, NV10TCL_VIEWPORT_CLIP_HORIZ(i
), 1);
870 BEGIN_RING(chan
, celsius
, NV10TCL_VIEWPORT_CLIP_VERT(i
), 1);
874 BEGIN_RING(chan
, celsius
, 0x290, 1);
875 OUT_RING (chan
, (0x10<<16)|1);
876 BEGIN_RING(chan
, celsius
, 0x3f4, 1);
879 BEGIN_RING(chan
, celsius
, NV10TCL_NOP
, 1);
882 if (class != NV10TCL
) {
884 BEGIN_RING(chan
, celsius
, 0x120, 3);
889 BEGIN_RING(chan
, pNv
->NvImageBlit
, 0x120, 3);
894 BEGIN_RING(chan
, celsius
, NV10TCL_NOP
, 1);
898 BEGIN_RING(chan
, celsius
, NV10TCL_NOP
, 1);
902 BEGIN_RING(chan
, celsius
, NV10TCL_FOG_ENABLE
, 1);
904 BEGIN_RING(chan
, celsius
, NV10TCL_ALPHA_FUNC_ENABLE
, 1);
906 BEGIN_RING(chan
, celsius
, NV10TCL_ALPHA_FUNC_FUNC
, 2);
907 OUT_RING (chan
, 0x207);
909 BEGIN_RING(chan
, celsius
, NV10TCL_TX_ENABLE(0), 2);
912 BEGIN_RING(chan
, celsius
, NV10TCL_RC_IN_ALPHA(0), 6);
919 BEGIN_RING(chan
, celsius
, NV10TCL_RC_OUT_ALPHA(0), 6);
920 OUT_RING (chan
, 0x00000c00);
922 OUT_RING (chan
, 0x00000c00);
923 OUT_RING (chan
, 0x18000000);
924 OUT_RING (chan
, 0x300c0000);
925 OUT_RING (chan
, 0x00001c80);
926 BEGIN_RING(chan
, celsius
, NV10TCL_BLEND_FUNC_ENABLE
, 1);
928 BEGIN_RING(chan
, celsius
, NV10TCL_DITHER_ENABLE
, 2);
931 BEGIN_RING(chan
, celsius
, NV10TCL_LINE_SMOOTH_ENABLE
, 1);
933 BEGIN_RING(chan
, celsius
, NV10TCL_VERTEX_WEIGHT_ENABLE
, 2);
936 BEGIN_RING(chan
, celsius
, NV10TCL_BLEND_FUNC_SRC
, 4);
940 OUT_RING (chan
, 0x8006);
941 BEGIN_RING(chan
, celsius
, NV10TCL_STENCIL_MASK
, 8);
942 OUT_RING (chan
, 0xff);
943 OUT_RING (chan
, 0x207);
945 OUT_RING (chan
, 0xff);
946 OUT_RING (chan
, 0x1e00);
947 OUT_RING (chan
, 0x1e00);
948 OUT_RING (chan
, 0x1e00);
949 OUT_RING (chan
, 0x1d01);
950 BEGIN_RING(chan
, celsius
, NV10TCL_NORMALIZE_ENABLE
, 1);
952 BEGIN_RING(chan
, celsius
, NV10TCL_FOG_ENABLE
, 2);
955 BEGIN_RING(chan
, celsius
, NV10TCL_LIGHT_MODEL
, 1);
957 BEGIN_RING(chan
, celsius
, NV10TCL_SEPARATE_SPECULAR_ENABLE
, 1);
959 BEGIN_RING(chan
, celsius
, NV10TCL_ENABLED_LIGHTS
, 1);
961 BEGIN_RING(chan
, celsius
, NV10TCL_POLYGON_OFFSET_POINT_ENABLE
, 3);
965 BEGIN_RING(chan
, celsius
, NV10TCL_DEPTH_FUNC
, 1);
966 OUT_RING (chan
, 0x201);
967 BEGIN_RING(chan
, celsius
, NV10TCL_DEPTH_WRITE_ENABLE
, 1);
969 BEGIN_RING(chan
, celsius
, NV10TCL_DEPTH_TEST_ENABLE
, 1);
971 BEGIN_RING(chan
, celsius
, NV10TCL_POLYGON_OFFSET_FACTOR
, 2);
974 BEGIN_RING(chan
, celsius
, NV10TCL_POINT_SIZE
, 1);
976 BEGIN_RING(chan
, celsius
, NV10TCL_POINT_PARAMETERS_ENABLE
, 2);
979 BEGIN_RING(chan
, celsius
, NV10TCL_LINE_WIDTH
, 1);
981 BEGIN_RING(chan
, celsius
, NV10TCL_LINE_SMOOTH_ENABLE
, 1);
983 BEGIN_RING(chan
, celsius
, NV10TCL_POLYGON_MODE_FRONT
, 2);
984 OUT_RING (chan
, 0x1b02);
985 OUT_RING (chan
, 0x1b02);
986 BEGIN_RING(chan
, celsius
, NV10TCL_CULL_FACE
, 2);
987 OUT_RING (chan
, 0x405);
988 OUT_RING (chan
, 0x901);
989 BEGIN_RING(chan
, celsius
, NV10TCL_POLYGON_SMOOTH_ENABLE
, 1);
991 BEGIN_RING(chan
, celsius
, NV10TCL_CULL_FACE_ENABLE
, 1);
993 BEGIN_RING(chan
, celsius
, NV10TCL_TX_GEN_MODE_S(0), 8);
994 for (i
= 0; i
< 8; i
++)
997 BEGIN_RING(chan
, celsius
, NV10TCL_FOG_EQUATION_CONSTANT
, 3);
998 OUT_RING (chan
, 0x3fc00000); /* -1.50 */
999 OUT_RING (chan
, 0xbdb8aa0a); /* -0.09 */
1000 OUT_RING (chan
, 0); /* 0.00 */
1002 BEGIN_RING(chan
, celsius
, NV10TCL_NOP
, 1);
1005 BEGIN_RING(chan
, celsius
, NV10TCL_FOG_MODE
, 2);
1006 OUT_RING (chan
, 0x802);
1008 /* for some reason VIEW_MATRIX_ENABLE need to be 6 instead of 4 when
1009 * using texturing, except when using the texture matrix
1011 BEGIN_RING(chan
, celsius
, NV10TCL_VIEW_MATRIX_ENABLE
, 1);
1013 BEGIN_RING(chan
, celsius
, NV10TCL_COLOR_MASK
, 1);
1014 OUT_RING (chan
, 0x01010101);
1016 BEGIN_RING(chan
, celsius
, NV10TCL_PROJECTION_MATRIX(0), 16);
1017 for(i
= 0; i
< 16; i
++)
1018 OUT_RINGf(chan
, i
/4 == i
%4 ? 1.0 : 0.0);
1020 BEGIN_RING(chan
, celsius
, NV10TCL_DEPTH_RANGE_NEAR
, 2);
1022 OUT_RINGf (chan
, 65536.0);
1024 BEGIN_RING(chan
, celsius
, NV10TCL_VIEWPORT_TRANSLATE_X
, 4);
1025 OUT_RINGf (chan
, -2048.0);
1026 OUT_RINGf (chan
, -2048.0);
1027 OUT_RINGf (chan
, 0);
1030 /* Set vertex component */
1031 BEGIN_RING(chan
, celsius
, NV10TCL_VERTEX_COL_4F_R
, 4);
1032 OUT_RINGf (chan
, 1.0);
1033 OUT_RINGf (chan
, 1.0);
1034 OUT_RINGf (chan
, 1.0);
1035 OUT_RINGf (chan
, 1.0);
1036 BEGIN_RING(chan
, celsius
, NV10TCL_VERTEX_COL2_3F_R
, 3);
1040 BEGIN_RING(chan
, celsius
, NV10TCL_VERTEX_NOR_3F_X
, 3);
1043 OUT_RINGf (chan
, 1.0);
1044 BEGIN_RING(chan
, celsius
, NV10TCL_VERTEX_TX0_4F_S
, 4);
1045 OUT_RINGf (chan
, 0.0);
1046 OUT_RINGf (chan
, 0.0);
1047 OUT_RINGf (chan
, 0.0);
1048 OUT_RINGf (chan
, 1.0);
1049 BEGIN_RING(chan
, celsius
, NV10TCL_VERTEX_TX1_4F_S
, 4);
1050 OUT_RINGf (chan
, 0.0);
1051 OUT_RINGf (chan
, 0.0);
1052 OUT_RINGf (chan
, 0.0);
1053 OUT_RINGf (chan
, 1.0);
1054 BEGIN_RING(chan
, celsius
, NV10TCL_VERTEX_FOG_1F
, 1);
1055 OUT_RINGf (chan
, 0.0);
1056 BEGIN_RING(chan
, celsius
, NV10TCL_EDGEFLAG_ENABLE
, 1);
1064 /* NOTE: Assumes lock on bitmap is already made */
1065 /* NOTE: Assumes buffer is not mapped */
1066 /* NOTE: Allows different formats of source and destination */
1067 BOOL
HIDDNouveauNV103DCopyBox(struct CardData
* carddata
,
1068 struct HIDDNouveauBitMapData
* srcdata
, struct HIDDNouveauBitMapData
* destdata
,
1069 LONG srcX
, LONG srcY
, LONG destX
, LONG destY
, LONG width
, LONG height
,
1072 struct Picture sPict
, dPict
;
1073 LONG maskX
= 0; LONG maskY
= 0;
1075 HIDDNouveauFillPictureFromBitMapData(&sPict
, srcdata
);
1076 HIDDNouveauFillPictureFromBitMapData(&dPict
, destdata
);
1078 if (NV10EXAPrepareComposite(blendop
,
1079 &sPict
, NULL
, &dPict
, srcdata
, NULL
, destdata
))
1081 NV10EXAComposite(destdata
, srcX
, srcY
,
1084 width
, height
, &sPict
, NULL
);