randr12: Some changes to crtc regs.
[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         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_TX_OFFSET(unit), 1 );
111         OUT_RING  (NVAccelGetPixmapOffset(pixmap));
112
113         int log2w = log2i(Pict->pDrawable->width);
114         int log2h = log2i(Pict->pDrawable->height);
115         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_TX_FORMAT(unit), 1 );
116         OUT_RING  ((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         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_TX_ENABLE(unit), 1 );
127         OUT_RING  (1);
128
129         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_TX_NPOT_PITCH(unit), 1);
130         OUT_RING  (exaGetPixmapPitch(pixmap) << 16);
131
132         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_TX_NPOT_SIZE(unit), 1);
133         OUT_RING  ((Pict->pDrawable->width<<16) | Pict->pDrawable->height); /* FIXME alignment restrictions, should be even at least */
134
135         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_TX_FILTER(unit), 1);
136         if (Pict->filter == PictFilterNearest)
137                 OUT_RING  ((NV10_TCL_PRIMITIVE_3D_TX_FILTER_MAGNIFY_NEAREST<<28) |
138                                 (NV10_TCL_PRIMITIVE_3D_TX_FILTER_MINIFY_NEAREST<<24));
139         else
140                 OUT_RING  ((NV10_TCL_PRIMITIVE_3D_TX_FILTER_MAGNIFY_LINEAR<<28) |
141                                 (NV10_TCL_PRIMITIVE_3D_TX_FILTER_MINIFY_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         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_BUFFER_FORMAT, 4);
155         OUT_RING  (NV10DstFormat(Pict->format));
156         OUT_RING  (((uint32_t)exaGetPixmapPitch(pixmap) << 16) |(uint32_t)exaGetPixmapPitch(pixmap));
157         OUT_RING  (NVAccelGetPixmapOffset(pixmap));
158         OUT_RING  (0);
159         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 2);
160         OUT_RING  ((w<<16)|x);
161         OUT_RING  ((h<<16)|y);
162         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_MODE, 1); /* clip_mode */
163         OUT_RING  (0);
164         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 1);
165         OUT_RING  (((w-1+x)<<16)|x|0x08000800);
166         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(0), 1);
167         OUT_RING  (((h-1+y)<<16)|y|0x08000800);
168
169         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_PROJECTION_MATRIX(0), 16);
170         for(i=0;i<16;i++)
171                 if (i/4==i%4)
172                         OUT_RINGf (1.0f);
173                 else
174                         OUT_RINGf (0.0f);
175
176         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR, 2);
177         OUT_RING  (0);
178 #if SCREEN_BPP == 32
179         OUT_RINGf (16777216.0);
180 #else
181         OUT_RINGf (65536.0);
182 #endif
183         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_X, 4);
184         OUT_RINGf ((w * 0.5) - 2048.0);
185         OUT_RINGf ((h * 0.5) - 2048.0);
186 #if SCREEN_BPP == 32
187         OUT_RINGf (16777215.0 * 0.5);
188 #else
189         OUT_RINGf (65535.0 * 0.5);
190 #endif
191         OUT_RING  (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         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC, 2);
246         OUT_RING  (pictops[op].src);
247         OUT_RING  (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         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_BEGIN_END, 1);
278         OUT_RING  (NV10_TCL_PRIMITIVE_3D_VERTEX_BEGIN_END_QUADS);
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         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_2F_S, 2);
287         OUT_RINGf (tx);
288         OUT_RINGf (ty);
289         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_POS_3F_X, 3);
290         OUT_RINGf (vx);
291         OUT_RINGf (vy);
292         OUT_RINGf (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         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_2F_S, 2);
298         OUT_RINGf (t0x);
299         OUT_RINGf (t0y);
300         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_2F_S, 2);
301         OUT_RINGf (t1x);
302         OUT_RINGf (t1y);
303         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_POS_3F_X, 3);
304         OUT_RINGf (vx);
305         OUT_RINGf (vy);
306         OUT_RINGf (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         FIRE_RING();
375 }
376
377 static void NV10DoneComposite (PixmapPtr pDst)
378 {
379         ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
380         NVPtr pNv = NVPTR(pScrn);
381
382         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_BEGIN_END, 1);
383         OUT_RING  (NV10_TCL_PRIMITIVE_3D_VERTEX_BEGIN_END_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         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_DMA_NOTIFY, 1);
418         OUT_RING  (NvNullObject);
419
420         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_DMA_IN_MEMORY0, 2);
421         OUT_RING  (NvDmaFB);
422         OUT_RING  (NvDmaTT);
423
424         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_DMA_IN_MEMORY2, 2);
425         OUT_RING  (NvDmaFB);
426         OUT_RING  (NvDmaFB);
427
428         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_NOP, 1);
429         OUT_RING  (0);
430
431         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 2);
432         OUT_RING  (0);
433         OUT_RING  (0);
434
435         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 1);
436         OUT_RING  ((0x7ff<<16)|0x800);
437         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(0), 1);
438         OUT_RING  ((0x7ff<<16)|0x800);
439
440         for (i=1;i<8;i++) {
441                 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(i), 1);
442                 OUT_RING  (0);
443                 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(i), 1);
444                 OUT_RING  (0);
445         }
446
447         BEGIN_RING(Nv3D, 0x290, 1);
448         OUT_RING  ((0x10<<16)|1);
449         BEGIN_RING(Nv3D, 0x3f4, 1);
450         OUT_RING  (0);
451
452 //      BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_NOTIFY, 1);
453 //      OUT_RING  (0);
454         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_NOP, 1);
455         OUT_RING  (0);
456
457         if (class != NV10_TCL_PRIMITIVE_3D) {
458                 /* For nv11, nv17 */
459                 BEGIN_RING(Nv3D, 0x120, 3);
460                 OUT_RING  (0);
461                 OUT_RING  (1);
462                 OUT_RING  (2);
463
464                 BEGIN_RING(NvImageBlit, 0x120, 3);
465                 OUT_RING  (0);
466                 OUT_RING  (1);
467                 OUT_RING  (2);
468
469                 BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_NOP, 1);
470                 OUT_RING  (0);
471         }
472
473         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_NOP, 1);
474         OUT_RING  (0);
475
476         /* Set state */
477         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_FOG_ENABLE, 1);
478         OUT_RING  (0);
479         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE, 1);
480         OUT_RING  (0);
481         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC, 2);
482         OUT_RING  (0x207);
483         OUT_RING  (0);
484         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_TX_ENABLE(0), 2);
485         OUT_RING  (0);
486         OUT_RING  (0);
487         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_RC_IN_ALPHA(0), 12);
488         OUT_RING  (0x30141010);
489         OUT_RING  (0);
490         OUT_RING  (0x20040000);
491         OUT_RING  (0);
492         OUT_RING  (0);
493         OUT_RING  (0);
494         OUT_RING  (0x00000c00);
495         OUT_RING  (0);
496         OUT_RING  (0x00000c00);
497         OUT_RING  (0x18000000);
498         OUT_RING  (0x300e0300);
499         OUT_RING  (0x0c091c80);
500         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE, 1);
501         OUT_RING  (0);
502         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_DITHER_ENABLE, 2);
503         OUT_RING  (1);
504         OUT_RING  (0);
505         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE, 1);
506         OUT_RING  (0);
507         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_WEIGHT_ENABLE, 2);
508         OUT_RING  (0);
509         OUT_RING  (0);
510         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC, 4);
511         OUT_RING  (1);
512         OUT_RING  (0);
513         OUT_RING  (0);
514         OUT_RING  (0x8006);
515         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_STENCIL_MASK, 8);
516         OUT_RING  (0xff);
517         OUT_RING  (0x207);
518         OUT_RING  (0);
519         OUT_RING  (0xff);
520         OUT_RING  (0x1e00);
521         OUT_RING  (0x1e00);
522         OUT_RING  (0x1e00);
523         OUT_RING  (0x1d01);
524         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE, 1);
525         OUT_RING  (0);
526         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_FOG_ENABLE, 2);
527         OUT_RING  (0);
528         OUT_RING  (0);
529         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_LIGHT_MODEL, 1);
530         OUT_RING  (0);
531         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_COLOR_CONTROL, 1);
532         OUT_RING  (0);
533         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1);
534         OUT_RING  (0);
535         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE, 3);
536         OUT_RING  (0);
537         OUT_RING  (0);
538         OUT_RING  (0);
539         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_DEPTH_FUNC, 1);
540         OUT_RING  (0x201);
541         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE, 1);
542         OUT_RING  (0);
543         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE, 1);
544         OUT_RING  (0);
545         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR, 2);
546         OUT_RING  (0);
547         OUT_RING  (0);
548         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_POINT_SIZE, 1);
549         OUT_RING  (8);
550         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_POINT_PARAMETERS_ENABLE, 2);
551         OUT_RING  (0);
552         OUT_RING  (0);
553         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_LINE_WIDTH, 1);
554         OUT_RING  (8);
555         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE, 1);
556         OUT_RING  (0);
557         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT, 2);
558         OUT_RING  (0x1b02);
559         OUT_RING  (0x1b02);
560         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_CULL_FACE, 2);
561         OUT_RING  (0x405);
562         OUT_RING  (0x901);
563         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE, 1);
564         OUT_RING  (0);
565         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE, 1);
566         OUT_RING  (0);
567         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(0), 8);
568         for (i=0;i<8;i++) {
569                 OUT_RING  (0);
570         }
571         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_FOG_EQUATION_CONSTANT, 3);
572         OUT_RING  (0x3fc00000); /* -1.50 */
573         OUT_RING  (0xbdb8aa0a); /* -0.09 */
574         OUT_RING  (0);          /*  0.00 */
575
576         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_NOP, 1);
577         OUT_RING  (0);
578
579         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_FOG_MODE, 2);
580         OUT_RING  (0x802);
581         OUT_RING  (2);
582         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VIEW_MATRIX_ENABLE, 1);
583         OUT_RING  (4);
584         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_COLOR_MASK, 1);
585         OUT_RING  (0x01010101);
586
587         /* Set vertex component */
588         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_COL_4F_R, 4);
589         OUT_RINGf (0.6);
590         OUT_RINGf (0.4);
591         OUT_RINGf (0.2);
592         OUT_RINGf (1.0);
593         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_COL2_3F_R, 3);
594         OUT_RING  (0);
595         OUT_RING  (0);
596         OUT_RING  (0);
597         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_NOR_3F_X, 3);
598         OUT_RING  (0);
599         OUT_RING  (0);
600         OUT_RINGf (1.0);
601         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_S, 4);
602         OUT_RINGf (0.0);
603         OUT_RINGf (0.0);
604         OUT_RINGf (0.0);
605         OUT_RINGf (1.0);
606         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_S, 4);
607         OUT_RINGf (0.0);
608         OUT_RINGf (0.0);
609         OUT_RINGf (0.0);
610         OUT_RINGf (1.0);
611         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_VERTEX_FOG_1F, 1);
612         OUT_RINGf (0.0);
613         BEGIN_RING(Nv3D, NV10_TCL_PRIMITIVE_3D_EDGEFLAG_ENABLE, 1);
614         OUT_RING  (1);
615
616         return TRUE;
617 }
618
619
620
621