A little more work on nv10 exa.
[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 = (int)log2(Pict->pDrawable->width);
114         int log2h = (int)log2(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 NV10SetPictOp(NVPtr pNv,int op)
195 {
196         struct {int src;int dst;} pictops[] =
197         {
198                 {0x0000,0x0000}, // PictOpClear
199                 {0x0001,0x0000}, // PictOpSrc 
200                 {0x0000,0x0001}, // PictOpDst
201                 {0x0001,0x0303}, // PictOpOver
202                 {0x0305,0x0001}, // PictOpOverReverse
203                 {0x0304,0x0000}, // PictOpIn
204                 {0x0000,0x0302}, // PictOpInReverse
205                 {0x0305,0x0000}, // PictOpOut
206                 {0x0000,0x0303}, // PictOpOutReverse
207                 {0x0304,0x0303}, // PictOpAtop
208                 {0x0305,0x0302}, // PictOpAtopReverse
209                 {0x0305,0x0303}, // PictOpXor
210                 {0x0001,0x0001}, // PictOpAdd
211         };
212
213         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC, 2);
214         NVDmaNext (pNv, pictops[op].src);
215         NVDmaNext (pNv, pictops[op].dst);
216 }
217
218 static Bool NV10PrepareComposite(int      op,
219                                PicturePtr pSrcPicture,
220                                PicturePtr pMaskPicture,
221                                PicturePtr pDstPicture,
222                                PixmapPtr  pSrc,
223                                PixmapPtr  pMask,
224                                PixmapPtr  pDst)
225 {
226         ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
227         NVPtr pNv = NVPTR(pScrn);
228
229         /* Set dst format */
230         NV10SetBuffer(pNv,pDstPicture,pDst);
231
232         /* Set src format */
233         NV10SetTexture(pNv,0,pSrcPicture,pSrc);
234
235         /* Set mask format */
236         if (pMaskPicture)
237                 NV10SetTexture(pNv,1,pMaskPicture,pMask);
238
239         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_BEGIN_END, 1);
240         NVDmaNext (pNv, 8); /* GL_QUADS + 1 */
241
242         /* Set PictOp */
243         NV10SetPictOp(pNv, op);
244
245         state.have_mask=(pMaskPicture!=NULL);
246         return TRUE;
247 }
248
249 static inline void NV10Vertex(NVPtr pNv,float vx,float vy,float tx,float ty)
250 {
251         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_2F_S, 2);
252         NVDmaFloat(pNv, tx);
253         NVDmaFloat(pNv, ty);
254         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_POS_3F_X, 3);
255         NVDmaFloat(pNv, vx);
256         NVDmaFloat(pNv, vy);
257         NVDmaFloat(pNv, 0.f);
258 }
259
260 static inline void NV10MVertex(NVPtr pNv,float vx,float vy,float t0x,float t0y,float t1x,float t1y)
261 {
262         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_2F_S, 2);
263         NVDmaFloat(pNv, t0x);
264         NVDmaFloat(pNv, t0y);
265         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_2F_S, 2);
266         NVDmaFloat(pNv, t1x);
267         NVDmaFloat(pNv, t1y);
268         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_POS_3F_X, 3);
269         NVDmaFloat(pNv, vx);
270         NVDmaFloat(pNv, vy);
271         NVDmaFloat(pNv, 0.f);
272 }
273
274 #define xFixedToFloat(v) \
275         ((float)xFixedToInt((v)) + ((float)xFixedFrac(v) / 65536.0))
276
277 static void
278 NV10EXATransformCoord(PictTransformPtr t, int x, int y, float sx, float sy,
279                                           float *x_ret, float *y_ret)
280 {
281         PictVector v;
282
283         if (t) {
284                 v.vector[0] = IntToxFixed(x);
285                 v.vector[1] = IntToxFixed(y);
286                 v.vector[2] = xFixed1;
287                 PictureTransformPoint(t, &v);
288                 *x_ret = xFixedToFloat(v.vector[0]) / sx;
289                 *y_ret = xFixedToFloat(v.vector[1]) / sy;
290         } else {
291                 *x_ret = (float)x / sx;
292                 *y_ret = (float)y / sy;
293         }
294 }
295
296
297 static void NV10Composite(PixmapPtr pDst,
298                         int       srcX,
299                         int       srcY,
300                         int       maskX,
301                         int       maskY,
302                         int       dstX,
303                         int       dstY,
304                         int       width,
305                         int       height)
306 {
307         ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
308         NVPtr pNv = NVPTR(pScrn);
309         float sX0, sX1, sY0, sY1;
310         float mX0, mX1, mY0, mY1;
311
312         NV10EXATransformCoord(state.unit[0].transform, srcX, srcY,
313                               state.unit[0].width,
314                               state.unit[0].height, &sX0, &sY0);
315         NV10EXATransformCoord(state.unit[0].transform,
316                               srcX + width, srcY + height,
317                               state.unit[0].width,
318                               state.unit[0].height, &sX1, &sY1);
319
320         if (state.have_mask) {
321                 NV10EXATransformCoord(state.unit[1].transform, maskX, maskY,
322                                       state.unit[1].width,
323                                       state.unit[1].height, &mX0, &mY0);
324                 NV10EXATransformCoord(state.unit[1].transform,
325                                       maskX + width, maskY + height,
326                                       state.unit[1].width,
327                                       state.unit[1].height, &mX1, &mY1);
328                 NV10MVertex(pNv , dstX         ,          dstY,sX0 , sY0 , mX0 , mY0);
329                 NV10MVertex(pNv , dstX + width ,          dstY,sX1 , sY0 , mX1 , mY0);
330                 NV10MVertex(pNv , dstX + width , dstY + height,sX1 , sY1 , mX1 , mY1);
331                 NV10MVertex(pNv , dstX         , dstY + height,sX0 , sY1 , mX0 , mY1);
332         } else {
333                 NV10Vertex(pNv , dstX         ,          dstY , sX0 , sY0);
334                 NV10Vertex(pNv , dstX + width ,          dstY , sX1 , sY0);
335                 NV10Vertex(pNv , dstX + width , dstY + height , sX1 , sY1);
336                 NV10Vertex(pNv , dstX         , dstY + height , sX0 , sY1);
337         }
338
339         NVDmaKickoff(pNv);
340 }
341
342 static void NV10DoneComposite (PixmapPtr pDst)
343 {
344         ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
345         NVPtr pNv = NVPTR(pScrn);
346
347         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_BEGIN_END, 1);
348         NVDmaNext (pNv, 0); /* STOP */
349
350         exaMarkSync(pDst->drawable.pScreen);
351 }
352
353
354 Bool
355 NVAccelInitNV10TCL(ScrnInfoPtr pScrn)
356 {
357         NVPtr pNv = NVPTR(pScrn);
358         static int have_object = FALSE;
359         uint32_t class = 0, chipset;
360         int i;
361
362         chipset = (nvReadMC(pNv, 0) >> 20) & 0xff;
363         if (    ((chipset & 0xf0) != NV_ARCH_10) &&
364                 ((chipset & 0xf0) != NV_ARCH_20) )
365                 return FALSE;
366
367         if (chipset>=0x20)
368                 class = NV11_TCL_PRIMITIVE_3D;
369         else if (chipset>=0x17)
370                 class = NV17_TCL_PRIMITIVE_3D;
371         else if (chipset>=0x11)
372                 class = NV11_TCL_PRIMITIVE_3D;
373         else
374                 class = NV10_TCL_PRIMITIVE_3D;
375
376         if (!have_object) {
377                 if (!NVDmaCreateContextObject(pNv, Nv3D, class))
378                         return FALSE;
379                 have_object = TRUE;
380         }
381
382         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_SET_DMA_NOTIFY, 1);
383         NVDmaNext (pNv, NvNullObject);
384
385         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY0, 2);
386         NVDmaNext (pNv, NvDmaFB);
387         NVDmaNext (pNv, NvDmaTT);
388
389         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY2, 2);
390         NVDmaNext (pNv, NvDmaFB);
391         NVDmaNext (pNv, NvDmaFB);
392
393         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_NOP, 1);
394         NVDmaNext (pNv, 0);
395
396         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 2);
397         NVDmaNext (pNv, 0);
398         NVDmaNext (pNv, 0);
399
400         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 1);
401         NVDmaNext (pNv, (0x7ff<<16)|0x800);
402         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(0), 1);
403         NVDmaNext (pNv, (0x7ff<<16)|0x800);
404
405         for (i=1;i<8;i++) {
406                 NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(i), 1);
407                 NVDmaNext (pNv, 0);
408                 NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(i), 1);
409                 NVDmaNext (pNv, 0);
410         }
411
412         NVDmaStart(pNv, Nv3D, 0x290, 1);
413         NVDmaNext (pNv, (0x10<<16)|1);
414         NVDmaStart(pNv, Nv3D, 0x3f4, 1);
415         NVDmaNext (pNv, 0);
416
417 //      NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_NOTIFY, 1);
418 //      NVDmaNext (pNv, 0);
419         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_NOP, 1);
420         NVDmaNext (pNv, 0);
421
422 #if IS_NV11
423         NVDmaStart(pNv, Nv3D, 0x120, 3);
424         NVDmaNext (pNv, 0);
425         NVDmaNext (pNv, 1);
426         NVDmaNext (pNv, 2);
427
428         NVDmaStart(pNv, NvImageBlit, 0x120, 3);
429         NVDmaNext (pNv, 0);
430         NVDmaNext (pNv, 1);
431         NVDmaNext (pNv, 2);
432
433         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_NOP, 1);
434         NVDmaNext (pNv, 0);
435 #endif
436
437         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_NOP, 1);
438         NVDmaNext (pNv, 0);
439
440         /* Set state */
441         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_FOG_ENABLE, 1);
442         NVDmaNext (pNv, 0);
443         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE, 1);
444         NVDmaNext (pNv, 0);
445         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC, 2);
446         NVDmaNext (pNv, 0x207);
447         NVDmaNext (pNv, 0);
448         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_TX_ENABLE(0), 2);
449         NVDmaNext (pNv, 0);
450         NVDmaNext (pNv, 0);
451         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_RC_IN_ALPHA(0), 12);
452         NVDmaNext (pNv, 0x30141010);
453         NVDmaNext (pNv, 0);
454         NVDmaNext (pNv, 0x20040000);
455         NVDmaNext (pNv, 0);
456         NVDmaNext (pNv, 0);
457         NVDmaNext (pNv, 0);
458         NVDmaNext (pNv, 0x00000c00);
459         NVDmaNext (pNv, 0);
460         NVDmaNext (pNv, 0x00000c00);
461         NVDmaNext (pNv, 0x18000000);
462         NVDmaNext (pNv, 0x300e0300);
463         NVDmaNext (pNv, 0x0c091c80);
464         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE, 1);
465         NVDmaNext (pNv, 0);
466         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_DITHER_ENABLE, 2);
467         NVDmaNext (pNv, 1);
468         NVDmaNext (pNv, 0);
469         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE, 1);
470         NVDmaNext (pNv, 0);
471         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_WEIGHT_ENABLE, 2);
472         NVDmaNext (pNv, 0);
473         NVDmaNext (pNv, 0);
474         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC, 4);
475         NVDmaNext (pNv, 1);
476         NVDmaNext (pNv, 0);
477         NVDmaNext (pNv, 0);
478         NVDmaNext (pNv, 0x8006);
479         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_STENCIL_MASK, 8);
480         NVDmaNext (pNv, 0xff);
481         NVDmaNext (pNv, 0x207);
482         NVDmaNext (pNv, 0);
483         NVDmaNext (pNv, 0xff);
484         NVDmaNext (pNv, 0x1e00);
485         NVDmaNext (pNv, 0x1e00);
486         NVDmaNext (pNv, 0x1e00);
487         NVDmaNext (pNv, 0x1d01);
488         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE, 1);
489         NVDmaNext (pNv, 0);
490         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_FOG_ENABLE, 2);
491         NVDmaNext (pNv, 0);
492         NVDmaNext (pNv, 0);
493         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_LIGHT_MODEL, 1);
494         NVDmaNext (pNv, 0);
495         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_COLOR_CONTROL, 1);
496         NVDmaNext (pNv, 0);
497         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1);
498         NVDmaNext (pNv, 0);
499         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE, 3);
500         NVDmaNext (pNv, 0);
501         NVDmaNext (pNv, 0);
502         NVDmaNext (pNv, 0);
503         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_DEPTH_FUNC, 1);
504         NVDmaNext (pNv, 0x201);
505         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE, 1);
506         NVDmaNext (pNv, 0);
507         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE, 1);
508         NVDmaNext (pNv, 0);
509         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR, 2);
510         NVDmaNext (pNv, 0);
511         NVDmaNext (pNv, 0);
512         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_POINT_SIZE, 1);
513         NVDmaNext (pNv, 8);
514         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_POINT_PARAMETERS_ENABLE, 2);
515         NVDmaNext (pNv, 0);
516         NVDmaNext (pNv, 0);
517         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_LINE_WIDTH, 1);
518         NVDmaNext (pNv, 8);
519         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE, 1);
520         NVDmaNext (pNv, 0);
521         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT, 2);
522         NVDmaNext (pNv, 0x1b02);
523         NVDmaNext (pNv, 0x1b02);
524         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_CULL_FACE, 2);
525         NVDmaNext (pNv, 0x405);
526         NVDmaNext (pNv, 0x901);
527         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE, 1);
528         NVDmaNext (pNv, 0);
529         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE, 1);
530         NVDmaNext (pNv, 0);
531         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(0), 8);
532         for (i=0;i<8;i++) {
533                 NVDmaNext (pNv, 0);
534         }
535         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_FOG_EQUATION_CONSTANT, 3);
536         NVDmaNext (pNv, 0x3fc00000);    /* -1.50 */
537         NVDmaNext (pNv, 0xbdb8aa0a);    /* -0.09 */
538         NVDmaNext (pNv, 0);             /*  0.00 */
539
540         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_NOP, 1);
541         NVDmaNext (pNv, 0);
542
543         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_FOG_MODE, 2);
544         NVDmaNext (pNv, 0x802);
545         NVDmaNext (pNv, 2);
546         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_VIEW_MATRIX_ENABLE, 1);
547         NVDmaNext (pNv, 4);
548         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_COLOR_MASK, 1);
549         NVDmaNext (pNv, 0x01010101);
550
551         /* Set vertex component */
552         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_COL_4F_R, 4);
553         NVDmaFloat (pNv, 0.6);
554         NVDmaFloat (pNv, 0.4);
555         NVDmaFloat (pNv, 0.2);
556         NVDmaFloat (pNv, 1.0);
557         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_COL2_3F_R, 3);
558         NVDmaNext (pNv, 0);
559         NVDmaNext (pNv, 0);
560         NVDmaNext (pNv, 0);
561         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_NOR_3F_X, 3);
562         NVDmaNext (pNv, 0);
563         NVDmaNext (pNv, 0);
564         NVDmaFloat (pNv, 1.0);
565         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_S, 4);
566         NVDmaFloat (pNv, 0.0);
567         NVDmaFloat (pNv, 0.0);
568         NVDmaFloat (pNv, 0.0);
569         NVDmaFloat (pNv, 1.0);
570         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_S, 4);
571         NVDmaFloat (pNv, 0.0);
572         NVDmaFloat (pNv, 0.0);
573         NVDmaFloat (pNv, 0.0);
574         NVDmaFloat (pNv, 1.0);
575         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_FOG_1F, 1);
576         NVDmaFloat (pNv, 0.0);
577         NVDmaStart(pNv, Nv3D, NV10_TCL_PRIMITIVE_3D_EDGEFLAG_ENABLE, 1);
578         NVDmaNext (pNv, 1);
579
580         return TRUE;
581 }
582
583
584
585