Remove division in NV30EXATransformCoord. We want coords between 0 and texture width...
[nouveau] / src / nv10_exa.c
1 #ifdef HAVE_CONFIG_H
2 #include "config.h"
3 #endif
4
5 #include "nv_include.h"
6
7 typedef struct nv10_exa_state {
8         Bool have_mask;
9
10         struct {
11                 PictTransformPtr transform;
12                 float width;
13                 float height;
14         } unit[2];
15 } nv10_exa_state_t;
16 static nv10_exa_state_t state;
17
18 static int NV10TexFormat(int ExaFormat)
19 {
20         struct {int exa;int hw;} tex_format[] =
21         {
22                 {PICT_a8r8g8b8, NV10_TCL_PRIMITIVE_3D_TX_FORMAT_FORMAT_R8G8B8A8},
23                 {PICT_a1r5g5b5, NV10_TCL_PRIMITIVE_3D_TX_FORMAT_FORMAT_R5G5B5A1},
24                 {PICT_a4r4g4b4, NV10_TCL_PRIMITIVE_3D_TX_FORMAT_FORMAT_R4G4B4A4},
25                 {PICT_a8,       NV10_TCL_PRIMITIVE_3D_TX_FORMAT_FORMAT_A8_RECT}
26                 // FIXME other formats
27         };
28
29         int i;
30         for(i=0;i<sizeof(tex_format)/sizeof(tex_format[0]);i++)
31         {
32                 if(tex_format[i].exa==ExaFormat)
33                         return tex_format[i].hw;
34         }
35
36         return 0;
37 }
38
39 static int NV10DstFormat(int ExaFormat)
40 {
41         struct {int exa;int hw;} dst_format[] =
42         {
43                 {PICT_a8r8g8b8, 0x108},
44                 {PICT_x8r8g8b8, 0x108}, // FIXME that one might need more
45                 {PICT_r5g6b5,   0x103}
46                 // FIXME other formats
47         };
48
49         int i;
50         for(i=0;i<sizeof(dst_format)/sizeof(dst_format[0]);i++)
51         {
52                 if(dst_format[i].exa==ExaFormat)
53                         return dst_format[i].hw;
54         }
55
56         return 0;
57 }
58
59 static Bool NV10CheckTexture(PicturePtr Picture)
60 {
61         int w = Picture->pDrawable->width;
62         int h = Picture->pDrawable->height;
63
64         if ((w > 2046) || (h>2046))
65                 return FALSE;
66         if (!NV10TexFormat(Picture->format))
67                 return FALSE;
68         if (Picture->filter != PictFilterNearest && Picture->filter != PictFilterBilinear)
69                 return FALSE;
70         if (Picture->repeat != RepeatNone)
71                 return FALSE;
72         return TRUE;
73 }
74
75 static Bool NV10CheckBuffer(PicturePtr Picture)
76 {
77         int w = Picture->pDrawable->width;
78         int h = Picture->pDrawable->height;
79
80         if ((w > 4096) || (h>4096))
81                 return FALSE;
82         if (!NV10DstFormat(Picture->format))
83                 return FALSE;
84         return TRUE;
85 }
86
87 static Bool NV10CheckComposite(int      op,
88                              PicturePtr pSrcPicture,
89                              PicturePtr pMaskPicture,
90                              PicturePtr pDstPicture)
91 {
92         // XXX A8 + A8 special case "TO BE DONE LATER"
93 /*      if ((!pMaskPicture) &&
94                         (pSrcPicture->format == PICT_a8) &&
95                         (pDstPicture->format == PICT_a8) )
96                 return TRUE;*/
97
98         if (!NV10CheckBuffer(pDstPicture))
99                 return FALSE;
100         if (!NV10CheckTexture(pSrcPicture))
101                 return FALSE;
102         if ((pMaskPicture)&&(!NV10CheckTexture(pMaskPicture)))
103                 return FALSE;
104
105         return TRUE;
106 }
107
108 static void NV10SetTexture(NVPtr pNv,int unit,PicturePtr Pict,PixmapPtr pixmap)
109 {
110         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_TX_OFFSET(unit), 1 );
111         NVDmaNext (pNv, NVAccelGetPixmapOffset(pixmap));
112
113         int log2w = log2i(Pict->pDrawable->width);
114         int log2h = log2i(Pict->pDrawable->height);
115         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_TX_FORMAT(unit), 1 );
116         NVDmaNext (pNv, (NV10_TCL_PRIMITIVE_3D_TX_FORMAT_WRAP_T_CLAMP_TO_EDGE<<28) |
117                         (NV10_TCL_PRIMITIVE_3D_TX_FORMAT_WRAP_S_CLAMP_TO_EDGE<<24) |
118                         (log2w<<20) |
119                         (log2h<<16) |
120                         (1<<12) | /* lod == 1 */
121                         (1<<11) | /* enable NPOT */
122                         (NV10TexFormat(Pict->format)<<7) |
123                         0x51 /* UNK */
124                         );
125
126         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_TX_ENABLE(unit), 1 );
127         NVDmaNext (pNv, 1);
128
129         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_TX_NPOT_PITCH(unit), 1);
130         NVDmaNext (pNv, exaGetPixmapPitch(pixmap) << 16);
131
132         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_TX_NPOT_SIZE(unit), 1);
133         NVDmaNext (pNv, (Pict->pDrawable->width<<16) | Pict->pDrawable->height); /* FIXME alignment restrictions, should be even at least */
134
135         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_TX_FILTER(unit), 1);
136         if (Pict->filter == PictFilterNearest)
137                 NVDmaNext (pNv, (NV10_TCL_PRIMITIVE_3D_TX_FILTER_MAG_FILTER_NEAREST<<28) |
138                                 (NV10_TCL_PRIMITIVE_3D_TX_FILTER_MIN_FILTER_NEAREST<<24));
139         else
140                 NVDmaNext (pNv, (NV10_TCL_PRIMITIVE_3D_TX_FILTER_MAG_FILTER_LINEAR<<28) |
141                                 (NV10_TCL_PRIMITIVE_3D_TX_FILTER_MIN_FILTER_LINEAR<<24));
142
143         state.unit[unit].width          = (float)pixmap->drawable.width;
144         state.unit[unit].height         = (float)pixmap->drawable.height;
145         state.unit[unit].transform      = Pict->transform;
146 }
147
148 static void NV10SetBuffer(NVPtr pNv,PicturePtr Pict,PixmapPtr pixmap)
149 {
150         int x = 0,y = 0,i;
151         int w = Pict->pDrawable->width;
152         int h = Pict->pDrawable->height;
153
154         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_BUFFER_FORMAT, 4);
155         NVDmaNext (pNv, NV10DstFormat(Pict->format));
156         NVDmaNext (pNv, ((uint32_t)exaGetPixmapPitch(pixmap) << 16) |(uint32_t)exaGetPixmapPitch(pixmap));
157         NVDmaNext (pNv, NVAccelGetPixmapOffset(pixmap));
158         NVDmaNext (pNv, 0);
159         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 2);
160         NVDmaNext (pNv, (w<<16)|x);
161         NVDmaNext (pNv, (h<<16)|y);
162         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_MODE, 1); /* clip_mode */
163         NVDmaNext (pNv, 0);
164         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 1);
165         NVDmaNext (pNv, ((w-1+x)<<16)|x|0x08000800);
166         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(0), 1);
167         NVDmaNext (pNv, ((h-1+y)<<16)|y|0x08000800);
168
169         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_PROJECTION_MATRIX(0), 16);
170         for(i=0;i<16;i++)
171                 if (i/4==i%4)
172                         NVDmaFloat(pNv, 1.0f);
173                 else
174                         NVDmaFloat(pNv, 0.0f);
175
176         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR, 2);
177         NVDmaNext (pNv, 0);
178 #if SCREEN_BPP == 32
179         NVDmaFloat (pNv, 16777216.0);
180 #else
181         NVDmaFloat (pNv, 65536.0);
182 #endif
183         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_X, 4);
184         NVDmaFloat (pNv, (w * 0.5) - 2048.0);
185         NVDmaFloat (pNv, (h * 0.5) - 2048.0);
186 #if SCREEN_BPP == 32
187         NVDmaFloat (pNv, 16777215.0 * 0.5);
188 #else
189         NVDmaFloat (pNv, 65535.0 * 0.5);
190 #endif
191         NVDmaNext (pNv, 0);
192 }
193
194 static void NV10SetMultitexture(NVPtr pNv,int multitex)
195 {
196         // FIXME
197         if (multitex)
198         {
199 /*
200 18141010    NV10_TCL_PRIMITIVE_3D.RC_IN_ALPHA[0] = D_INPUT=ZERO | D_COMPONENT_USAGE=ALPHA | D_MAPPING=UNSIGNED_IDENTITY_NV | C_INPUT=ZERO | C_COMPONENT_USAGE=ALPHA | C_MAPPING=UNSIGNED_IDENTITY_NV | B_INPUT=PRIMARY_COLOR_NV | B_COMPONENT_USAGE=ALPHA | B_MAPPING=UNSIGNED_IDENTITY_NV | A_INPUT=TEXTURE1_ARB | A_COMPONENT_USAGE=ALPHA | A_MAPPING=UNSIGNED_IDENTITY_NV
201 091c1010    NV10_TCL_PRIMITIVE_3D.RC_IN_ALPHA[1] = D_INPUT=ZERO | D_COMPONENT_USAGE=ALPHA | D_MAPPING=UNSIGNED_IDENTITY_NV | C_INPUT=ZERO | C_COMPONENT_USAGE=ALPHA | C_MAPPING=UNSIGNED_IDENTITY_NV | B_INPUT=SPARE0_NV | B_COMPONENT_USAGE=ALPHA | B_MAPPING=UNSIGNED_IDENTITY_NV | A_INPUT=TEXTURE0_ARB | A_COMPONENT_USAGE=BLUE | A_MAPPING=UNSIGNED_IDENTITY_NV
202 08040820    NV10_TCL_PRIMITIVE_3D.RC_IN_RGB[0] = D_INPUT=ZERO | D_COMPONENT_USAGE=RGB | D_MAPPING=UNSIGNED_INVERT_NV | C_INPUT=TEXTURE1_ARB | C_COMPONENT_USAGE=RGB | C_MAPPING=UNSIGNED_IDENTITY_NV | B_INPUT=PRIMARY_COLOR_NV | B_COMPONENT_USAGE=RGB | B_MAPPING=UNSIGNED_IDENTITY_NV | A_INPUT=TEXTURE1_ARB | A_COMPONENT_USAGE=RGB | A_MAPPING=UNSIGNED_IDENTITY_NV
203 090c0920    NV10_TCL_PRIMITIVE_3D.RC_IN_RGB[1] = D_INPUT=ZERO | D_COMPONENT_USAGE=RGB | D_MAPPING=UNSIGNED_INVERT_NV | C_INPUT=TEXTURE0_ARB | C_COMPONENT_USAGE=RGB | C_MAPPING=UNSIGNED_IDENTITY_NV | B_INPUT=SPARE0_NV | B_COMPONENT_USAGE=RGB | B_MAPPING=UNSIGNED_IDENTITY_NV | A_INPUT=TEXTURE0_ARB | A_COMPONENT_USAGE=RGB | A_MAPPING=UNSIGNED_IDENTITY_NV
204 00000000    NV10_TCL_PRIMITIVE_3D.RC_COLOR[0] = B=0 | G=0 | R=0 | A=0
205 00000000    NV10_TCL_PRIMITIVE_3D.RC_COLOR[1] = B=0 | G=0 | R=0 | A=0
206 00000c00    NV10_TCL_PRIMITIVE_3D.RC_OUT_ALPHA[0] = CD_OUTPUT=ZERO | AB_OUTPUT=ZERO | SUM_OUTPUT=SPARE0_NV | CD_DOT_PRODUCT=FALSE | AB_DOT_PRODUCT=FALSE | MUX_SUM=FALSE | BIAS=NONE | SCALE=NONE | leftover=0x00000000/0x0000ffff
207 00000c00    NV10_TCL_PRIMITIVE_3D.RC_OUT_ALPHA[1] = CD_OUTPUT=ZERO | AB_OUTPUT=ZERO | SUM_OUTPUT=SPARE0_NV | CD_DOT_PRODUCT=FALSE | AB_DOT_PRODUCT=FALSE | MUX_SUM=FALSE | BIAS=NONE | SCALE=NONE | leftover=0x00000000/0x0000ffff
208 000010cd    NV10_TCL_PRIMITIVE_3D.RC_OUT_RGB[0] = CD_OUTPUT=SPARE1_NV | AB_OUTPUT=SPARE0_NV | SUM_OUTPUT=ZERO | CD_DOT_PRODUCT=TRUE | AB_DOT_PRODUCT=FALSE | MUX_SUM=FALSE | BIAS=NONE | SCALE=NONE | OPERATION=0 | leftover=0x00000000/0x3800ffff
209 280010cd    NV10_TCL_PRIMITIVE_3D.RC_OUT_RGB[1] = CD_OUTPUT=SPARE1_NV | AB_OUTPUT=SPARE0_NV | SUM_OUTPUT=ZERO | CD_DOT_PRODUCT=TRUE | AB_DOT_PRODUCT=FALSE | MUX_SUM=FALSE | BIAS=NONE | SCALE=NONE | OPERATION=5 | leftover=0x00000000/0x3800ffff
210 300e0300    NV10_TCL_PRIMITIVE_3D.RC_FINAL0 = D_INPUT=ZERO | D_COMPONENT_USAGE=RGB | D_MAPPING=UNSIGNED_IDENTITY_NV | C_INPUT=FOG | C_COMPONENT_USAGE=RGB | C_MAPPING=UNSIGNED_IDENTITY_NV | B_INPUT=SPARE0_PLUS_SECONDARY_COLOR_NV | B_COMPONENT_USAGE=RGB | B_MAPPING=UNSIGNED_IDENTITY_NV | A_INPUT=ZERO | A_COMPONENT_USAGE=ALPHA | A_MAPPING=UNSIGNED_INVERT_NV
211 0c091c80    NV10_TCL_PRIMITIVE_3D.RC_FINAL1 = COLOR_SUM_CLAMP=TRUE | G_INPUT=SPARE0_NV | G_COMPONENT_USAGE=ALPHA | G_MAPPING=UNSIGNED_IDENTITY_NV | F_INPUT=TEXTURE0_ARB | F_COMPONENT_USAGE=RGB | F_MAPPING=UNSIGNED_IDENTITY_NV | E_INPUT=SPARE0_NV | E_COMPONENT_USAGE=RGB | E_MAPPING=UNSIGNED_IDENTITY_NV | leftover=0x00000000/0xffffff80
212 00042294  size 1, subchannel 1 (0xbeef5601),offset 0x0294,increment
213 00000000    NV10_TCL_PRIMITIVE_3D.LIGHT_MODEL = COLOR_CONTROL=0 | LOCAL_VIEWER=FALSE | leftover=0x00000000/0x00010002
214 000423b8  size 1, subchannel 1 (0xbeef5601),offset 0x03b8,increment
215 00000000    NV10_TCL_PRIMITIVE_3D.COLOR_CONTROL
216 000423bc  size 1, subchannel 1 (0xbeef5601),offset 0x03bc,increment
217 00000000    NV10_TCL_PRIMITIVE_3D.ENABLED_LIGHTS = LIGHT0=FALSE | LIGHT1=FALSE | LIGHT2=FALSE | LIGHT3=FALSE | LIGHT4=FALSE | LIGHT5=FALSE | LIGHT6=FALSE | LIGHT7=FALSE | leftover=0x00000000/0x00005555
218 00402500  size 16, subchannel 1 (0xbeef5601),offset 0x0500,increment
219 */              
220         }
221         else
222         {
223         }
224 }
225
226 static void NV10SetPictOp(NVPtr pNv,int op)
227 {
228         struct {int src;int dst;} pictops[] =
229         {
230                 {0x0000,0x0000}, // PictOpClear
231                 {0x0001,0x0000}, // PictOpSrc 
232                 {0x0000,0x0001}, // PictOpDst
233                 {0x0001,0x0303}, // PictOpOver
234                 {0x0305,0x0001}, // PictOpOverReverse
235                 {0x0304,0x0000}, // PictOpIn
236                 {0x0000,0x0302}, // PictOpInReverse
237                 {0x0305,0x0000}, // PictOpOut
238                 {0x0000,0x0303}, // PictOpOutReverse
239                 {0x0304,0x0303}, // PictOpAtop
240                 {0x0305,0x0302}, // PictOpAtopReverse
241                 {0x0305,0x0303}, // PictOpXor
242                 {0x0001,0x0001}, // PictOpAdd
243         };
244
245         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC, 2);
246         NVDmaNext (pNv, pictops[op].src);
247         NVDmaNext (pNv, pictops[op].dst);
248 }
249
250 static Bool NV10PrepareComposite(int      op,
251                                PicturePtr pSrcPicture,
252                                PicturePtr pMaskPicture,
253                                PicturePtr pDstPicture,
254                                PixmapPtr  pSrc,
255                                PixmapPtr  pMask,
256                                PixmapPtr  pDst)
257 {
258         ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
259         NVPtr pNv = NVPTR(pScrn);
260
261         /* Set dst format */
262         NV10SetBuffer(pNv,pDstPicture,pDst);
263
264         /* Set src format */
265         NV10SetTexture(pNv,0,pSrcPicture,pSrc);
266
267         /* Set mask format */
268         if (pMaskPicture)
269                 NV10SetTexture(pNv,1,pMaskPicture,pMask);
270
271         /* Set Multitexturing */
272         NV10SetMultitexture(pNv, (pMaskPicture!=NULL));
273
274         /* Set PictOp */
275         NV10SetPictOp(pNv, op);
276
277         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_BEGIN_END, 1);
278         NVDmaNext (pNv, 8); /* GL_QUADS + 1 */
279
280         state.have_mask=(pMaskPicture!=NULL);
281         return TRUE;
282 }
283
284 static inline void NV10Vertex(NVPtr pNv,float vx,float vy,float tx,float ty)
285 {
286         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_2F_S, 2);
287         NVDmaFloat(pNv, tx);
288         NVDmaFloat(pNv, ty);
289         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_POS_3F_X, 3);
290         NVDmaFloat(pNv, vx);
291         NVDmaFloat(pNv, vy);
292         NVDmaFloat(pNv, 0.f);
293 }
294
295 static inline void NV10MVertex(NVPtr pNv,float vx,float vy,float t0x,float t0y,float t1x,float t1y)
296 {
297         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_2F_S, 2);
298         NVDmaFloat(pNv, t0x);
299         NVDmaFloat(pNv, t0y);
300         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_2F_S, 2);
301         NVDmaFloat(pNv, t1x);
302         NVDmaFloat(pNv, t1y);
303         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_POS_3F_X, 3);
304         NVDmaFloat(pNv, vx);
305         NVDmaFloat(pNv, vy);
306         NVDmaFloat(pNv, 0.f);
307 }
308
309 #define xFixedToFloat(v) \
310         ((float)xFixedToInt((v)) + ((float)xFixedFrac(v) / 65536.0))
311
312 static void
313 NV10EXATransformCoord(PictTransformPtr t, int x, int y, float sx, float sy,
314                                           float *x_ret, float *y_ret)
315 {
316         PictVector v;
317
318         if (t) {
319                 v.vector[0] = IntToxFixed(x);
320                 v.vector[1] = IntToxFixed(y);
321                 v.vector[2] = xFixed1;
322                 PictureTransformPoint(t, &v);
323                 *x_ret = xFixedToFloat(v.vector[0]) / sx;
324                 *y_ret = xFixedToFloat(v.vector[1]) / sy;
325         } else {
326                 *x_ret = (float)x / sx;
327                 *y_ret = (float)y / sy;
328         }
329 }
330
331
332 static void NV10Composite(PixmapPtr pDst,
333                         int       srcX,
334                         int       srcY,
335                         int       maskX,
336                         int       maskY,
337                         int       dstX,
338                         int       dstY,
339                         int       width,
340                         int       height)
341 {
342         ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
343         NVPtr pNv = NVPTR(pScrn);
344         float sX0, sX1, sY0, sY1;
345         float mX0, mX1, mY0, mY1;
346
347         NV10EXATransformCoord(state.unit[0].transform, srcX, srcY,
348                               state.unit[0].width,
349                               state.unit[0].height, &sX0, &sY0);
350         NV10EXATransformCoord(state.unit[0].transform,
351                               srcX + width, srcY + height,
352                               state.unit[0].width,
353                               state.unit[0].height, &sX1, &sY1);
354
355         if (state.have_mask) {
356                 NV10EXATransformCoord(state.unit[1].transform, maskX, maskY,
357                                       state.unit[1].width,
358                                       state.unit[1].height, &mX0, &mY0);
359                 NV10EXATransformCoord(state.unit[1].transform,
360                                       maskX + width, maskY + height,
361                                       state.unit[1].width,
362                                       state.unit[1].height, &mX1, &mY1);
363                 NV10MVertex(pNv , dstX         ,          dstY,sX0 , sY0 , mX0 , mY0);
364                 NV10MVertex(pNv , dstX + width ,          dstY,sX1 , sY0 , mX1 , mY0);
365                 NV10MVertex(pNv , dstX + width , dstY + height,sX1 , sY1 , mX1 , mY1);
366                 NV10MVertex(pNv , dstX         , dstY + height,sX0 , sY1 , mX0 , mY1);
367         } else {
368                 NV10Vertex(pNv , dstX         ,          dstY , sX0 , sY0);
369                 NV10Vertex(pNv , dstX + width ,          dstY , sX1 , sY0);
370                 NV10Vertex(pNv , dstX + width , dstY + height , sX1 , sY1);
371                 NV10Vertex(pNv , dstX         , dstY + height , sX0 , sY1);
372         }
373
374         NVDmaKickoff(pNv);
375 }
376
377 static void NV10DoneComposite (PixmapPtr pDst)
378 {
379         ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
380         NVPtr pNv = NVPTR(pScrn);
381
382         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_BEGIN_END, 1);
383         NVDmaNext (pNv, 0); /* STOP */
384
385         exaMarkSync(pDst->drawable.pScreen);
386 }
387
388
389 Bool
390 NVAccelInitNV10TCL(ScrnInfoPtr pScrn)
391 {
392         NVPtr pNv = NVPTR(pScrn);
393         static int have_object = FALSE;
394         uint32_t class = 0, chipset;
395         int i;
396
397         chipset = (nvReadMC(pNv, 0) >> 20) & 0xff;
398         if (    ((chipset & 0xf0) != NV_ARCH_10) &&
399                 ((chipset & 0xf0) != NV_ARCH_20) )
400                 return FALSE;
401
402         if (chipset>=0x20)
403                 class = NV11_TCL_PRIMITIVE_3D;
404         else if (chipset>=0x17)
405                 class = NV17_TCL_PRIMITIVE_3D;
406         else if (chipset>=0x11)
407                 class = NV11_TCL_PRIMITIVE_3D;
408         else
409                 class = NV10_TCL_PRIMITIVE_3D;
410
411         if (!have_object) {
412                 if (!NVDmaCreateContextObject(pNv, Nv3D, class))
413                         return FALSE;
414                 have_object = TRUE;
415         }
416
417         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_SET_DMA_NOTIFY, 1);
418         NVDmaNext (pNv, NvNullObject);
419
420         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY0, 2);
421         NVDmaNext (pNv, NvDmaFB);
422         NVDmaNext (pNv, NvDmaTT);
423
424         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY2, 2);
425         NVDmaNext (pNv, NvDmaFB);
426         NVDmaNext (pNv, NvDmaFB);
427
428         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_NOP, 1);
429         NVDmaNext (pNv, 0);
430
431         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 2);
432         NVDmaNext (pNv, 0);
433         NVDmaNext (pNv, 0);
434
435         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 1);
436         NVDmaNext (pNv, (0x7ff<<16)|0x800);
437         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(0), 1);
438         NVDmaNext (pNv, (0x7ff<<16)|0x800);
439
440         for (i=1;i<8;i++) {
441                 NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(i), 1);
442                 NVDmaNext (pNv, 0);
443                 NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(i), 1);
444                 NVDmaNext (pNv, 0);
445         }
446
447         NVDmaStart(pNv, Nv3D, 0x290, 1);
448         NVDmaNext (pNv, (0x10<<16)|1);
449         NVDmaStart(pNv, Nv3D, 0x3f4, 1);
450         NVDmaNext (pNv, 0);
451
452 //      NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_NOTIFY, 1);
453 //      NVDmaNext (pNv, 0);
454         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_NOP, 1);
455         NVDmaNext (pNv, 0);
456
457         if (class != NV10_TCL_PRIMITIVE_3D) {
458                 /* For nv11, nv17 */
459                 NVDmaStart(pNv, Nv3D, 0x120, 3);
460                 NVDmaNext (pNv, 0);
461                 NVDmaNext (pNv, 1);
462                 NVDmaNext (pNv, 2);
463
464                 NVDmaStart(pNv, NvImageBlit, 0x120, 3);
465                 NVDmaNext (pNv, 0);
466                 NVDmaNext (pNv, 1);
467                 NVDmaNext (pNv, 2);
468
469                 NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_NOP, 1);
470                 NVDmaNext (pNv, 0);
471         }
472
473         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_NOP, 1);
474         NVDmaNext (pNv, 0);
475
476         /* Set state */
477         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_FOG_ENABLE, 1);
478         NVDmaNext (pNv, 0);
479         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE, 1);
480         NVDmaNext (pNv, 0);
481         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC, 2);
482         NVDmaNext (pNv, 0x207);
483         NVDmaNext (pNv, 0);
484         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_TX_ENABLE(0), 2);
485         NVDmaNext (pNv, 0);
486         NVDmaNext (pNv, 0);
487         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_RC_IN_ALPHA(0), 12);
488         NVDmaNext (pNv, 0x30141010);
489         NVDmaNext (pNv, 0);
490         NVDmaNext (pNv, 0x20040000);
491         NVDmaNext (pNv, 0);
492         NVDmaNext (pNv, 0);
493         NVDmaNext (pNv, 0);
494         NVDmaNext (pNv, 0x00000c00);
495         NVDmaNext (pNv, 0);
496         NVDmaNext (pNv, 0x00000c00);
497         NVDmaNext (pNv, 0x18000000);
498         NVDmaNext (pNv, 0x300e0300);
499         NVDmaNext (pNv, 0x0c091c80);
500         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE, 1);
501         NVDmaNext (pNv, 0);
502         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_DITHER_ENABLE, 2);
503         NVDmaNext (pNv, 1);
504         NVDmaNext (pNv, 0);
505         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE, 1);
506         NVDmaNext (pNv, 0);
507         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_WEIGHT_ENABLE, 2);
508         NVDmaNext (pNv, 0);
509         NVDmaNext (pNv, 0);
510         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC, 4);
511         NVDmaNext (pNv, 1);
512         NVDmaNext (pNv, 0);
513         NVDmaNext (pNv, 0);
514         NVDmaNext (pNv, 0x8006);
515         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_STENCIL_MASK, 8);
516         NVDmaNext (pNv, 0xff);
517         NVDmaNext (pNv, 0x207);
518         NVDmaNext (pNv, 0);
519         NVDmaNext (pNv, 0xff);
520         NVDmaNext (pNv, 0x1e00);
521         NVDmaNext (pNv, 0x1e00);
522         NVDmaNext (pNv, 0x1e00);
523         NVDmaNext (pNv, 0x1d01);
524         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE, 1);
525         NVDmaNext (pNv, 0);
526         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_FOG_ENABLE, 2);
527         NVDmaNext (pNv, 0);
528         NVDmaNext (pNv, 0);
529         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_LIGHT_MODEL, 1);
530         NVDmaNext (pNv, 0);
531         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_COLOR_CONTROL, 1);
532         NVDmaNext (pNv, 0);
533         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1);
534         NVDmaNext (pNv, 0);
535         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE, 3);
536         NVDmaNext (pNv, 0);
537         NVDmaNext (pNv, 0);
538         NVDmaNext (pNv, 0);
539         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_DEPTH_FUNC, 1);
540         NVDmaNext (pNv, 0x201);
541         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE, 1);
542         NVDmaNext (pNv, 0);
543         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE, 1);
544         NVDmaNext (pNv, 0);
545         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR, 2);
546         NVDmaNext (pNv, 0);
547         NVDmaNext (pNv, 0);
548         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_POINT_SIZE, 1);
549         NVDmaNext (pNv, 8);
550         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_POINT_PARAMETERS_ENABLE, 2);
551         NVDmaNext (pNv, 0);
552         NVDmaNext (pNv, 0);
553         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_LINE_WIDTH, 1);
554         NVDmaNext (pNv, 8);
555         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE, 1);
556         NVDmaNext (pNv, 0);
557         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT, 2);
558         NVDmaNext (pNv, 0x1b02);
559         NVDmaNext (pNv, 0x1b02);
560         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_CULL_FACE, 2);
561         NVDmaNext (pNv, 0x405);
562         NVDmaNext (pNv, 0x901);
563         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE, 1);
564         NVDmaNext (pNv, 0);
565         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE, 1);
566         NVDmaNext (pNv, 0);
567         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(0), 8);
568         for (i=0;i<8;i++) {
569                 NVDmaNext (pNv, 0);
570         }
571         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_FOG_EQUATION_CONSTANT, 3);
572         NVDmaNext (pNv, 0x3fc00000);    /* -1.50 */
573         NVDmaNext (pNv, 0xbdb8aa0a);    /* -0.09 */
574         NVDmaNext (pNv, 0);             /*  0.00 */
575
576         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_NOP, 1);
577         NVDmaNext (pNv, 0);
578
579         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_FOG_MODE, 2);
580         NVDmaNext (pNv, 0x802);
581         NVDmaNext (pNv, 2);
582         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_VIEW_MATRIX_ENABLE, 1);
583         NVDmaNext (pNv, 4);
584         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_COLOR_MASK, 1);
585         NVDmaNext (pNv, 0x01010101);
586
587         /* Set vertex component */
588         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_COL_4F_R, 4);
589         NVDmaFloat (pNv, 0.6);
590         NVDmaFloat (pNv, 0.4);
591         NVDmaFloat (pNv, 0.2);
592         NVDmaFloat (pNv, 1.0);
593         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_COL2_3F_R, 3);
594         NVDmaNext (pNv, 0);
595         NVDmaNext (pNv, 0);
596         NVDmaNext (pNv, 0);
597         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_NOR_3F_X, 3);
598         NVDmaNext (pNv, 0);
599         NVDmaNext (pNv, 0);
600         NVDmaFloat (pNv, 1.0);
601         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_S, 4);
602         NVDmaFloat (pNv, 0.0);
603         NVDmaFloat (pNv, 0.0);
604         NVDmaFloat (pNv, 0.0);
605         NVDmaFloat (pNv, 1.0);
606         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_S, 4);
607         NVDmaFloat (pNv, 0.0);
608         NVDmaFloat (pNv, 0.0);
609         NVDmaFloat (pNv, 0.0);
610         NVDmaFloat (pNv, 1.0);
611         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_FOG_1F, 1);
612         NVDmaFloat (pNv, 0.0);
613         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_EDGEFLAG_ENABLE, 1);
614         NVDmaNext (pNv, 1);
615
616         return TRUE;
617 }
618
619
620
621