2 * Copyright 2007 Stephane Marchesin
3 * Copyright 2007 Arthur Huillet
4 * Copyright 2007 Peter Winters
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
21 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 #include "nv_include.h"
31 typedef struct nv10_exa_state {
33 Bool is_a8_plus_a8; /*as known as is_extremely_dirty :)*/
35 PictTransformPtr transform;
40 static nv10_exa_state_t state;
42 static int NV10TexFormat(int ExaFormat)
44 struct {int exa;int hw;} tex_format[] =
46 {PICT_a8r8g8b8, 0x900},
47 {PICT_x8r8g8b8, 0x900},
48 {PICT_r5g6b5, 0x880}, //this one was only tested with rendercheck
49 //{PICT_a1r5g5b5, NV10_TCL_PRIMITIVE_3D_TX_FORMAT_FORMAT_R5G5B5A1},
50 //{PICT_a4r4g4b4, NV10_TCL_PRIMITIVE_3D_TX_FORMAT_FORMAT_R4G4B4A4},
52 // FIXME other formats
56 for(i=0;i<sizeof(tex_format)/sizeof(tex_format[0]);i++)
58 if(tex_format[i].exa==ExaFormat)
59 return tex_format[i].hw;
65 static int NV10DstFormat(int ExaFormat)
67 struct {int exa;int hw;} dst_format[] =
69 {PICT_a8r8g8b8, 0x108},
70 {PICT_x8r8g8b8, 0x108}, //FIXME blending factors?
72 // FIXME other formats
76 for(i=0;i<sizeof(dst_format)/sizeof(dst_format[0]);i++)
78 if(dst_format[i].exa==ExaFormat)
79 return dst_format[i].hw;
85 static Bool NV10CheckTexture(PicturePtr Picture)
87 int w = Picture->pDrawable->width;
88 int h = Picture->pDrawable->height;
90 if ((w > 2046) || (h>2046))
92 if (!NV10TexFormat(Picture->format))
94 if (Picture->filter != PictFilterNearest && Picture->filter != PictFilterBilinear)
96 if (Picture->componentAlpha)
98 /* we cannot repeat on NV10 because NPOT textures do not support this. unfortunately. */
99 if (Picture->repeat != RepeatNone)
100 /* we can repeat 1x1 textures */
101 if (!(w == 1 && h == 1))
106 static Bool NV10CheckBuffer(PicturePtr Picture)
108 int w = Picture->pDrawable->width;
109 int h = Picture->pDrawable->height;
111 if ((w > 4096) || (h>4096))
113 if (Picture->componentAlpha) //this is used by rendercheck CA composite tests. not sure about real-life.
115 if (!NV10DstFormat(Picture->format))
120 static Bool NV10CheckPictOp(int op)
122 if ( op == PictOpAtopReverse ) /*this op doesn't work right now*/
126 if ( op >= PictOpSaturate )
127 { //we do no saturate, disjoint, conjoint, though we could do e.g. DisjointClear which really is Clear
133 /* Check if the current operation is a doable A8 + A8 */
134 /* A8 destination is a special case, because we do it by having the card think
135 it's ARGB. For now we support PictOpAdd which is the only important op for this dst format,
136 and without transformation or funny things.*/
137 static Bool NV10CheckA8_PLUS_A8_FEASABILITY(PicturePtr src, PicturePtr msk, PicturePtr dst, int op)
139 /*This does not work quite well yet so we fallback*/
142 if ((!msk) && (src->format == PICT_a8) && (dst->format == PICT_a8) && (!src->transform) &&
143 ((op == PictOpAdd) || (op == PictOpSrc) || (op == PictOpClear) || (op == PictOpDst)) && (src->repeat == RepeatNone))
151 #define NV10EXAFallbackInfo(X,Y,Z,S,T) NV10EXAFallbackInfo_real(X,Y,Z,S,T)
153 #define NV10EXAFallbackInfo(X,Y,Z,S,T) do { ; } while (0)
156 static void NV10EXAFallbackInfo_real(char * reason, int op, PicturePtr pSrcPicture,
157 PicturePtr pMaskPicture,
158 PicturePtr pDstPicture)
162 sprintf(out, "%s ", reason);
163 out = out + strlen(out);
167 sprintf(out, "PictOpClear ");
170 sprintf(out, "PictOpSrc ");
173 sprintf(out, "PictOpDst ");
176 sprintf(out, "PictOpOver ");
178 case PictOpOutReverse:
179 sprintf(out, "PictOpOutReverse ");
182 sprintf(out, "PictOpAdd ");
185 sprintf(out, "PictOp%d ", op);
187 out = out + strlen(out);
188 switch ( pSrcPicture->format )
191 sprintf(out, "A8R8G8B8 ");
194 sprintf(out, "X8R8G8B8 ");
197 sprintf(out, "X8B8G8R8 ");
200 sprintf(out, "R5G6B5 ");
209 sprintf(out, "%x ", pSrcPicture->format);
212 sprintf(out, "(%dx%d) ", pSrcPicture->pDrawable->width, pSrcPicture->pDrawable->height);
213 if ( pSrcPicture->repeat != RepeatNone )
218 switch ( pDstPicture->format )
221 sprintf(out, "A8R8G8B8 ");
224 sprintf(out, "X8R8G8B8 ");
227 sprintf(out, "X8B8G8R8 ");
230 sprintf(out, "R5G6B5 ");
239 sprintf(out, "%x ", pDstPicture->format);
242 sprintf(out, "(%dx%d) ", pDstPicture->pDrawable->width, pDstPicture->pDrawable->height);
243 if ( pDstPicture->repeat != RepeatNone )
247 sprintf(out, "& NONE");
249 switch ( pMaskPicture->format )
252 sprintf(out, "& A8R8G8B8 ");
255 sprintf(out, "& X8R8G8B8 ");
258 sprintf(out, "& X8B8G8R8 ");
261 sprintf(out, "& A8 ");
264 sprintf(out, "& A1 ");
267 sprintf(out, "& %x ", pMaskPicture->format);
270 sprintf(out, "(%dx%d) ", pMaskPicture->pDrawable->width, pMaskPicture->pDrawable->height);
271 if ( pMaskPicture->repeat != RepeatNone )
276 xf86DrvMsg(0, X_INFO, out2);
280 Bool NV10CheckComposite(int op,
281 PicturePtr pSrcPicture,
282 PicturePtr pMaskPicture,
283 PicturePtr pDstPicture)
286 if (NV10CheckA8_PLUS_A8_FEASABILITY(pSrcPicture,pMaskPicture,pDstPicture,op))
287 { //A8 destination hack is OK ? - disabled by default anyway
288 NV10EXAFallbackInfo("Hackelerating", op, pSrcPicture, pMaskPicture, pDstPicture);
292 if (!NV10CheckPictOp(op))
294 NV10EXAFallbackInfo("pictop", op, pSrcPicture, pMaskPicture, pDstPicture);
297 if (!NV10CheckBuffer(pDstPicture))
299 NV10EXAFallbackInfo("dst", op, pSrcPicture, pMaskPicture, pDstPicture);
303 if (!NV10CheckTexture(pSrcPicture))
305 NV10EXAFallbackInfo("src", op, pSrcPicture, pMaskPicture, pDstPicture);
309 if ((pMaskPicture) &&(!NV10CheckTexture(pMaskPicture)))
311 NV10EXAFallbackInfo("mask", op, pSrcPicture, pMaskPicture, pDstPicture);
315 NV10EXAFallbackInfo("Accelerating", op, pSrcPicture, pMaskPicture, pDstPicture);
319 static void NV10SetTexture(NVPtr pNv,int unit,PicturePtr Pict,PixmapPtr pixmap)
321 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_TX_OFFSET(unit), 1 );
322 OUT_RING (NVAccelGetPixmapOffset(pixmap));
323 int log2w = log2i(Pict->pDrawable->width);
324 int log2h = log2i(Pict->pDrawable->height);
327 (NV10_TCL_PRIMITIVE_3D_TX_FORMAT_WRAP_T_CLAMP_TO_EDGE) |
328 (NV10_TCL_PRIMITIVE_3D_TX_FORMAT_WRAP_S_CLAMP_TO_EDGE) |
331 (1<<12) | /* lod == 1 */
334 /* if repeat is set we're always handling a 1x1 texture with ARGB/XRGB destination, in that case we change the format
335 to use the POT (swizzled) matching format */
336 if (Pict->repeat != RepeatNone)
338 if (Pict->format == PICT_a8)
339 txfmt |= 0x80; /* A8 */
340 else if (Pict->format == PICT_r5g6b5 )
341 txfmt |= 0x280; /* R5G6B5 */
343 txfmt |= 0x300; /* ARGB format */
347 if ( ! state.is_a8_plus_a8 )
349 txfmt |= NV10TexFormat(Pict->format);
350 w = Pict->pDrawable->width;
351 /* NPOT_SIZE expects an even number for width, we can round up uneven
352 * numbers here because EXA always gives 64 byte aligned pixmaps
353 * and for all formats we support 64 bytes represents an even number
359 txfmt |= NV10TexFormat(PICT_a8r8g8b8);
360 w = (exaGetPixmapPitch(pixmap)) >> 2;
363 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_TX_NPOT_PITCH(unit), 1);
364 OUT_RING (exaGetPixmapPitch(pixmap) << 16);
366 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_TX_NPOT_SIZE(unit), 1);
367 OUT_RING ((w<<16) | Pict->pDrawable->height);
370 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_TX_FORMAT(unit), 1 );
373 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_TX_ENABLE(unit), 1 );
374 OUT_RING (NV10_TCL_PRIMITIVE_3D_TX_ENABLE_ENABLE);
376 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_TX_FILTER(unit), 1);
377 if (Pict->filter == PictFilterNearest)
378 OUT_RING ((NV10_TCL_PRIMITIVE_3D_TX_FILTER_MAGNIFY_NEAREST) |
379 (NV10_TCL_PRIMITIVE_3D_TX_FILTER_MINIFY_NEAREST));
381 OUT_RING ((NV10_TCL_PRIMITIVE_3D_TX_FILTER_MAGNIFY_LINEAR) |
382 (NV10_TCL_PRIMITIVE_3D_TX_FILTER_MINIFY_LINEAR));
384 state.unit[unit].width = (float)pixmap->drawable.width;
385 state.unit[unit].height = (float)pixmap->drawable.height;
386 state.unit[unit].transform = Pict->transform;
389 static void NV10SetBuffer(NVPtr pNv,PicturePtr Pict,PixmapPtr pixmap)
397 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_BUFFER_FORMAT, 4);
398 if ( state.is_a8_plus_a8 )
400 OUT_RING (NV10DstFormat(PICT_a8r8g8b8));
403 OUT_RING (NV10DstFormat(Pict->format));
406 OUT_RING (((uint32_t)exaGetPixmapPitch(pixmap) << 16) |(uint32_t)exaGetPixmapPitch(pixmap));
407 OUT_RING (NVAccelGetPixmapOffset(pixmap));
410 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 2);
411 OUT_RING ((w<<16)|x);
412 OUT_RING ((h<<16)|y);
413 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_MODE, 1); /* clip_mode */
415 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 1);
416 OUT_RING (((w-1+x)<<16)|x|0x08000800);
417 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(0), 1);
418 OUT_RING (((h-1+y)<<16)|y|0x08000800);
420 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_PROJECTION_MATRIX(0), 16);
427 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR, 2);
430 OUT_RINGf (16777216.0);
434 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_X, 4);
441 static void NV10SetRegCombs(NVPtr pNv, PicturePtr src, PicturePtr mask)
443 /*This can be a bit difficult to understand at first glance.
444 Reg combiners are described here:
445 http://icps.u-strasbg.fr/~marchesin/perso/extensions/NV/register_combiners.html
447 Single texturing setup, without honoring vertex colors (non default setup) is:
448 Alpha RC 0 : a_0 * 1 + 0 * 0
449 RGB RC 0 : rgb_0 * 1 + 0 * 0
452 Default setup uses vertex rgb/alpha in place of 1s above, but we don't need that in 2D.
454 Multi texturing setup, where we do TEX0 in TEX1 (masking) is:
455 Alpha RC 0 : a_0 * a_1 + 0 * 0
456 RGB RC0 : rgb_0 * a_1 + 0 * 0
461 unsigned int rc0_in_alpha = 0, rc0_in_rgb = 0;
462 unsigned int rc1_in_alpha = 0, rc1_in_rgb = 0;
464 #define A_ALPHA_ZERO (NV10_TCL_PRIMITIVE_3D_RC_IN_ALPHA_A_INPUT_ZERO | NV10_TCL_PRIMITIVE_3D_RC_IN_ALPHA_A_COMPONENT_USAGE_ALPHA)
465 #define B_ALPHA_ZERO (NV10_TCL_PRIMITIVE_3D_RC_IN_ALPHA_B_INPUT_ZERO | NV10_TCL_PRIMITIVE_3D_RC_IN_ALPHA_B_COMPONENT_USAGE_ALPHA)
466 #define C_ALPHA_ZERO (NV10_TCL_PRIMITIVE_3D_RC_IN_ALPHA_C_INPUT_ZERO | NV10_TCL_PRIMITIVE_3D_RC_IN_ALPHA_C_COMPONENT_USAGE_ALPHA)
467 #define D_ALPHA_ZERO (NV10_TCL_PRIMITIVE_3D_RC_IN_ALPHA_D_INPUT_ZERO | NV10_TCL_PRIMITIVE_3D_RC_IN_ALPHA_D_COMPONENT_USAGE_ALPHA)
469 #define A_ALPHA_ONE (A_ALPHA_ZERO | (NV10_TCL_PRIMITIVE_3D_RC_IN_ALPHA_A_MAPPING_UNSIGNED_INVERT_NV))
470 #define B_ALPHA_ONE (B_ALPHA_ZERO | (NV10_TCL_PRIMITIVE_3D_RC_IN_ALPHA_B_MAPPING_UNSIGNED_INVERT_NV))
471 #define C_ALPHA_ONE (C_ALPHA_ZERO | (NV10_TCL_PRIMITIVE_3D_RC_IN_ALPHA_C_MAPPING_UNSIGNED_INVERT_NV))
472 #define D_ALPHA_ONE (D_ALPHA_ZERO | (NV10_TCL_PRIMITIVE_3D_RC_IN_ALPHA_D_MAPPING_UNSIGNED_INVERT_NV))
474 #define A_RGB_ZERO (NV10_TCL_PRIMITIVE_3D_RC_IN_RGB_A_INPUT_ZERO | NV10_TCL_PRIMITIVE_3D_RC_IN_RGB_A_COMPONENT_USAGE_RGB)
475 #define B_RGB_ZERO (NV10_TCL_PRIMITIVE_3D_RC_IN_RGB_B_INPUT_ZERO | NV10_TCL_PRIMITIVE_3D_RC_IN_RGB_B_COMPONENT_USAGE_RGB)
476 #define C_RGB_ZERO (NV10_TCL_PRIMITIVE_3D_RC_IN_RGB_C_INPUT_ZERO | NV10_TCL_PRIMITIVE_3D_RC_IN_RGB_C_COMPONENT_USAGE_RGB)
477 #define D_RGB_ZERO (NV10_TCL_PRIMITIVE_3D_RC_IN_RGB_D_INPUT_ZERO | NV10_TCL_PRIMITIVE_3D_RC_IN_RGB_D_COMPONENT_USAGE_RGB)
479 #define A_RGB_ONE (A_RGB_ZERO | NV10_TCL_PRIMITIVE_3D_RC_IN_RGB_A_MAPPING_UNSIGNED_INVERT_NV)
480 #define B_RGB_ONE (B_RGB_ZERO | NV10_TCL_PRIMITIVE_3D_RC_IN_RGB_B_MAPPING_UNSIGNED_INVERT_NV)
481 #define C_RGB_ONE (C_RGB_ZERO | NV10_TCL_PRIMITIVE_3D_RC_IN_RGB_C_MAPPING_UNSIGNED_INVERT_NV)
482 #define D_RGB_ONE (D_RGB_ZERO | NV10_TCL_PRIMITIVE_3D_RC_IN_RGB_D_MAPPING_UNSIGNED_INVERT_NV)
485 rc0_in_alpha |= C_ALPHA_ZERO | D_ALPHA_ZERO;
486 if (src->format == PICT_x8r8g8b8)
487 rc0_in_alpha |= A_ALPHA_ONE; //A = alpha = 1 everywhere
489 rc0_in_alpha |= 0x18000000; //A = a_0, use texture 0 alpha value
492 rc0_in_alpha |= B_ALPHA_ONE;
494 if ( mask->format == PICT_x8r8g8b8 ) //no alpha? ignore it
495 rc0_in_alpha |= B_ALPHA_ONE;
497 rc0_in_alpha |= 0x00190000; //B = a_1, use texture 1 alpha value
499 rc0_in_rgb |= C_RGB_ZERO | D_RGB_ZERO;
500 if (src->format == PICT_a8 )
501 rc0_in_rgb |= A_RGB_ZERO;
503 rc0_in_rgb |= 0x08000000; //A = rgb_0, use texture 0 rgb
506 rc0_in_rgb |= B_RGB_ONE;
508 if ( mask->format == PICT_x8r8g8b8 ) //no alpha? ignore it
509 rc0_in_rgb |= B_RGB_ONE;
511 rc0_in_rgb |= 0x00190000; //B = a_1, use texture 1 alpha value
513 if ( state.is_a8_plus_a8 )
515 rc0_in_alpha = 0x18000000 | B_ALPHA_ONE | C_ALPHA_ZERO | D_ALPHA_ZERO; //A = a_0, use texture 0 alpha value
516 rc0_in_rgb = 0x08000000 | B_RGB_ONE | C_RGB_ZERO | D_RGB_ZERO; //A = rgb_0, use texture 0 rgb
519 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_RC_IN_ALPHA(0), 12);
520 OUT_RING(rc0_in_alpha);
521 OUT_RING (rc1_in_alpha);
522 OUT_RING (rc0_in_rgb);
523 OUT_RING (rc1_in_rgb);
524 OUT_RING (0); /*COLOR 0*/
525 OUT_RING (0); /*COLOR 1*/
526 OUT_RING (0x00000c00);
528 OUT_RING (0x000010cd);
529 OUT_RING (0x18000000);
530 OUT_RING (0x300e0300);
531 OUT_RING (0x0c091c80);
534 static void NV10SetPictOp(NVPtr pNv,int op, int sf, int df)
536 struct {int src;int dst;} pictops[] =
538 {0x0000,0x0000}, // PictOpClear
539 {0x0001,0x0000}, // PictOpSrc
540 {0x0000,0x0001}, // PictOpDst
541 {0x0001,0x0303}, // PictOpOver
542 {0x0305,0x0001}, // PictOpOverReverse
543 {0x0304,0x0000}, // PictOpIn
544 {0x0000,0x0302}, // PictOpInReverse
545 {0x0305,0x0000}, // PictOpOut
546 {0x0000,0x0303}, // PictOpOutReverse
547 {0x0304,0x0303}, // PictOpAtop
548 {0x0305,0x0302}, // PictOpAtopReverse
549 {0x0305,0x0303}, // PictOpXor
550 {0x0001,0x0001}, // PictOpAdd
553 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC, 2);
554 OUT_RING (pictops[op].src);
555 OUT_RING (pictops[op].dst);
556 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE, 1);
560 Bool NV10PrepareComposite(int op,
561 PicturePtr pSrcPicture,
562 PicturePtr pMaskPicture,
563 PicturePtr pDstPicture,
568 ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
569 NVPtr pNv = NVPTR(pScrn);
571 if (NV10CheckA8_PLUS_A8_FEASABILITY(pSrcPicture,pMaskPicture,pDstPicture,op))
572 { //is this our A8 + A8 hack?
573 state.have_mask = FALSE;
574 state.is_a8_plus_a8 = TRUE;
575 NV10SetBuffer(pNv,pDstPicture,pDst);
576 NV10SetTexture(pNv,0,pSrcPicture,pSrc);
577 NV10SetRegCombs(pNv, pSrcPicture, pMaskPicture);
578 NV10SetPictOp(pNv, op, PICT_r5g6b5, PICT_r5g6b5);
579 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_BEGIN_END, 1);
580 OUT_RING (NV10_TCL_PRIMITIVE_3D_VERTEX_BEGIN_END_QUADS);
584 state.is_a8_plus_a8 = FALSE;
587 NV10SetBuffer(pNv,pDstPicture,pDst);
590 NV10SetTexture(pNv,0,pSrcPicture,pSrc);
592 /* Set mask format */
594 NV10SetTexture(pNv,1,pMaskPicture,pMask);
596 NV10SetRegCombs(pNv, pSrcPicture, pMaskPicture);
599 NV10SetPictOp(pNv, op, pSrcPicture->format, pDstPicture->format);
601 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_BEGIN_END, 1);
602 OUT_RING (NV10_TCL_PRIMITIVE_3D_VERTEX_BEGIN_END_QUADS);
604 state.have_mask=(pMaskPicture!=NULL);
608 static inline void NV10Vertex(NVPtr pNv,float vx,float vy,float tx,float ty)
610 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_2F_S, 2);
613 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_POS_3F_X, 3);
619 static inline void NV10MVertex(NVPtr pNv,float vx,float vy,float t0x,float t0y,float t1x,float t1y)
621 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_2F_S, 2);
624 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_2F_S, 2);
627 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_POS_3F_X, 3);
633 #define xFixedToFloat(v) \
634 ((float)xFixedToInt((v)) + ((float)xFixedFrac(v) / 65536.0))
637 NV10EXATransformCoord(PictTransformPtr t, int x, int y, float sx, float sy,
638 float *x_ret, float *y_ret)
643 v.vector[0] = IntToxFixed(x);
644 v.vector[1] = IntToxFixed(y);
645 v.vector[2] = xFixed1;
646 PictureTransformPoint(t, &v);
647 *x_ret = xFixedToFloat(v.vector[0]);
648 *y_ret = xFixedToFloat(v.vector[1]);
656 void NV10Composite(PixmapPtr pDst,
666 ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
667 NVPtr pNv = NVPTR(pScrn);
668 float sX0, sX1, sY0, sY1;
669 float mX0, mX1, mY0, mY1;
671 if ( state.is_a8_plus_a8 )
673 //xf86DrvMsg(0, X_INFO, "Composite hack part - srcX %d srcY %d dstX %d dstY %d w %d h %d\n", srcX, srcY, dstX, dstY, width, height);
676 width = ((width + 3) &~ 3) >> 2;
679 NV10EXATransformCoord(state.unit[0].transform, srcX, srcY,
681 state.unit[0].height, &sX0, &sY0);
682 NV10EXATransformCoord(state.unit[0].transform,
683 srcX + width, srcY + height,
685 state.unit[0].height, &sX1, &sY1);
687 if (state.have_mask) {
688 NV10EXATransformCoord(state.unit[1].transform, maskX, maskY,
690 state.unit[1].height, &mX0, &mY0);
691 NV10EXATransformCoord(state.unit[1].transform,
692 maskX + width, maskY + height,
694 state.unit[1].height, &mX1, &mY1);
695 NV10MVertex(pNv , dstX , dstY,sX0 , sY0 , mX0 , mY0);
696 NV10MVertex(pNv , dstX + width , dstY,sX1 , sY0 , mX1 , mY0);
697 NV10MVertex(pNv , dstX + width , dstY + height,sX1 , sY1 , mX1 , mY1);
698 NV10MVertex(pNv , dstX , dstY + height,sX0 , sY1 , mX0 , mY1);
700 NV10Vertex(pNv , dstX , dstY , sX0 , sY0);
701 NV10Vertex(pNv , dstX + width , dstY , sX1 , sY0);
702 NV10Vertex(pNv , dstX + width , dstY + height , sX1 , sY1);
703 NV10Vertex(pNv , dstX , dstY + height , sX0 , sY1);
709 void NV10DoneComposite (PixmapPtr pDst)
711 ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
712 NVPtr pNv = NVPTR(pScrn);
714 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_BEGIN_END, 1);
715 OUT_RING (NV10_TCL_PRIMITIVE_3D_VERTEX_BEGIN_END_STOP);
717 exaMarkSync(pDst->drawable.pScreen);
722 NVAccelInitNV10TCL(ScrnInfoPtr pScrn)
724 NVPtr pNv = NVPTR(pScrn);
725 static int have_object = FALSE;
726 uint32_t class = 0, chipset;
729 chipset = (nvReadMC(pNv, 0) >> 20) & 0xff;
730 if ( ((chipset & 0xf0) != NV_ARCH_10) &&
731 ((chipset & 0xf0) != NV_ARCH_20) )
735 class = NV11_TCL_PRIMITIVE_3D;
736 else if (chipset>=0x17)
737 class = NV17_TCL_PRIMITIVE_3D;
738 else if (chipset>=0x11)
739 class = NV11_TCL_PRIMITIVE_3D;
741 class = NV10_TCL_PRIMITIVE_3D;
744 if (!NVDmaCreateContextObject(pNv, Nv3D, class))
749 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_DMA_NOTIFY, 1);
750 OUT_RING (NvNullObject);
752 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_DMA_IN_MEMORY0, 2);
756 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_DMA_IN_MEMORY2, 2);
760 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_NOP, 1);
763 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 2);
767 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 1);
768 OUT_RING ((0x7ff<<16)|0x800);
769 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(0), 1);
770 OUT_RING ((0x7ff<<16)|0x800);
773 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(i), 1);
775 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(i), 1);
779 BEGIN_RING(Nv3D, 0x290, 1);
780 OUT_RING ((0x10<<16)|1);
781 BEGIN_RING(Nv3D, 0x3f4, 1);
784 // BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_NOTIFY, 1);
786 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_NOP, 1);
789 if (class != NV10_TCL_PRIMITIVE_3D) {
791 BEGIN_RING(Nv3D, 0x120, 3);
796 BEGIN_RING(NvImageBlit, 0x120, 3);
801 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_NOP, 1);
805 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_NOP, 1);
809 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_FOG_ENABLE, 1);
811 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE, 1);
813 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC, 2);
816 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_TX_ENABLE(0), 2);
819 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_RC_IN_ALPHA(0), 12);
820 OUT_RING (0x30141010);
822 OUT_RING (0x20040000);
826 OUT_RING (0x00000c00);
828 OUT_RING (0x00000c00);
829 OUT_RING (0x18000000);
830 OUT_RING (0x300e0300);
831 OUT_RING (0x0c091c80);
832 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE, 1);
834 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_DITHER_ENABLE, 2);
837 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE, 1);
839 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_WEIGHT_ENABLE, 2);
842 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC, 4);
847 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_STENCIL_MASK, 8);
856 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE, 1);
858 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_FOG_ENABLE, 2);
861 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_LIGHT_MODEL, 1);
863 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_COLOR_CONTROL, 1);
865 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1);
867 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE, 3);
871 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_DEPTH_FUNC, 1);
873 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE, 1);
875 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE, 1);
877 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR, 2);
880 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_POINT_SIZE, 1);
882 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_POINT_PARAMETERS_ENABLE, 2);
885 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_LINE_WIDTH, 1);
887 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE, 1);
889 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT, 2);
892 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_CULL_FACE, 2);
895 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE, 1);
897 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE, 1);
899 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(0), 8);
903 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_FOG_EQUATION_CONSTANT, 3);
904 OUT_RING (0x3fc00000); /* -1.50 */
905 OUT_RING (0xbdb8aa0a); /* -0.09 */
906 OUT_RING (0); /* 0.00 */
908 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_NOP, 1);
911 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_FOG_MODE, 2);
914 /* for some reason VIEW_MATRIX_ENABLE need to be 6 instead of 4 when
915 * using texturing, except when using the texture matrix
917 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VIEW_MATRIX_ENABLE, 1);
919 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_COLOR_MASK, 1);
920 OUT_RING (0x01010101);
922 /* Set vertex component */
923 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_COL_4F_R, 4);
928 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_COL2_3F_R, 3);
932 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_NOR_3F_X, 3);
936 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_S, 4);
941 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_S, 4);
946 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_FOG_1F, 1);
948 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_EDGEFLAG_ENABLE, 1);