Merge branch 'master' of git+ssh://znh@git.freedesktop.org/git/mesa/mesa
[mesa.git] / src / mesa / drivers / dri / nouveau / nv10_swtcl.c
1 /*
2 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
4 * Copyright 2006 Stephane Marchesin. All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sub license,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
15 * of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
20 * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
24 */
25
26 /* Software TCL for NV10, NV20, NV30, NV40, NV50 */
27
28 #include <stdio.h>
29 #include <math.h>
30
31 #include "glheader.h"
32 #include "context.h"
33 #include "mtypes.h"
34 #include "macros.h"
35 #include "colormac.h"
36 #include "enums.h"
37
38 #include "swrast/swrast.h"
39 #include "swrast_setup/swrast_setup.h"
40 #include "tnl/t_context.h"
41 #include "tnl/t_pipeline.h"
42
43 #include "nouveau_swtcl.h"
44 #include "nv10_swtcl.h"
45 #include "nouveau_context.h"
46 #include "nouveau_span.h"
47 #include "nouveau_reg.h"
48 #include "nouveau_tex.h"
49 #include "nouveau_fifo.h"
50 #include "nouveau_msg.h"
51 #include "nouveau_object.h"
52
53 static void nv10RasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim );
54 static void nv10RenderPrimitive( GLcontext *ctx, GLenum prim );
55 static void nv10ResetLineStipple( GLcontext *ctx );
56
57
58
59 static inline void nv10StartPrimitive(struct nouveau_context* nmesa,uint32_t primitive,uint32_t size)
60 {
61 if (nmesa->screen->card->type==NV_10)
62 BEGIN_RING_SIZE(NvSub3D,NV10_TCL_PRIMITIVE_3D_BEGIN_END,1);
63 else if (nmesa->screen->card->type==NV_20)
64 BEGIN_RING_SIZE(NvSub3D,NV20_TCL_PRIMITIVE_3D_BEGIN_END,1);
65 else
66 BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_BEGIN_END,1);
67 OUT_RING(primitive);
68
69 if (nmesa->screen->card->type==NV_10)
70 BEGIN_RING_SIZE(NvSub3D,NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_DATA|NONINC_METHOD,size);
71 else if (nmesa->screen->card->type==NV_20)
72 BEGIN_RING_SIZE(NvSub3D,NV20_TCL_PRIMITIVE_3D_VERTEX_DATA|NONINC_METHOD,size);
73 else
74 BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_VERTEX_DATA|NONINC_METHOD,size);
75 }
76
77 inline void nv10FinishPrimitive(struct nouveau_context *nmesa)
78 {
79 if (nmesa->screen->card->type==NV_10)
80 BEGIN_RING_SIZE(NvSub3D,NV10_TCL_PRIMITIVE_3D_BEGIN_END,1);
81 else if (nmesa->screen->card->type==NV_20)
82 BEGIN_RING_SIZE(NvSub3D,NV20_TCL_PRIMITIVE_3D_BEGIN_END,1);
83 else
84 BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_BEGIN_END,1);
85 OUT_RING(0x0);
86 FIRE_RING();
87 }
88
89
90 static inline void nv10ExtendPrimitive(struct nouveau_context* nmesa, int size)
91 {
92 /* make sure there's enough room. if not, wait */
93 if (RING_AVAILABLE()<size)
94 {
95 WAIT_RING(nmesa,size);
96 }
97 }
98
99 /**********************************************************************/
100 /* Render unclipped begin/end objects */
101 /**********************************************************************/
102
103 static inline void nv10_render_generic_primitive_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags,GLuint prim)
104 {
105 struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
106 GLubyte *vertptr = (GLubyte *)nmesa->verts;
107 GLuint vertsize = nmesa->vertex_size;
108 GLuint size_dword = vertsize*(count-start)/4;
109
110 nv10ExtendPrimitive(nmesa, size_dword);
111 nv10StartPrimitive(nmesa,prim+1,size_dword);
112 OUT_RINGp((nouveauVertex*)(vertptr+(start*vertsize)),size_dword);
113 nv10FinishPrimitive(nmesa);
114 }
115
116 static void nv10_render_points_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
117 {
118 nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_POINTS);
119 }
120
121 static void nv10_render_lines_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
122 {
123 nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_LINES);
124 }
125
126 static void nv10_render_line_strip_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
127 {
128 nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_LINE_STRIP);
129 }
130
131 static void nv10_render_line_loop_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
132 {
133 nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_LINE_LOOP);
134 }
135
136 static void nv10_render_triangles_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
137 {
138 nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_TRIANGLES);
139 }
140
141 static void nv10_render_tri_strip_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
142 {
143 nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_TRIANGLE_STRIP);
144 }
145
146 static void nv10_render_tri_fan_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
147 {
148 nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_TRIANGLE_FAN);
149 }
150
151 static void nv10_render_quads_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
152 {
153 nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_QUADS);
154 }
155
156 static void nv10_render_quad_strip_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
157 {
158 nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_QUAD_STRIP);
159 }
160
161 static void nv10_render_poly_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
162 {
163 nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_POLYGON);
164 }
165
166 static void nv10_render_noop_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
167 {
168 }
169
170 static void (*nv10_render_tab_verts[GL_POLYGON+2])(GLcontext *,
171 GLuint,
172 GLuint,
173 GLuint) =
174 {
175 nv10_render_points_verts,
176 nv10_render_lines_verts,
177 nv10_render_line_loop_verts,
178 nv10_render_line_strip_verts,
179 nv10_render_triangles_verts,
180 nv10_render_tri_strip_verts,
181 nv10_render_tri_fan_verts,
182 nv10_render_quads_verts,
183 nv10_render_quad_strip_verts,
184 nv10_render_poly_verts,
185 nv10_render_noop_verts,
186 };
187
188
189 static inline void nv10_render_generic_primitive_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags,GLuint prim)
190 {
191 struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
192 GLubyte *vertptr = (GLubyte *)nmesa->verts;
193 GLuint vertsize = nmesa->vertex_size;
194 GLuint size_dword = vertsize*(count-start)/4;
195 const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts;
196 GLuint j;
197
198 nv10ExtendPrimitive(nmesa, size_dword);
199 nv10StartPrimitive(nmesa,prim+1,size_dword);
200 for (j=start; j<count; j++ ) {
201 OUT_RINGp((nouveauVertex*)(vertptr+(elt[j]*vertsize)),vertsize);
202 }
203 nv10FinishPrimitive(nmesa);
204 }
205
206 static void nv10_render_points_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
207 {
208 nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_POINTS);
209 }
210
211 static void nv10_render_lines_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
212 {
213 nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_LINES);
214 }
215
216 static void nv10_render_line_strip_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
217 {
218 nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_LINE_STRIP);
219 }
220
221 static void nv10_render_line_loop_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
222 {
223 nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_LINE_LOOP);
224 }
225
226 static void nv10_render_triangles_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
227 {
228 nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_TRIANGLES);
229 }
230
231 static void nv10_render_tri_strip_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
232 {
233 nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_TRIANGLE_STRIP);
234 }
235
236 static void nv10_render_tri_fan_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
237 {
238 nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_TRIANGLE_FAN);
239 }
240
241 static void nv10_render_quads_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
242 {
243 nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_QUADS);
244 }
245
246 static void nv10_render_quad_strip_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
247 {
248 nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_QUAD_STRIP);
249 }
250
251 static void nv10_render_poly_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
252 {
253 nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_POLYGON);
254 }
255
256 static void nv10_render_noop_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
257 {
258 }
259
260 static void (*nv10_render_tab_elts[GL_POLYGON+2])(GLcontext *,
261 GLuint,
262 GLuint,
263 GLuint) =
264 {
265 nv10_render_points_elts,
266 nv10_render_lines_elts,
267 nv10_render_line_loop_elts,
268 nv10_render_line_strip_elts,
269 nv10_render_triangles_elts,
270 nv10_render_tri_strip_elts,
271 nv10_render_tri_fan_elts,
272 nv10_render_quads_elts,
273 nv10_render_quad_strip_elts,
274 nv10_render_poly_elts,
275 nv10_render_noop_elts,
276 };
277
278
279 /**********************************************************************/
280 /* Choose render functions */
281 /**********************************************************************/
282
283
284 #define EMIT_ATTR( ATTR, STYLE ) \
285 do { \
286 nmesa->vertex_attrs[nmesa->vertex_attr_count].attrib = (ATTR); \
287 nmesa->vertex_attrs[nmesa->vertex_attr_count].format = (STYLE); \
288 nmesa->vertex_attr_count++; \
289 } while (0)
290
291 static void nv10_render_clipped_line(GLcontext *ctx,GLuint ii,GLuint jj)
292 {
293
294 }
295
296 static void nv10_render_clipped_poly(GLcontext *ctx,const GLuint *elts,GLuint n)
297 {
298 TNLcontext *tnl = TNL_CONTEXT(ctx);
299 struct vertex_buffer *VB = &tnl->vb;
300 GLuint *tmp = VB->Elts;
301 VB->Elts = (GLuint *)elts;
302 nv10_render_generic_primitive_elts( ctx, 0, n, PRIM_BEGIN|PRIM_END,GL_POLYGON );
303 VB->Elts = tmp;
304 }
305
306 static void nv10ChooseRenderState(GLcontext *ctx)
307 {
308 TNLcontext *tnl = TNL_CONTEXT(ctx);
309 struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
310
311 tnl->Driver.Render.PrimTabVerts = nv10_render_tab_verts;
312 tnl->Driver.Render.PrimTabElts = nv10_render_tab_elts;
313 tnl->Driver.Render.ClippedLine = nv10_render_clipped_line;
314 tnl->Driver.Render.ClippedPolygon = nv10_render_clipped_poly;
315 }
316
317
318
319 static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa)
320 {
321 GLcontext* ctx=nmesa->glCtx;
322 TNLcontext *tnl = TNL_CONTEXT(ctx);
323 DECLARE_RENDERINPUTS(index);
324 struct vertex_buffer *VB = &tnl->vb;
325 int attr_size[16];
326 int default_attr_size[8]={3,3,3,4,3,1,4,4};
327 int i;
328 int slots=0;
329 int total_size=0;
330 /* t_vertex_generic dereferences a NULL pointer if we
331 * pass NULL as the vp transform...
332 */
333 const GLfloat ident_vp[16] = {
334 1.0, 0.0, 0.0, 0.0,
335 0.0, 1.0, 0.0, 0.0,
336 0.0, 0.0, 1.0, 0.0,
337 0.0, 0.0, 0.0, 1.0
338 };
339
340 nmesa->vertex_attr_count = 0;
341 RENDERINPUTS_COPY(index, nmesa->render_inputs_bitset);
342
343 /*
344 * Determine attribute sizes
345 */
346 for(i=0;i<8;i++)
347 {
348 if (RENDERINPUTS_TEST(index, i))
349 attr_size[i]=default_attr_size[i];
350 else
351 attr_size[i]=0;
352 }
353 for(i=8;i<16;i++)
354 {
355 if (RENDERINPUTS_TEST(index, i))
356 attr_size[i]=VB->TexCoordPtr[i-8]->size;
357 else
358 attr_size[i]=0;
359 }
360
361 /*
362 * Tell t_vertex about the vertex format
363 */
364 for(i=0;i<16;i++)
365 {
366 if (RENDERINPUTS_TEST(index, i))
367 {
368 slots=i+1;
369 if (i==_TNL_ATTRIB_POS)
370 {
371 /* special-case POS */
372 EMIT_ATTR(_TNL_ATTRIB_POS,EMIT_3F_VIEWPORT);
373 }
374 else
375 {
376 switch(attr_size[i])
377 {
378 case 1:
379 EMIT_ATTR(i,EMIT_1F);
380 break;
381 case 2:
382 EMIT_ATTR(i,EMIT_2F);
383 break;
384 case 3:
385 EMIT_ATTR(i,EMIT_3F);
386 break;
387 case 4:
388 EMIT_ATTR(i,EMIT_4F);
389 break;
390 }
391 }
392 if (i==_TNL_ATTRIB_COLOR0)
393 nmesa->color_offset=total_size;
394 if (i==_TNL_ATTRIB_COLOR1)
395 nmesa->specular_offset=total_size;
396 total_size+=attr_size[i];
397 }
398 }
399
400 nmesa->vertex_size=_tnl_install_attrs( ctx,
401 nmesa->vertex_attrs,
402 nmesa->vertex_attr_count,
403 ident_vp, 0 );
404 assert(nmesa->vertex_size==total_size*4);
405
406 /*
407 * Tell the hardware about the vertex format
408 */
409 if (nmesa->screen->card->type==NV_10) {
410 int size;
411
412 #define NV_VERTEX_ATTRIBUTE_TYPE_FLOAT 2
413
414 #define NV10_SET_VERTEX_ATTRIB(i,j) \
415 do { \
416 size = attr_size[j] << 4; \
417 size |= (attr_size[j]*4) << 8; \
418 size |= NV_VERTEX_ATTRIBUTE_TYPE_FLOAT; \
419 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VERTEX_ATTR(i),1); \
420 OUT_RING_CACHE(size); \
421 } while (0)
422
423 NV10_SET_VERTEX_ATTRIB(0, _TNL_ATTRIB_POS);
424 NV10_SET_VERTEX_ATTRIB(1, _TNL_ATTRIB_COLOR0);
425 NV10_SET_VERTEX_ATTRIB(2, _TNL_ATTRIB_COLOR1);
426 NV10_SET_VERTEX_ATTRIB(3, _TNL_ATTRIB_TEX0);
427 NV10_SET_VERTEX_ATTRIB(4, _TNL_ATTRIB_TEX1);
428 NV10_SET_VERTEX_ATTRIB(5, _TNL_ATTRIB_NORMAL);
429 NV10_SET_VERTEX_ATTRIB(6, _TNL_ATTRIB_WEIGHT);
430 NV10_SET_VERTEX_ATTRIB(7, _TNL_ATTRIB_FOG);
431
432 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_VALIDATE,1);
433 OUT_RING_CACHE(0);
434 } else if (nmesa->screen->card->type==NV_20) {
435 for(i=0;i<16;i++)
436 {
437 int size=attr_size[i];
438 BEGIN_RING_CACHE(NvSub3D,NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR(i),1);
439 OUT_RING_CACHE(NV_VERTEX_ATTRIBUTE_TYPE_FLOAT|(size*0x10));
440 }
441 } else {
442 BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DO_VERTICES, 1);
443 OUT_RING(0);
444 BEGIN_RING_CACHE(NvSub3D,NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR0_POS,slots);
445 for(i=0;i<slots;i++)
446 {
447 int size=attr_size[i];
448 OUT_RING_CACHE(NV_VERTEX_ATTRIBUTE_TYPE_FLOAT|(size*0x10));
449 }
450 // FIXME this is probably not needed
451 BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_VERTEX_UNK_0,1);
452 OUT_RING(0);
453 BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_VERTEX_UNK_0,1);
454 OUT_RING(0);
455 BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_VERTEX_UNK_0,1);
456 OUT_RING(0);
457 }
458 }
459
460
461 static void nv10ChooseVertexState( GLcontext *ctx )
462 {
463 struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
464 TNLcontext *tnl = TNL_CONTEXT(ctx);
465 DECLARE_RENDERINPUTS(index);
466
467 RENDERINPUTS_COPY(index, tnl->render_inputs_bitset);
468 if (!RENDERINPUTS_EQUAL(index, nmesa->render_inputs_bitset))
469 {
470 RENDERINPUTS_COPY(nmesa->render_inputs_bitset, index);
471 nv10OutputVertexFormat(nmesa);
472 }
473
474 if (nmesa->screen->card->type >= NV_40) {
475 /* Ensure passthrough shader is being used, and mvp matrix
476 * is up to date
477 */
478 nvsUpdateShader(ctx, nmesa->passthrough_vp);
479
480 /* Update texenv shader / user fragprog */
481 nvsUpdateShader(ctx, (nouveauShader*)ctx->FragmentProgram._Current);
482 }
483 }
484
485
486 /**********************************************************************/
487 /* High level hooks for t_vb_render.c */
488 /**********************************************************************/
489
490
491 static void nv10RenderStart(GLcontext *ctx)
492 {
493 TNLcontext *tnl = TNL_CONTEXT(ctx);
494 struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
495
496 if (nmesa->new_state) {
497 nmesa->new_render_state |= nmesa->new_state;
498 }
499
500 if (nmesa->new_render_state) {
501 nv10ChooseVertexState(ctx);
502 nv10ChooseRenderState(ctx);
503 nmesa->new_render_state = 0;
504 }
505 }
506
507 static void nv10RenderFinish(GLcontext *ctx)
508 {
509 }
510
511
512 /* System to flush dma and emit state changes based on the rasterized
513 * primitive.
514 */
515 void nv10RasterPrimitive(GLcontext *ctx,
516 GLenum glprim,
517 GLuint hwprim)
518 {
519 struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
520
521 assert (!nmesa->new_state);
522
523 if (hwprim != nmesa->current_primitive)
524 {
525 nmesa->current_primitive=hwprim;
526
527 }
528 }
529
530 static const GLuint hw_prim[GL_POLYGON+1] = {
531 GL_POINTS+1,
532 GL_LINES+1,
533 GL_LINE_STRIP+1,
534 GL_LINE_LOOP+1,
535 GL_TRIANGLES+1,
536 GL_TRIANGLE_STRIP+1,
537 GL_TRIANGLE_FAN+1,
538 GL_QUADS+1,
539 GL_QUAD_STRIP+1,
540 GL_POLYGON+1
541 };
542
543 /* Callback for mesa:
544 */
545 static void nv10RenderPrimitive( GLcontext *ctx, GLuint prim )
546 {
547 nv10RasterPrimitive( ctx, prim, hw_prim[prim] );
548 }
549
550 static void nv10ResetLineStipple( GLcontext *ctx )
551 {
552 /* FIXME do something here */
553 WARN_ONCE("Unimplemented nv10ResetLineStipple\n");
554 }
555
556
557 /**********************************************************************/
558 /* Initialization. */
559 /**********************************************************************/
560
561 void nv10TriInitFunctions(GLcontext *ctx)
562 {
563 struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
564 TNLcontext *tnl = TNL_CONTEXT(ctx);
565
566 tnl->Driver.RunPipeline = nouveauRunPipeline;
567 tnl->Driver.Render.Start = nv10RenderStart;
568 tnl->Driver.Render.Finish = nv10RenderFinish;
569 tnl->Driver.Render.PrimitiveNotify = nv10RenderPrimitive;
570 tnl->Driver.Render.ResetLineStipple = nv10ResetLineStipple;
571 tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
572 tnl->Driver.Render.CopyPV = _tnl_copy_pv;
573 tnl->Driver.Render.Interp = _tnl_interp;
574
575 _tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12,
576 64 * sizeof(GLfloat) );
577
578 nmesa->verts = (GLubyte *)tnl->clipspace.vertex_buf;
579 }
580
581