bumpmap sample is correct now
[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/4);
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 inline void nv10_render_points(GLcontext *ctx,GLuint first,GLuint last)
307 {
308 WARN_ONCE("Unimplemented\n");
309 }
310
311 static inline void nv10_render_line(GLcontext *ctx,GLuint v1,GLuint v2)
312 {
313 struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
314 GLubyte *vertptr = (GLubyte *)nmesa->verts;
315 GLuint vertsize = nmesa->vertex_size;
316 GLuint size_dword = vertsize*(2)/4;
317
318 /* OUT_RINGp wants size in DWORDS */
319 vertsize >>= 2;
320
321 nv10ExtendPrimitive(nmesa, size_dword);
322 nv10StartPrimitive(nmesa,GL_LINES+1,size_dword);
323 OUT_RINGp((nouveauVertex*)(vertptr+(v1*vertsize)),vertsize);
324 OUT_RINGp((nouveauVertex*)(vertptr+(v2*vertsize)),vertsize);
325 nv10FinishPrimitive(nmesa);
326 }
327
328 static inline void nv10_render_triangle(GLcontext *ctx,GLuint v1,GLuint v2,GLuint v3)
329 {
330 struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
331 GLubyte *vertptr = (GLubyte *)nmesa->verts;
332 GLuint vertsize = nmesa->vertex_size;
333 GLuint size_dword = vertsize*(3)/4;
334
335 /* OUT_RINGp wants size in DWORDS */
336 vertsize >>= 2;
337
338 nv10ExtendPrimitive(nmesa, size_dword);
339 nv10StartPrimitive(nmesa,GL_TRIANGLES+1,size_dword);
340 OUT_RINGp((nouveauVertex*)(vertptr+(v1*vertsize)),vertsize);
341 OUT_RINGp((nouveauVertex*)(vertptr+(v2*vertsize)),vertsize);
342 OUT_RINGp((nouveauVertex*)(vertptr+(v3*vertsize)),vertsize);
343 nv10FinishPrimitive(nmesa);
344 }
345
346 static inline void nv10_render_quad(GLcontext *ctx,GLuint v1,GLuint v2,GLuint v3,GLuint v4)
347 {
348 struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
349 GLubyte *vertptr = (GLubyte *)nmesa->verts;
350 GLuint vertsize = nmesa->vertex_size;
351 GLuint size_dword = vertsize*(4)/4;
352
353 /* OUT_RINGp wants size in DWORDS */
354 vertsize >>= 2;
355
356 nv10ExtendPrimitive(nmesa, size_dword);
357 nv10StartPrimitive(nmesa,GL_QUADS+1,size_dword);
358 OUT_RINGp((nouveauVertex*)(vertptr+(v1*vertsize)),vertsize);
359 OUT_RINGp((nouveauVertex*)(vertptr+(v2*vertsize)),vertsize);
360 OUT_RINGp((nouveauVertex*)(vertptr+(v3*vertsize)),vertsize);
361 OUT_RINGp((nouveauVertex*)(vertptr+(v4*vertsize)),vertsize);
362 nv10FinishPrimitive(nmesa);
363 }
364
365
366
367 static void nv10ChooseRenderState(GLcontext *ctx)
368 {
369 TNLcontext *tnl = TNL_CONTEXT(ctx);
370 struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
371
372 tnl->Driver.Render.PrimTabVerts = nv10_render_tab_verts;
373 tnl->Driver.Render.PrimTabElts = nv10_render_tab_elts;
374 tnl->Driver.Render.ClippedLine = nv10_render_clipped_line;
375 tnl->Driver.Render.ClippedPolygon = nv10_render_clipped_poly;
376 tnl->Driver.Render.Points = nv10_render_points;
377 tnl->Driver.Render.Line = nv10_render_line;
378 tnl->Driver.Render.Triangle = nv10_render_triangle;
379 tnl->Driver.Render.Quad = nv10_render_quad;
380 }
381
382
383
384 static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa)
385 {
386 GLcontext* ctx=nmesa->glCtx;
387 TNLcontext *tnl = TNL_CONTEXT(ctx);
388 DECLARE_RENDERINPUTS(index);
389 struct vertex_buffer *VB = &tnl->vb;
390 int attr_size[16];
391 int default_attr_size[8]={3,3,3,4,3,1,4,4};
392 int i;
393 int slots=0;
394 int total_size=0;
395
396 nmesa->vertex_attr_count = 0;
397 RENDERINPUTS_COPY(index, nmesa->render_inputs_bitset);
398
399 /*
400 * Determine attribute sizes
401 */
402 for(i=0;i<8;i++)
403 {
404 if (RENDERINPUTS_TEST(index, i))
405 attr_size[i]=default_attr_size[i];
406 else
407 attr_size[i]=0;
408 }
409 for(i=8;i<16;i++)
410 {
411 if (RENDERINPUTS_TEST(index, i))
412 attr_size[i]=VB->TexCoordPtr[i-8]->size;
413 else
414 attr_size[i]=0;
415 }
416
417 /*
418 * Tell t_vertex about the vertex format
419 */
420 for(i=0;i<16;i++)
421 {
422 if (RENDERINPUTS_TEST(index, i))
423 {
424 slots=i+1;
425 switch(attr_size[i])
426 {
427 case 1:
428 EMIT_ATTR(i,EMIT_1F);
429 break;
430 case 2:
431 EMIT_ATTR(i,EMIT_2F);
432 break;
433 case 3:
434 EMIT_ATTR(i,EMIT_3F);
435 break;
436 case 4:
437 EMIT_ATTR(i,EMIT_4F);
438 break;
439 }
440 if (i==_TNL_ATTRIB_COLOR0)
441 nmesa->color_offset=total_size;
442 if (i==_TNL_ATTRIB_COLOR1)
443 nmesa->specular_offset=total_size;
444 total_size+=attr_size[i];
445 }
446 }
447
448 nmesa->vertex_size=_tnl_install_attrs( ctx,
449 nmesa->vertex_attrs,
450 nmesa->vertex_attr_count,
451 NULL, 0 );
452 assert(nmesa->vertex_size==total_size*4);
453
454 /*
455 * Tell the hardware about the vertex format
456 */
457 if (nmesa->screen->card->type==NV_10) {
458 int size;
459
460 #define NV_VERTEX_ATTRIBUTE_TYPE_FLOAT 2
461
462 #define NV10_SET_VERTEX_ATTRIB(i,j) \
463 do { \
464 size = attr_size[j] << 4; \
465 size |= (attr_size[j]*4) << 8; \
466 size |= NV_VERTEX_ATTRIBUTE_TYPE_FLOAT; \
467 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VERTEX_ATTR(i),1); \
468 OUT_RING_CACHE(size); \
469 } while (0)
470
471 NV10_SET_VERTEX_ATTRIB(0, _TNL_ATTRIB_POS);
472 NV10_SET_VERTEX_ATTRIB(1, _TNL_ATTRIB_COLOR0);
473 NV10_SET_VERTEX_ATTRIB(2, _TNL_ATTRIB_COLOR1);
474 NV10_SET_VERTEX_ATTRIB(3, _TNL_ATTRIB_TEX0);
475 NV10_SET_VERTEX_ATTRIB(4, _TNL_ATTRIB_TEX1);
476 NV10_SET_VERTEX_ATTRIB(5, _TNL_ATTRIB_NORMAL);
477 NV10_SET_VERTEX_ATTRIB(6, _TNL_ATTRIB_WEIGHT);
478 NV10_SET_VERTEX_ATTRIB(7, _TNL_ATTRIB_FOG);
479
480 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_VALIDATE,1);
481 OUT_RING_CACHE(0);
482 } else if (nmesa->screen->card->type==NV_20) {
483 for(i=0;i<16;i++)
484 {
485 int size=attr_size[i];
486 BEGIN_RING_CACHE(NvSub3D,NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR(i),1);
487 OUT_RING_CACHE(NV_VERTEX_ATTRIBUTE_TYPE_FLOAT|(size*0x10));
488 }
489 } else {
490 BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DO_VERTICES, 1);
491 OUT_RING(0);
492 BEGIN_RING_CACHE(NvSub3D,NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR0_POS,slots);
493 for(i=0;i<slots;i++)
494 {
495 int size=attr_size[i];
496 OUT_RING_CACHE(NV_VERTEX_ATTRIBUTE_TYPE_FLOAT|(size*0x10));
497 }
498 // FIXME this is probably not needed
499 BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_VERTEX_UNK_0,1);
500 OUT_RING(0);
501 BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_VERTEX_UNK_0,1);
502 OUT_RING(0);
503 BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_VERTEX_UNK_0,1);
504 OUT_RING(0);
505 }
506 }
507
508
509 static void nv10ChooseVertexState( GLcontext *ctx )
510 {
511 struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
512 TNLcontext *tnl = TNL_CONTEXT(ctx);
513 DECLARE_RENDERINPUTS(index);
514
515 RENDERINPUTS_COPY(index, tnl->render_inputs_bitset);
516 if (!RENDERINPUTS_EQUAL(index, nmesa->render_inputs_bitset))
517 {
518 RENDERINPUTS_COPY(nmesa->render_inputs_bitset, index);
519 nv10OutputVertexFormat(nmesa);
520 }
521
522 if (nmesa->screen->card->type == NV_30) {
523 nouveauShader *fp;
524
525 if (ctx->FragmentProgram.Enabled) {
526 fp = (nouveauShader *) ctx->FragmentProgram.Current;
527 nvsUpdateShader(ctx, fp);
528 } else
529 nvsUpdateShader(ctx, nmesa->passthrough_fp);
530 }
531
532 if (nmesa->screen->card->type >= NV_40) {
533 /* Ensure passthrough shader is being used, and mvp matrix
534 * is up to date
535 */
536 nvsUpdateShader(ctx, nmesa->passthrough_vp);
537
538 /* Update texenv shader / user fragprog */
539 nvsUpdateShader(ctx, (nouveauShader*)ctx->FragmentProgram._Current);
540 }
541 }
542
543
544 /**********************************************************************/
545 /* High level hooks for t_vb_render.c */
546 /**********************************************************************/
547
548
549 static void nv10RenderStart(GLcontext *ctx)
550 {
551 TNLcontext *tnl = TNL_CONTEXT(ctx);
552 struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
553
554 if (nmesa->new_state) {
555 nmesa->new_render_state |= nmesa->new_state;
556 }
557
558 if (nmesa->new_render_state) {
559 nv10ChooseVertexState(ctx);
560 nv10ChooseRenderState(ctx);
561 nmesa->new_render_state = 0;
562 }
563 }
564
565 static void nv10RenderFinish(GLcontext *ctx)
566 {
567 }
568
569
570 /* System to flush dma and emit state changes based on the rasterized
571 * primitive.
572 */
573 void nv10RasterPrimitive(GLcontext *ctx,
574 GLenum glprim,
575 GLuint hwprim)
576 {
577 struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
578
579 assert (!nmesa->new_state);
580
581 if (hwprim != nmesa->current_primitive)
582 {
583 nmesa->current_primitive=hwprim;
584
585 }
586 }
587
588 static const GLuint hw_prim[GL_POLYGON+1] = {
589 GL_POINTS+1,
590 GL_LINES+1,
591 GL_LINE_STRIP+1,
592 GL_LINE_LOOP+1,
593 GL_TRIANGLES+1,
594 GL_TRIANGLE_STRIP+1,
595 GL_TRIANGLE_FAN+1,
596 GL_QUADS+1,
597 GL_QUAD_STRIP+1,
598 GL_POLYGON+1
599 };
600
601 /* Callback for mesa:
602 */
603 static void nv10RenderPrimitive( GLcontext *ctx, GLuint prim )
604 {
605 nv10RasterPrimitive( ctx, prim, hw_prim[prim] );
606 }
607
608 static void nv10ResetLineStipple( GLcontext *ctx )
609 {
610 /* FIXME do something here */
611 WARN_ONCE("Unimplemented nv10ResetLineStipple\n");
612 }
613
614
615 /**********************************************************************/
616 /* Initialization. */
617 /**********************************************************************/
618
619 void nv10TriInitFunctions(GLcontext *ctx)
620 {
621 struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
622 TNLcontext *tnl = TNL_CONTEXT(ctx);
623
624 tnl->Driver.RunPipeline = nouveauRunPipeline;
625 tnl->Driver.Render.Start = nv10RenderStart;
626 tnl->Driver.Render.Finish = nv10RenderFinish;
627 tnl->Driver.Render.PrimitiveNotify = nv10RenderPrimitive;
628 tnl->Driver.Render.ResetLineStipple = nv10ResetLineStipple;
629 tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
630 tnl->Driver.Render.CopyPV = _tnl_copy_pv;
631 tnl->Driver.Render.Interp = _tnl_interp;
632
633 _tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12,
634 64 * sizeof(GLfloat) );
635
636 nmesa->verts = (GLubyte *)tnl->clipspace.vertex_buf;
637 }
638
639