NV30EXA: Minor code cleanup.
[nouveau] / src / nv30_exa.c
1 #ifdef HAVE_CONFIG_H
2 #include "config.h"
3 #endif
4
5 #ifdef ENABLE_NV30EXA
6
7 #include "nv_include.h"
8 #include "nv_shaders.h"
9
10 typedef struct nv_pict_surface_format {
11         int      pict_fmt;
12         uint32_t card_fmt;
13 } nv_pict_surface_format_t;
14
15 typedef struct nv_pict_texture_format {
16         int      pict_fmt;
17         uint32_t card_fmt;
18         uint32_t card_swz;
19 } nv_pict_texture_format_t;
20
21 typedef struct nv_pict_op {
22         Bool     src_alpha;
23         Bool     dst_alpha;
24         uint32_t src_card_op;
25         uint32_t dst_card_op;
26 } nv_pict_op_t;
27
28 typedef struct nv30_exa_state {
29         Bool have_mask;
30
31         struct {
32                 PictTransformPtr transform;
33                 float width;
34                 float height;
35         } unit[2];
36 } nv30_exa_state_t;
37 static nv30_exa_state_t exa_state;
38 #define NV30EXA_STATE nv30_exa_state_t *state = &exa_state
39
40 static nv_pict_surface_format_t
41 NV30SurfaceFormat[] = {
42         { PICT_a8r8g8b8 , 0x148 },
43         { PICT_x8r8g8b8 , 0x145 },
44         { PICT_r5g6b5   , 0x143 },
45         { PICT_a8       , 0x149 },
46         { -1, ~0 }
47 };
48
49 static nv_pict_surface_format_t *
50 NV30_GetPictSurfaceFormat(int format)
51 {
52         int i = 0;
53
54         while (NV30SurfaceFormat[i].pict_fmt != -1) {
55                 if (NV30SurfaceFormat[i].pict_fmt == format)
56                         return &NV30SurfaceFormat[i];
57                 i++;
58         }
59
60         return NULL;
61 }
62
63 enum {
64         NV30EXA_FPID_PASS_COL0 = 0,
65         NV30EXA_FPID_PASS_TEX0 = 1,
66         NV30EXA_FPID_COMPOSITE_MASK = 2,
67         NV30EXA_FPID_COMPOSITE_MASK_SA_CA = 3,
68         NV30EXA_FPID_COMPOSITE_MASK_CA = 4,
69         NV30EXA_FPID_MAX = 5
70 } NV30EXA_FPID;
71
72 static nv_shader_t *nv40_fp_map[NV30EXA_FPID_MAX] = {
73         &nv30_fp_pass_col0,
74         &nv30_fp_pass_tex0,
75         &nv30_fp_composite_mask,
76         &nv30_fp_composite_mask_sa_ca,
77         &nv30_fp_composite_mask_ca
78 };
79
80 static nv_shader_t *nv40_fp_map_a8[NV30EXA_FPID_MAX];
81
82 static void
83 NV30EXAHackupA8Shaders(ScrnInfoPtr pScrn)
84 {
85         int s;
86
87         for (s = 0; s < NV30EXA_FPID_MAX; s++) {
88                 nv_shader_t *def, *a8;
89
90                 def = nv40_fp_map[s];
91                 a8 = xcalloc(1, sizeof(nv_shader_t));
92                 a8->card_priv.NV30FP.num_regs = def->card_priv.NV30FP.num_regs;
93                 a8->size = def->size + 4;
94                 memcpy(a8->data, def->data, def->size * sizeof(uint32_t));
95                 nv40_fp_map_a8[s] = a8;
96
97                 a8->data[a8->size - 8 + 0] &= ~0x00000081;
98                 a8->data[a8->size - 4 + 0]  = 0x01401e81;
99                 a8->data[a8->size - 4 + 1]  = 0x1c9dfe00;
100                 a8->data[a8->size - 4 + 2]  = 0x0001c800;
101                 a8->data[a8->size - 4 + 3]  = 0x0001c800;
102         }
103 }
104
105 /* should be in nouveau_reg.h at some point.. */
106 #define NV30TCL_TX_SWIZZLE_UNIT_S0_X_SHIFT      14
107 #define NV30TCL_TX_SWIZZLE_UNIT_S0_X_ZERO        0
108 #define NV30TCL_TX_SWIZZLE_UNIT_S0_X_ONE         1
109 #define NV30TCL_TX_SWIZZLE_UNIT_S0_X_S1          2
110 #define NV30TCL_TX_SWIZZLE_UNIT_S0_Y_SHIFT      12
111 #define NV30TCL_TX_SWIZZLE_UNIT_S0_Z_SHIFT      10
112 #define NV30TCL_TX_SWIZZLE_UNIT_S0_W_SHIFT       8
113 #define NV30TCL_TX_SWIZZLE_UNIT_S1_X_SHIFT       6
114 #define NV30TCL_TX_SWIZZLE_UNIT_S1_X_X           3
115 #define NV30TCL_TX_SWIZZLE_UNIT_S1_X_Y           2
116 #define NV30TCL_TX_SWIZZLE_UNIT_S1_X_Z           1
117 #define NV30TCL_TX_SWIZZLE_UNIT_S1_X_W           0
118 #define NV30TCL_TX_SWIZZLE_UNIT_S1_Y_SHIFT       4
119 #define NV30TCL_TX_SWIZZLE_UNIT_S1_Z_SHIFT       2
120 #define NV30TCL_TX_SWIZZLE_UNIT_S1_W_SHIFT       0
121
122 #define _(r,tf,ts0x,ts0y,ts0z,ts0w,ts1x,ts1y,ts1z,ts1w)                       \
123   {                                                                           \
124   PICT_##r,                                                                   \
125   (tf),                                                                       \
126   (NV30TCL_TX_SWIZZLE_UNIT_S0_X_##ts0x << NV30TCL_TX_SWIZZLE_UNIT_S0_X_SHIFT)|\
127   (NV30TCL_TX_SWIZZLE_UNIT_S0_X_##ts0y << NV30TCL_TX_SWIZZLE_UNIT_S0_Y_SHIFT)|\
128   (NV30TCL_TX_SWIZZLE_UNIT_S0_X_##ts0z << NV30TCL_TX_SWIZZLE_UNIT_S0_Z_SHIFT)|\
129   (NV30TCL_TX_SWIZZLE_UNIT_S0_X_##ts0w << NV30TCL_TX_SWIZZLE_UNIT_S0_W_SHIFT)|\
130   (NV30TCL_TX_SWIZZLE_UNIT_S1_X_##ts1x << NV30TCL_TX_SWIZZLE_UNIT_S1_X_SHIFT)|\
131   (NV30TCL_TX_SWIZZLE_UNIT_S1_X_##ts1y << NV30TCL_TX_SWIZZLE_UNIT_S1_Y_SHIFT)|\
132   (NV30TCL_TX_SWIZZLE_UNIT_S1_X_##ts1z << NV30TCL_TX_SWIZZLE_UNIT_S1_Z_SHIFT)|\
133   (NV30TCL_TX_SWIZZLE_UNIT_S1_X_##ts1w << NV30TCL_TX_SWIZZLE_UNIT_S1_W_SHIFT)\
134   }
135 static nv_pict_texture_format_t
136 NV30TextureFormat[] = {
137         _(a8r8g8b8, 0x85,   S1,   S1,   S1,   S1, X, Y, Z, W),
138         _(x8r8g8b8, 0x85,   S1,   S1,   S1,  ONE, X, Y, Z, W),
139         _(x8b8g8r8, 0x85,   S1,   S1,   S1,  ONE, Z, Y, X, W),
140         _(a1r5g5b5, 0x82,   S1,   S1,   S1,   S1, X, Y, Z, W),
141         _(x1r5g5b5, 0x82,   S1,   S1,   S1,  ONE, X, Y, Z, W),
142         _(  r5g6b5, 0x84,   S1,   S1,   S1,   S1, X, Y, Z, W),
143         _(      a8, 0x81, ZERO, ZERO, ZERO,   S1, X, X, X, X),
144         { -1, ~0, ~0 }
145 };
146
147 static nv_pict_texture_format_t *
148 NV30_GetPictTextureFormat(int format)
149 {
150         int i = 0;
151
152         while (NV30TextureFormat[i].pict_fmt != -1) {
153                 if (NV30TextureFormat[i].pict_fmt == format)
154                         return &NV30TextureFormat[i];
155                 i++;
156         }
157
158         return NULL;
159 }
160
161 #define NV30_TCL_PRIMITIVE_3D_BF_ZERO                                     0x0000
162 #define NV30_TCL_PRIMITIVE_3D_BF_ONE                                      0x0001
163 #define NV30_TCL_PRIMITIVE_3D_BF_SRC_COLOR                                0x0300
164 #define NV30_TCL_PRIMITIVE_3D_BF_ONE_MINUS_SRC_COLOR                      0x0301
165 #define NV30_TCL_PRIMITIVE_3D_BF_SRC_ALPHA                                0x0302
166 #define NV30_TCL_PRIMITIVE_3D_BF_ONE_MINUS_SRC_ALPHA                      0x0303
167 #define NV30_TCL_PRIMITIVE_3D_BF_DST_ALPHA                                0x0304
168 #define NV30_TCL_PRIMITIVE_3D_BF_ONE_MINUS_DST_ALPHA                      0x0305
169 #define NV30_TCL_PRIMITIVE_3D_BF_DST_COLOR                                0x0306
170 #define NV30_TCL_PRIMITIVE_3D_BF_ONE_MINUS_DST_COLOR                      0x0307
171 #define NV30_TCL_PRIMITIVE_3D_BF_ALPHA_SATURATE                           0x0308
172 #define BF(bf) NV30_TCL_PRIMITIVE_3D_BF_##bf
173
174 static nv_pict_op_t 
175 NV30PictOp[] = {
176 /* Clear       */ { 0, 0, BF(               ZERO), BF(               ZERO) },
177 /* Src         */ { 0, 0, BF(                ONE), BF(               ZERO) },
178 /* Dst         */ { 0, 0, BF(               ZERO), BF(                ONE) },
179 /* Over        */ { 1, 0, BF(                ONE), BF(ONE_MINUS_SRC_ALPHA) },
180 /* OverReverse */ { 0, 1, BF(ONE_MINUS_DST_ALPHA), BF(                ONE) },
181 /* In          */ { 0, 1, BF(          DST_ALPHA), BF(               ZERO) },
182 /* InReverse   */ { 1, 0, BF(               ZERO), BF(          SRC_ALPHA) },
183 /* Out         */ { 0, 1, BF(ONE_MINUS_DST_ALPHA), BF(               ZERO) },
184 /* OutReverse  */ { 1, 0, BF(               ZERO), BF(ONE_MINUS_SRC_ALPHA) },
185 /* Atop        */ { 1, 1, BF(          DST_ALPHA), BF(ONE_MINUS_SRC_ALPHA) },
186 /* AtopReverse */ { 1, 1, BF(ONE_MINUS_DST_ALPHA), BF(          SRC_ALPHA) },
187 /* Xor         */ { 1, 1, BF(ONE_MINUS_DST_ALPHA), BF(ONE_MINUS_SRC_ALPHA) },
188 /* Add         */ { 0, 0, BF(                ONE), BF(                ONE) }
189 };
190
191 static nv_pict_op_t *
192 NV30_GetPictOpRec(int op)
193 {
194         if (op >= PictOpSaturate)
195                 return NULL;
196         return &NV30PictOp[op];
197 }
198
199 #if 0
200 #define FALLBACK(fmt,args...) do {                                      \
201         ErrorF("FALLBACK %s:%d> " fmt, __func__, __LINE__, ##args);     \
202         return FALSE;                                                   \
203 } while(0)
204 #else
205 #define FALLBACK(fmt,args...) do { \
206         return FALSE;              \
207 } while(0)
208 #endif
209
210 static void
211 NV30_LoadVtxProg(ScrnInfoPtr pScrn, nv_shader_t *shader)
212 {
213         NVPtr pNv = NVPTR(pScrn);
214         static int next_hw_id = 0;
215         int i;
216
217         if (!shader->hw_id) {
218                 shader->hw_id = next_hw_id;
219
220                 NVDmaStart(pNv, Nv3D,
221                                 NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_FROM_ID, 1);
222                 NVDmaNext (pNv, (shader->hw_id));
223
224                 for (i=0; i<shader->size; i+=4) {
225                         NVDmaStart(pNv, Nv3D,
226                                         NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_INST0,
227                                         4);
228                         NVDmaNext (pNv, shader->data[i + 0]);
229                         NVDmaNext (pNv, shader->data[i + 1]);
230                         NVDmaNext (pNv, shader->data[i + 2]);
231                         NVDmaNext (pNv, shader->data[i + 3]);
232                         next_hw_id++;
233                 }
234         }
235
236         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_VP_PROGRAM_START_ID, 1);
237         NVDmaNext (pNv, (shader->hw_id));
238
239         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_VP_IN_REG, 2);
240         NVDmaNext (pNv, shader->card_priv.NV30VP.vp_in_reg);
241         NVDmaNext (pNv, shader->card_priv.NV30VP.vp_out_reg);
242 }
243
244 static void
245 NV30_LoadFragProg(ScrnInfoPtr pScrn, nv_shader_t *shader)
246 {
247         NVPtr pNv = NVPTR(pScrn);
248         static NVAllocRec *fp_mem = NULL;
249         static int next_hw_id_offset = 0;
250
251         if (!fp_mem) {
252                 fp_mem = NVAllocateMemory(pNv, NOUVEAU_MEM_FB, 0x1000);
253                 if (!fp_mem) {
254                         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
255                                    "Couldn't alloc fragprog buffer!\n");
256                         return;
257                 }
258         }
259
260         if (!shader->hw_id) {
261                 memcpy(fp_mem->map + next_hw_id_offset, shader->data,
262                                                         shader->size *
263                                                         sizeof(uint32_t));
264
265                 shader->hw_id  = fp_mem->offset;
266                 shader->hw_id += next_hw_id_offset;
267
268                 next_hw_id_offset += (shader->size * sizeof(uint32_t));
269                 next_hw_id_offset = (next_hw_id_offset + 63) & ~63;
270         }
271
272         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_FP_ACTIVE_PROGRAM, 1);
273         NVDmaNext (pNv, shader->hw_id | 1);
274
275         if (pNv->Architecture == NV_30) {
276                 NVDmaStart(pNv, Nv3D, 0x1d60, 1);
277                 NVDmaNext (pNv, 0); /* USES_KIL (1<<7) == 0 */
278                 NVDmaStart(pNv, Nv3D, 0x1450, 1);
279                 NVDmaNext (pNv, shader->card_priv.NV30FP.num_regs << 16);
280         } else {
281                 NVDmaStart(pNv, Nv3D, 0x1d60, 1);
282                 NVDmaNext (pNv, (0<<7) /* !USES_KIL */ |
283                          (shader->card_priv.NV30FP.num_regs << 24));
284         }
285 }
286
287 static void
288 NV30_SetupBlend(ScrnInfoPtr pScrn, nv_pict_op_t *blend,
289                 PictFormatShort dest_format, Bool component_alpha)
290 {
291         NVPtr pNv = NVPTR(pScrn);
292         uint32_t sblend, dblend;
293
294         sblend = blend->src_card_op;
295         dblend = blend->dst_card_op;
296
297         if (blend->dst_alpha) {
298                 if (!PICT_FORMAT_A(dest_format)) {
299                         if (sblend == BF(DST_ALPHA)) {
300                                 sblend = BF(ONE);
301                         } else if (sblend == BF(ONE_MINUS_DST_ALPHA)) {
302                                 sblend = BF(ZERO);
303                         }
304                 } else if (dest_format == PICT_a8) {
305                         if (sblend == BF(DST_ALPHA)) {
306                                 sblend = BF(DST_COLOR);
307                         } else if (sblend == BF(ONE_MINUS_DST_ALPHA)) {
308                                 sblend = BF(ONE_MINUS_DST_COLOR);
309                         }
310                 }
311         }
312
313         if (blend->src_alpha && (component_alpha || dest_format == PICT_a8)) {
314                 if (dblend == BF(SRC_ALPHA)) {
315                         dblend = BF(SRC_COLOR);
316                 } else if (dblend == BF(ONE_MINUS_SRC_ALPHA)) {
317                         dblend = BF(ONE_MINUS_SRC_COLOR);
318                 }
319         }
320
321         if (sblend == BF(ONE) && dblend == BF(ZERO)) {
322                 NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE, 1);
323                 NVDmaNext (pNv, 0);
324         } else {
325                 NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE, 5);
326                 NVDmaNext (pNv, 1);
327                 NVDmaNext (pNv, (sblend << 16) | sblend);
328                 NVDmaNext (pNv, (dblend << 16) | dblend);
329                 NVDmaNext (pNv, 0x00000000);                    /* Blend colour */
330                 NVDmaNext (pNv, (0x8006 << 16) | 0x8006);       /* FUNC_ADD, FUNC_ADD */
331         }
332 }
333
334 static Bool
335 NV30EXATexture(ScrnInfoPtr pScrn, PixmapPtr pPix, PicturePtr pPict, int unit)
336 {
337         NVPtr pNv = NVPTR(pScrn);
338         nv_pict_texture_format_t *fmt;
339         uint32_t card_filter, card_repeat, chipset;
340         NV30EXA_STATE;
341
342         fmt = NV30_GetPictTextureFormat(pPict->format);
343         if (!fmt)
344                 return FALSE;
345
346         if (pPict->repeat && pPict->repeatType == RepeatNormal)
347                 card_repeat = 1;
348         else
349                 card_repeat = 3;
350
351         if (pPict->filter == PictFilterBilinear)
352                 card_filter = 2;
353         else
354                 card_filter = 1;
355
356         if (pNv->Architecture == NV_ARCH_30)
357         {
358                 NVDmaStart(pNv, Nv3D,
359                                 NV30_TCL_PRIMITIVE_3D_TX_ADDRESS_UNIT(unit), 8);
360                 NVDmaNext (pNv, NVAccelGetPixmapOffset(pPix));
361                 NVDmaNext (pNv, (2 << 4)  /* 2D */ |
362                                 (fmt->card_fmt << 8) |
363                                 (1 << 13) /* NPOT */ |
364                                 (1<<16) /* 1 mipmap level */ |
365                                 (1<<0) /* NvDmaFB */ |
366                                 (1<<3) /* border disable? */);
367                 NVDmaNext (pNv, (card_repeat <<  0) /* S */ |
368                                 (card_repeat <<  8) /* T */ |
369                                 (card_repeat << 16) /* R */);
370                 NVDmaNext (pNv, 0x40000000);
371                 NVDmaNext (pNv, (((uint32_t)exaGetPixmapPitch(pPix))<<16) | fmt->card_swz);
372                 NVDmaNext (pNv, (card_filter << 16) /* min */ |
373                                 (card_filter << 24) /* mag */ |
374                                 0x3fd6 /* engine lock */);
375                 NVDmaNext (pNv, (pPix->drawable.width << 16) | pPix->drawable.height);
376                 NVDmaNext (pNv, 0); /* border ARGB */
377                 NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_TX_DEPTH_UNIT(unit), 1);
378                 NVDmaNext (pNv, 0x0);/* there should be an offset here, but what is it for ??? */
379         } else {
380                 NVDmaStart(pNv, Nv3D,
381                                 NV30_TCL_PRIMITIVE_3D_TX_ADDRESS_UNIT(unit), 8);
382                 NVDmaNext (pNv, NVAccelGetPixmapOffset(pPix));
383                 NVDmaNext (pNv, (2 << 4)  /* 2D */ |
384                                 (fmt->card_fmt << 8) |
385                                 (1 << 13) /* NPOT */ |
386                                 (1<<16) /* 1 mipmap level */ |
387                                 (1<<0) /* NvDmaFB */ |
388                                 (1<<3) /* border disable? */);
389                 NVDmaNext (pNv, (card_repeat <<  0) /* S */ |
390                                 (card_repeat <<  8) /* T */ |
391                                 (card_repeat << 16) /* R */);
392                 NVDmaNext (pNv, 0x80000000);
393                 NVDmaNext (pNv, fmt->card_swz);
394                 NVDmaNext (pNv, (card_filter << 16) /* min */ |
395                                 (card_filter << 24) /* mag */ |
396                                 0x3fd6 /* engine lock */);
397                 NVDmaNext (pNv, (pPix->drawable.width << 16) | pPix->drawable.height);
398                 NVDmaNext (pNv, 0); /* border ARGB */
399                 NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_TX_DEPTH_UNIT(unit), 1);
400                 NVDmaNext (pNv, (1 << 20) /* depth */ |
401                                 (uint32_t)exaGetPixmapPitch(pPix));
402         }
403
404                 state->unit[unit].width         = (float)pPix->drawable.width;
405                 state->unit[unit].height        = (float)pPix->drawable.height;
406                 state->unit[unit].transform     = pPict->transform;
407
408         return TRUE;
409 }
410
411 static Bool
412 NV30_SetupSurface(ScrnInfoPtr pScrn, PixmapPtr pPix, PictFormatShort format)
413 {
414         NVPtr pNv = NVPTR(pScrn);
415         nv_pict_surface_format_t *fmt;
416
417         fmt = NV30_GetPictSurfaceFormat(format);
418         if (!fmt) {
419                 ErrorF("AIII no format\n");
420                 return FALSE;
421         }
422
423         NVDmaStart(pNv, Nv3D, 0x208, 3);
424         NVDmaNext (pNv, fmt->card_fmt);
425         NVDmaNext (pNv, (uint32_t)exaGetPixmapPitch(pPix));
426         NVDmaNext (pNv, NVAccelGetPixmapOffset(pPix));
427
428         return TRUE;
429 }
430
431 static Bool
432 NV30EXACheckCompositeTexture(PicturePtr pPict)
433 {
434         nv_pict_texture_format_t *fmt;
435         int w = pPict->pDrawable->width;
436         int h = pPict->pDrawable->height;
437
438         if ((w > 4096) || (h>4096))
439                 FALLBACK("picture too large, %dx%d\n", w, h);
440
441         fmt = NV30_GetPictTextureFormat(pPict->format);
442         if (!fmt)
443                 FALLBACK("picture format 0x%08x not supported\n",
444                                 pPict->format);
445
446         if (pPict->filter != PictFilterNearest &&
447                         pPict->filter != PictFilterBilinear)
448                 FALLBACK("filter 0x%x not supported\n", pPict->filter);
449
450         if (pPict->repeat && (pPict->repeat != RepeatNormal &&
451                                 pPict->repeatType != RepeatNone))
452                 FALLBACK("repeat 0x%x not supported\n", pPict->repeatType);
453
454         return TRUE;
455 }
456
457 Bool
458 NV30EXACheckComposite(int op, PicturePtr psPict,
459                               PicturePtr pmPict,
460                               PicturePtr pdPict)
461 {
462         nv_pict_surface_format_t *fmt;
463         nv_pict_op_t *opr;
464
465         opr = NV30_GetPictOpRec(op);
466         if (!opr)
467                 FALLBACK("unsupported blend op 0x%x\n", op);
468
469         fmt = NV30_GetPictSurfaceFormat(pdPict->format);
470         if (!fmt)
471                 FALLBACK("dst picture format 0x%08x not supported\n",
472                                 pdPict->format);
473
474         if (!NV30EXACheckCompositeTexture(psPict))
475                 FALLBACK("src picture\n");
476         if (pmPict) {
477                 if (pmPict->componentAlpha &&
478                                 PICT_FORMAT_RGB(pmPict->format) &&
479                                 opr->src_alpha && opr->src_card_op != BF(ZERO))
480                         FALLBACK("mask CA + SA\n");
481                 if (!NV30EXACheckCompositeTexture(pmPict))
482                         FALLBACK("mask picture\n");
483         }
484
485         return TRUE;
486 }
487
488 Bool
489 NV30EXAPrepareComposite(int op, PicturePtr psPict,
490                                 PicturePtr pmPict,
491                                 PicturePtr pdPict,
492                                 PixmapPtr  psPix,
493                                 PixmapPtr  pmPix,
494                                 PixmapPtr  pdPix)
495 {
496         ScrnInfoPtr pScrn = xf86Screens[psPix->drawable.pScreen->myNum];
497         NVPtr pNv = NVPTR(pScrn);
498         nv_pict_op_t *blend;
499         int fpid = NV30EXA_FPID_PASS_COL0;
500         NV30EXA_STATE;
501
502         blend = NV30_GetPictOpRec(op);
503
504         NV30_SetupBlend(pScrn, blend, pdPict->format,
505                         (pmPict && pmPict->componentAlpha &&
506                          PICT_FORMAT_RGB(pmPict->format)));
507
508         NV30_SetupSurface(pScrn, pdPix, pdPict->format);
509         NV30EXATexture(pScrn, psPix, psPict, 0);
510
511         NV30_LoadVtxProg(pScrn, &nv40_vp_exa_render);
512         if (pmPict) {
513                 NV30EXATexture(pScrn, pmPix, pmPict, 1);
514
515                 if (pmPict->componentAlpha && PICT_FORMAT_RGB(pmPict->format)) {
516                         if (blend->src_alpha)
517                                 fpid = NV30EXA_FPID_COMPOSITE_MASK_SA_CA;
518                         else
519                                 fpid = NV30EXA_FPID_COMPOSITE_MASK_CA;
520                 } else {
521                         fpid = NV30EXA_FPID_COMPOSITE_MASK;
522                 }
523
524                 state->have_mask = TRUE;
525         } else {
526                 fpid = NV30EXA_FPID_PASS_TEX0;
527
528                 state->have_mask = FALSE;
529         }
530
531         if (pdPict->format == PICT_a8)
532                 NV30_LoadFragProg(pScrn, nv40_fp_map_a8[fpid]);
533         else
534                 NV30_LoadFragProg(pScrn, nv40_fp_map[fpid]);
535
536         /* Appears to be some kind of cache flush, needed here at least
537          * sometimes.. funky text rendering otherwise :)
538          */
539         NVDmaStart(pNv, Nv3D, 0x1fd8, 1);
540         NVDmaNext (pNv, 2);
541         NVDmaStart(pNv, Nv3D, 0x1fd8, 1);
542         NVDmaNext (pNv, 1);
543
544         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_BEGIN_END, 1);
545         NVDmaNext (pNv, 8); /* GL_QUADS */
546
547         return TRUE;
548 }
549
550 #define xFixedToFloat(v) \
551         ((float)xFixedToInt((v)) + ((float)xFixedFrac(v) / 65536.0))
552
553 static void
554 NV30EXATransformCoord(PictTransformPtr t, int x, int y, float sx, float sy,
555                                           float *x_ret, float *y_ret)
556 {
557         PictVector v;
558
559         if (t) {
560                 v.vector[0] = IntToxFixed(x);
561                 v.vector[1] = IntToxFixed(y);
562                 v.vector[2] = xFixed1;
563                 PictureTransformPoint(t, &v);
564                 *x_ret = xFixedToFloat(v.vector[0]) / sx;
565                 *y_ret = xFixedToFloat(v.vector[1]) / sy;
566         } else {
567                 *x_ret = (float)x / sx;
568                 *y_ret = (float)y / sy;
569         }
570 }
571
572 #define CV_OUTm(sx,sy,mx,my,dx,dy) do {                                        \
573         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_VTX_ATTR_2F_X(8), 4);   \
574         NVDmaFloat(pNv, (sx)); NVDmaFloat(pNv, (sy));                          \
575         NVDmaFloat(pNv, (mx)); NVDmaFloat(pNv, (my));                          \
576         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_VTX_ATTR_2I(0), 1);     \
577         NVDmaNext (pNv, ((dy)<<16)|(dx));                                      \
578 } while(0)
579 #define CV_OUT(sx,sy,dx,dy) do {                                               \
580         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_VTX_ATTR_2F_X(8), 2);   \
581         NVDmaFloat(pNv, (sx)); NVDmaFloat(pNv, (sy));                          \
582         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_VTX_ATTR_2I(0), 1);     \
583         NVDmaNext (pNv, ((dy)<<16)|(dx));                                      \
584 } while(0)
585
586 void
587 NV30EXAComposite(PixmapPtr pdPix, int srcX , int srcY,
588                                   int maskX, int maskY,
589                                   int dstX , int dstY,
590                                   int width, int height)
591 {
592         ScrnInfoPtr pScrn = xf86Screens[pdPix->drawable.pScreen->myNum];
593         NVPtr pNv = NVPTR(pScrn);
594         float sX0, sX1, sY0, sY1;
595         float mX0, mX1, mY0, mY1;
596         NV30EXA_STATE;
597
598         NV30EXATransformCoord(state->unit[0].transform, srcX, srcY,
599                               state->unit[0].width,
600                               state->unit[0].height, &sX0, &sY0);
601         NV30EXATransformCoord(state->unit[0].transform,
602                               srcX + width, srcY + height,
603                               state->unit[0].width,
604                               state->unit[0].height, &sX1, &sY1);
605
606         if (state->have_mask) {
607                 NV30EXATransformCoord(state->unit[1].transform, maskX, maskY,
608                                       state->unit[1].width,
609                                       state->unit[1].height, &mX0, &mY0);
610                 NV30EXATransformCoord(state->unit[1].transform,
611                                       maskX + width, maskY + height,
612                                       state->unit[1].width,
613                                       state->unit[1].height, &mX1, &mY1);
614                 CV_OUTm(sX0 , sY0 , mX0, mY0, dstX        ,          dstY);
615                 CV_OUTm(sX1 , sY0 , mX1, mY0, dstX + width,          dstY);
616                 CV_OUTm(sX1 , sY1 , mX1, mY1, dstX + width, dstY + height);
617                 CV_OUTm(sX0 , sY1 , mX0, mY1, dstX        , dstY + height);
618         } else {
619                 CV_OUT(sX0 , sY0 , dstX        ,          dstY);
620                 CV_OUT(sX1 , sY0 , dstX + width,          dstY);
621                 CV_OUT(sX1 , sY1 , dstX + width, dstY + height);
622                 CV_OUT(sX0 , sY1 , dstX        , dstY + height);
623         }
624
625         NVDmaKickoff(pNv);
626 }
627
628 void
629 NV30EXADoneComposite(PixmapPtr pdPix)
630 {
631         ScrnInfoPtr pScrn = xf86Screens[pdPix->drawable.pScreen->myNum];
632         NVPtr pNv = NVPTR(pScrn);
633
634         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_BEGIN_END, 1);
635         NVDmaNext (pNv, 0);
636 }
637
638 Bool
639 NVAccelInitNV30TCL(ScrnInfoPtr pScrn)
640 {
641         NVPtr pNv = NVPTR(pScrn);
642         static int have_object = FALSE;
643         uint32_t class = 0, chipset;
644         int i;
645
646 #undef  NV30_TCL_PRIMITIVE_3D
647 #define NV30_TCL_PRIMITIVE_3D                 0x0397
648 #define NV30_TCL_PRIMITIVE_3D_CHIPSET_3X_MASK 0x00000003
649 #define NV35_TCL_PRIMITIVE_3D                 0x0497
650 #define NV35_TCL_PRIMITIVE_3D_CHIPSET_3X_MASK 0x000001e0
651 #define NV34_TCL_PRIMITIVE_3D                 0x0697
652 #define NV34_TCL_PRIMITIVE_3D_CHIPSET_3X_MASK 0x00000010
653
654         chipset = (nvReadMC(pNv, 0) >> 20) & 0xff;
655         if ((chipset & 0xf0) != NV_ARCH_30)
656                 return TRUE;
657         chipset &= 0xf;
658
659         if (NV30_TCL_PRIMITIVE_3D_CHIPSET_3X_MASK & (1<<chipset))
660                 class = NV30_TCL_PRIMITIVE_3D;
661         else if (NV35_TCL_PRIMITIVE_3D_CHIPSET_3X_MASK & (1<<chipset))
662                 class = NV35_TCL_PRIMITIVE_3D;
663         else if (NV34_TCL_PRIMITIVE_3D_CHIPSET_3X_MASK & (1<<chipset))
664                 class = NV34_TCL_PRIMITIVE_3D;
665         else {
666                 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
667                            "NV30EXA: Unknown chipset NV3%1x\n", chipset);
668                 return FALSE;
669         }
670
671         if (!have_object) {
672                 if (!NVDmaCreateContextObject(pNv, Nv3D, class))
673                         return FALSE;
674                 have_object = TRUE;
675         }
676
677         NVDmaStart(pNv, Nv3D, 0x180, 1);
678         NVDmaNext (pNv, NvDmaNotifier0);
679         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT1, 3);
680         NVDmaNext (pNv, NvDmaFB);
681         NVDmaNext (pNv, NvDmaFB);
682         NVDmaNext (pNv, NvDmaFB);
683         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT8, 1);
684         NVDmaNext (pNv, NvDmaFB);
685         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT4, 2);
686         NVDmaNext (pNv, NvDmaFB);
687         NVDmaNext (pNv, NvDmaFB);
688         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT3, 1);
689         NVDmaNext (pNv, NvDmaFB);
690         NVDmaStart(pNv, Nv3D, 0x1b0, 1);
691         NVDmaNext (pNv, NvDmaFB);
692
693         NVDmaStart(pNv, Nv3D, 0x2b8, 1);
694         NVDmaNext(pNv, 0);
695         NVDmaStart(pNv, Nv3D, 0x200, 2);
696         NVDmaNext(pNv, 0);
697         NVDmaNext(pNv, 0);
698         NVDmaStart(pNv, Nv3D, 0x2c0, 1);
699         NVDmaNext(pNv, 0x0fff0000);
700         NVDmaStart(pNv, Nv3D, 0x2c4, 1);
701         NVDmaNext(pNv, 0x0fff0000);
702         /* voodoo */
703         for(i = 0x2c8; i <= 0x2fc; i += 4)
704         {
705                 NVDmaStart(pNv, Nv3D, i, 1);
706                 NVDmaNext(pNv, 0x0);
707         }
708         NVDmaStart(pNv, Nv3D, 0x02bc, 1);
709         NVDmaNext(pNv, 0);
710         NVDmaStart(pNv, Nv3D, 0x0220, 1);
711         NVDmaNext(pNv, 1);
712         NVDmaStart(pNv, Nv3D, 0x03b0, 1);
713         NVDmaNext(pNv, 0x00100000);
714         NVDmaStart(pNv, Nv3D, 0x1454, 1);
715         NVDmaNext(pNv, 0);
716         NVDmaStart(pNv, Nv3D, 0x1d80, 1);
717         NVDmaNext(pNv, 3);
718         NVDmaStart(pNv, Nv3D, 0x1450, 1);
719         NVDmaNext(pNv, 0x00030004);
720
721         /* NEW */
722         NVDmaStart(pNv, Nv3D, 0x1e98, 1);
723         NVDmaNext(pNv, 0);
724         NVDmaStart(pNv, Nv3D, 0x17e0, 3);
725         NVDmaNext(pNv, 0);
726         NVDmaNext(pNv, 0);
727         NVDmaNext(pNv, 0x3f800000);
728         NVDmaStart(pNv, Nv3D, 0x1f80, 16);
729         NVDmaNext(pNv, 0); 
730         NVDmaNext(pNv, 0); 
731         NVDmaNext(pNv, 0); 
732         NVDmaNext(pNv, 0);
733         NVDmaNext(pNv, 0); 
734         NVDmaNext(pNv, 0); 
735         NVDmaNext(pNv, 0); 
736         NVDmaNext(pNv, 0);
737         NVDmaNext(pNv, 0x0000ffff);
738         NVDmaNext(pNv, 0); 
739         NVDmaNext(pNv, 0); 
740         NVDmaNext(pNv, 0); 
741         NVDmaNext(pNv, 0);
742         NVDmaNext(pNv, 0); 
743         NVDmaNext(pNv, 0); 
744         NVDmaNext(pNv, 0);
745
746         NVDmaStart(pNv, Nv3D, 0x120, 3);
747         NVDmaNext(pNv, 0);
748         NVDmaNext(pNv, 1);
749         NVDmaNext(pNv, 2);
750
751         NVDmaStart(pNv, Nv3D, 0x1d88, 1);
752         NVDmaNext(pNv, 0x00001200);
753
754         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_RC_ENABLE, 1);
755         NVDmaNext       (pNv, 0);
756
757
758         /* identity viewport transform */
759         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_XFRM_OX, 8);
760         NVDmaFloat(pNv, 0.0);
761         NVDmaFloat(pNv, 0.0);
762         NVDmaFloat(pNv, 0.0);
763         NVDmaFloat(pNv, 0.0);
764         NVDmaFloat(pNv, 1.0);
765         NVDmaFloat(pNv, 1.0);
766         NVDmaFloat(pNv, 1.0);
767         NVDmaFloat(pNv, 0.0);
768
769         /* default 3D state */
770         /*XXX: replace with the same state that the DRI emits on startup */
771         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_ENABLE, 1);
772         NVDmaNext (pNv, 0);
773         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_ENABLE, 1);
774         NVDmaNext (pNv, 0);
775         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE, 1);
776         NVDmaNext (pNv, 0);
777         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE, 2);
778         NVDmaNext (pNv, 0); /* wr disable */
779         NVDmaNext (pNv, 0); /* test disable */
780         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_COLOR_MASK, 1);
781         NVDmaNext (pNv, 0x01010101); /* TR,TR,TR,TR */
782         NVDmaStart(pNv, Nv3D, NV40_TCL_PRIMITIVE_3D_COLOR_MASK_BUFFER123, 1);
783         NVDmaNext (pNv, 0x0000fff0);
784         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE, 1);
785         NVDmaNext (pNv, 0);
786         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE, 1);
787         NVDmaNext (pNv, 0);
788         NVDmaStart(pNv, Nv3D,
789                         NV30_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE, 2);
790         NVDmaNext (pNv, 0);
791         NVDmaNext (pNv, 0x1503);
792         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_DITHER_ENABLE, 1);
793         NVDmaNext (pNv, 0);
794         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_SHADE_MODEL, 1);
795         NVDmaNext (pNv, 0x1d01); /* GL_SMOOTH */
796         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR,2);
797         NVDmaFloat(pNv, 0.0);
798         NVDmaFloat(pNv, 0.0);
799         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT, 2);
800         NVDmaNext (pNv, 0x1b02); /* FRONT = GL_FILL */
801         NVDmaNext (pNv, 0x1b02); /* BACK  = GL_FILL */
802         NVDmaStart(pNv, Nv3D,
803                         NV30_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_PATTERN(0), 0x20);
804         for (i=0;i<0x20;i++)
805                 NVDmaNext(pNv, 0xFFFFFFFF);
806         for (i=0;i<16;i++) {
807                 NVDmaStart(pNv, Nv3D,
808                                 NV30_TCL_PRIMITIVE_3D_TX_ENABLE_UNIT(i), 1);
809                 NVDmaNext(pNv, 0);
810         }
811
812         NVDmaStart(pNv, Nv3D, 0x1d78, 1);
813         NVDmaNext (pNv, 0x110);
814
815         NVDmaStart(pNv, Nv3D, 0x0220, 1);
816         NVDmaNext (pNv, 1);
817         NVDmaStart(pNv, Nv3D,
818                         NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_DIM0, 2);
819         NVDmaNext (pNv, (4096 << 16));
820         NVDmaNext (pNv, (4096 << 16));
821         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_SCISSOR_WIDTH_XPOS, 2);
822         NVDmaNext (pNv, (4096 << 16));
823         NVDmaNext (pNv, (4096 << 16));
824         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_DIMS_0, 2);
825         NVDmaNext (pNv, (4096 << 16));
826         NVDmaNext (pNv, (4096 << 16));
827         NVDmaStart(pNv, Nv3D,
828                         NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_OFS0, 2);
829         NVDmaNext (pNv, (4095 << 16));
830         NVDmaNext (pNv, (4095 << 16));
831
832         return TRUE;
833 }
834
835 Bool
836 NVAccelInitNV40TCL(ScrnInfoPtr pScrn)
837 {
838         NVPtr pNv = NVPTR(pScrn);
839         static int have_object = FALSE;
840         uint32_t class = 0, chipset;
841         int i;
842
843         NV30EXAHackupA8Shaders(pScrn);
844
845 #undef  NV40_TCL_PRIMITIVE_3D
846 #define NV40_TCL_PRIMITIVE_3D                 0x4097
847 #define NV40_TCL_PRIMITIVE_3D_CHIPSET_4X_MASK 0x00000baf
848 #define NV44_TCL_PRIMITIVE_3D                 0x4497
849 #define NV44_TCL_PRIMITIVE_3D_CHIPSET_4X_MASK 0x00005450
850
851         chipset = (nvReadMC(pNv, 0) >> 20) & 0xff;
852         if ((chipset & 0xf0) != NV_ARCH_40)
853                 return TRUE;
854         chipset &= 0xf;
855
856         if (NV40_TCL_PRIMITIVE_3D_CHIPSET_4X_MASK & (1<<chipset))
857                 class = NV40_TCL_PRIMITIVE_3D;
858         else if (NV44_TCL_PRIMITIVE_3D_CHIPSET_4X_MASK & (1<<chipset))
859                 class = NV44_TCL_PRIMITIVE_3D;
860         else {
861                 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
862                            "NV30EXA: Unknown chipset NV4%1x\n", chipset);
863                 return FALSE;
864         }
865
866         if (!have_object) {
867                 if (!NVDmaCreateContextObject(pNv, Nv3D, class))
868                         return FALSE;
869                 have_object = TRUE;
870         }
871
872         NVDmaStart(pNv, Nv3D, 0x180, 1);
873         NVDmaNext (pNv, NvDmaNotifier0);
874         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT1, 2);
875         NVDmaNext (pNv, NvDmaFB);
876         NVDmaNext (pNv, NvDmaFB);
877         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT8, 1);
878         NVDmaNext (pNv, NvDmaFB);
879         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT4, 2);
880         NVDmaNext (pNv, NvDmaFB);
881         NVDmaNext (pNv, NvDmaFB);
882
883         /* voodoo */
884         NVDmaStart(pNv, Nv3D, 0x1ea4, 3);
885         NVDmaNext(pNv, 0x00000010);
886         NVDmaNext(pNv, 0x01000100);
887         NVDmaNext(pNv, 0xff800006);
888         NVDmaStart(pNv, Nv3D, 0x1fc4, 1);
889         NVDmaNext(pNv, 0x06144321);
890         NVDmaStart(pNv, Nv3D, 0x1fc8, 2);
891         NVDmaNext(pNv, 0xedcba987);
892         NVDmaNext(pNv, 0x00000021);
893         NVDmaStart(pNv, Nv3D, 0x1fd0, 1);
894         NVDmaNext(pNv, 0x00171615);
895         NVDmaStart(pNv, Nv3D, 0x1fd4, 1);
896         NVDmaNext(pNv, 0x001b1a19);
897         NVDmaStart(pNv, Nv3D, 0x1ef8, 1);
898         NVDmaNext(pNv, 0x0020ffff);
899         NVDmaStart(pNv, Nv3D, 0x1d64, 1);
900         NVDmaNext(pNv, 0x00d30000);
901         NVDmaStart(pNv, Nv3D, 0x1e94, 1);
902         NVDmaNext(pNv, 0x00000001);
903
904         /* identity viewport transform */
905         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_XFRM_OX, 8);
906         NVDmaFloat(pNv, 0.0);
907         NVDmaFloat(pNv, 0.0);
908         NVDmaFloat(pNv, 0.0);
909         NVDmaFloat(pNv, 0.0);
910         NVDmaFloat(pNv, 1.0);
911         NVDmaFloat(pNv, 1.0);
912         NVDmaFloat(pNv, 1.0);
913         NVDmaFloat(pNv, 0.0);
914
915         /* default 3D state */
916         /*XXX: replace with the same state that the DRI emits on startup */
917         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_ENABLE, 1);
918         NVDmaNext (pNv, 0);
919         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_ENABLE, 1);
920         NVDmaNext (pNv, 0);
921         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE, 1);
922         NVDmaNext (pNv, 0);
923         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE, 2);
924         NVDmaNext (pNv, 0); /* wr disable */
925         NVDmaNext (pNv, 0); /* test disable */
926         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_COLOR_MASK, 1);
927         NVDmaNext (pNv, 0x01010101); /* TR,TR,TR,TR */
928         NVDmaStart(pNv, Nv3D, NV40_TCL_PRIMITIVE_3D_COLOR_MASK_BUFFER123, 1);
929         NVDmaNext (pNv, 0x0000fff0);
930         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE, 1);
931         NVDmaNext (pNv, 0);
932         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE, 1);
933         NVDmaNext (pNv, 0);
934         NVDmaStart(pNv, Nv3D,
935                         NV30_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE, 2);
936         NVDmaNext (pNv, 0);
937         NVDmaNext (pNv, 0x1503);
938         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_DITHER_ENABLE, 1);
939         NVDmaNext (pNv, 0);
940         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_SHADE_MODEL, 1);
941         NVDmaNext (pNv, 0x1d01); /* GL_SMOOTH */
942         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR,2);
943         NVDmaFloat(pNv, 0.0);
944         NVDmaFloat(pNv, 0.0);
945         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT, 2);
946         NVDmaNext (pNv, 0x1b02); /* FRONT = GL_FILL */
947         NVDmaNext (pNv, 0x1b02); /* BACK  = GL_FILL */
948         NVDmaStart(pNv, Nv3D,
949                         NV30_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_PATTERN(0), 0x20);
950         for (i=0;i<0x20;i++)
951                 NVDmaNext(pNv, 0xFFFFFFFF);
952         for (i=0;i<16;i++) {
953                 NVDmaStart(pNv, Nv3D,
954                                 NV30_TCL_PRIMITIVE_3D_TX_ENABLE_UNIT(i), 1);
955                 NVDmaNext(pNv, 0);
956         }
957
958         NVDmaStart(pNv, Nv3D, 0x1d78, 1);
959         NVDmaNext (pNv, 0x110);
960
961         NVDmaStart(pNv, Nv3D, 0x0220, 1);
962         NVDmaNext (pNv, 1);
963         NVDmaStart(pNv, Nv3D,
964                         NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_DIM0, 2);
965         NVDmaNext (pNv, (4096 << 16));
966         NVDmaNext (pNv, (4096 << 16));
967         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_SCISSOR_WIDTH_XPOS, 2);
968         NVDmaNext (pNv, (4096 << 16));
969         NVDmaNext (pNv, (4096 << 16));
970         NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_DIMS_0, 2);
971         NVDmaNext (pNv, (4096 << 16));
972         NVDmaNext (pNv, (4096 << 16));
973         NVDmaStart(pNv, Nv3D,
974                         NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_OFS0, 2);
975         NVDmaNext (pNv, (4095 << 16));
976         NVDmaNext (pNv, (4095 << 16));
977
978         return TRUE;
979 }
980
981 #endif /* ENABLE_NV30EXA */