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.
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:
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
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.
26 /* Software TCL for NV10, NV20, NV30, NV40, G70 */
38 #include "swrast/swrast.h"
39 #include "swrast_setup/swrast_setup.h"
40 #include "tnl/t_context.h"
41 #include "tnl/t_pipeline.h"
43 #include "nouveau_tris.h"
44 #include "nv10_swtcl.h"
45 #include "nouveau_context.h"
46 #include "nouveau_span.h"
47 #include "nouveau_ioctl.h"
48 #include "nouveau_reg.h"
49 #include "nouveau_tex.h"
50 #include "nouveau_fifo.h"
52 /* XXX hack for now */
55 static void nv10RenderPrimitive( GLcontext
*ctx
, GLenum prim
);
56 static void nv10RasterPrimitive( GLcontext
*ctx
, GLenum rprim
, GLuint hwprim
);
60 /***********************************************************************
61 * Emit primitives as inline vertices *
62 ***********************************************************************/
63 #define LINE_FALLBACK (0)
64 #define POINT_FALLBACK (0)
65 #define TRI_FALLBACK (0)
66 #define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK)
67 #define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_TRI_UNFILLED)
70 /* the free room we want before we start a vertex batch. this is a performance-tunable */
71 #define NOUVEAU_MIN_PRIM_SIZE (32/4)
72 /* the size above which we fire the ring. this is a performance-tunable */
73 #define NOUVEAU_FIRE_SIZE (2048/4)
75 static inline void nv10StartPrimitive(struct nouveau_context
* nmesa
)
77 if (nmesa
->screen
->card_type
==NV_10
)
78 BEGIN_RING_SIZE(channel
,NV10_PRIMITIVE
,1);
79 else if (nmesa
->screen
->card_type
==NV_20
)
80 BEGIN_RING_SIZE(channel
,NV20_PRIMITIVE
,1);
82 BEGIN_RING_SIZE(channel
,NV30_PRIMITIVE
,1);
83 OUT_RING(nmesa
->current_primitive
);
85 if (nmesa
->screen
->card_type
==NV_10
)
86 BEGIN_RING_PRIM(channel
,NV10_BEGIN_VERTICES
,NOUVEAU_MIN_PRIM_SIZE
);
88 BEGIN_RING_PRIM(channel
,NV20_BEGIN_VERTICES
,NOUVEAU_MIN_PRIM_SIZE
);
91 inline void nv10FinishPrimitive(struct nouveau_context
*nmesa
)
94 if (nmesa
->screen
->card_type
==NV_10
)
95 BEGIN_RING_SIZE(channel
,NV10_PRIMITIVE
,1);
96 else if (nmesa
->screen
->card_type
==NV_20
)
97 BEGIN_RING_SIZE(channel
,NV20_PRIMITIVE
,1);
99 BEGIN_RING_SIZE(channel
,NV30_PRIMITIVE
,1);
105 static inline void nv10ExtendPrimitive(struct nouveau_context
* nmesa
, int size
)
107 /* when the fifo has enough stuff (2048 bytes) or there is not enough room, fire */
108 if ((RING_AHEAD()>=NOUVEAU_FIRE_SIZE
)||(RING_AVAILABLE()<size
/4))
110 nv10FinishPrimitive(nmesa
);
111 nv10StartPrimitive(nmesa
);
114 /* make sure there's enough room. if not, wait */
115 if (RING_AVAILABLE()<size
/4)
117 WAIT_RING(nmesa
,size
);
121 static inline void nv10_draw_quad(nouveauContextPtr nmesa
,
127 GLuint vertsize
= nmesa
->vertex_size
;
128 nv10ExtendPrimitive(nmesa
, 4 * 4 * vertsize
);
130 OUT_RINGp(v0
,vertsize
);
131 OUT_RINGp(v1
,vertsize
);
132 OUT_RINGp(v2
,vertsize
);
133 OUT_RINGp(v3
,vertsize
);
136 static inline void nv10_draw_triangle(nouveauContextPtr nmesa
,
141 GLuint vertsize
= nmesa
->vertex_size
;
142 nv10ExtendPrimitive(nmesa
, 3 * 4 * vertsize
);
144 OUT_RINGp(v0
,vertsize
);
145 OUT_RINGp(v1
,vertsize
);
146 OUT_RINGp(v2
,vertsize
);
149 static inline void nv10_draw_line(nouveauContextPtr nmesa
,
153 GLuint vertsize
= nmesa
->vertex_size
;
154 nv10ExtendPrimitive(nmesa
, 2 * 4 * vertsize
);
155 OUT_RINGp(v0
,vertsize
);
156 OUT_RINGp(v1
,vertsize
);
159 static inline void nv10_draw_point(nouveauContextPtr nmesa
,
162 GLuint vertsize
= nmesa
->vertex_size
;
163 nv10ExtendPrimitive(nmesa
, 1 * 4 * vertsize
);
164 OUT_RINGp(v0
,vertsize
);
169 #define CTX_ARG nouveauContextPtr nmesa
170 #define GET_VERTEX_DWORDS() nmesa->vertex_size
172 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); \
173 const char *nouveauverts = (char *)nmesa->verts;
174 #define VERT(x) (r200Vertex *)(r200verts + ((x) * vertsize * sizeof(int)))
175 #define VERTEX nouveauVertex
178 #define TAG(x) nouveau_##x
179 #include "tnl_dd/t_dd_triemit.h"
181 /***********************************************************************
182 * Macros for nouveau_dd_tritmp.h to draw basic primitives *
183 ***********************************************************************/
185 #define QUAD( a, b, c, d ) nouveau_quad( nmesa, a, b, c, d )
186 #define TRI( a, b, c ) nouveau_triangle( nmesa, a, b, c )
187 #define LINE( a, b ) nouveau_line( nmesa, a, b )
188 #define POINT( a ) nouveau_point( nmesa, a )
192 /***********************************************************************
193 * Build render functions from dd templates *
194 ***********************************************************************/
196 #define NOUVEAU_OFFSET_BIT 0x01
197 #define NOUVEAU_TWOSIDE_BIT 0x02
198 #define NOUVEAU_UNFILLED_BIT 0x04
199 #define NOUVEAU_FALLBACK_BIT 0x08
200 #define NOUVEAU_MAX_TRIFUNC 0x10
204 tnl_points_func points
;
206 tnl_triangle_func triangle
;
208 } rast_tab
[NOUVEAU_MAX_TRIFUNC
+ 1];
211 #define DO_FALLBACK (IND & NOUVEAU_FALLBACK_BIT)
212 #define DO_OFFSET (IND & NOUVEAU_OFFSET_BIT)
213 #define DO_UNFILLED (IND & NOUVEAU_UNFILLED_BIT)
214 #define DO_TWOSIDE (IND & NOUVEAU_TWOSIDE_BIT)
220 #define DO_FULL_QUAD 1
224 #define HAVE_BACK_COLORS 0
225 #define HAVE_HW_FLATSHADE 1
226 #define VERTEX nouveauVertex
230 #define DEPTH_SCALE 1.0
231 #define UNFILLED_TRI unfilled_tri
232 #define UNFILLED_QUAD unfilled_quad
233 #define VERT_X(_v) _v->v.x
234 #define VERT_Y(_v) _v->v.y
235 #define VERT_Z(_v) _v->v.z
236 #define AREA_IS_CCW(a) (a > 0)
237 #define GET_VERTEX(e) (nmesa->verts + (e * nmesa->vertex_size * sizeof(int)))
239 #define VERT_SET_RGBA( v, c ) \
241 nouveau_color_t *color = (nouveau_color_t *)&((v)->f[coloroffset]); \
243 color->green=(c)[1]; \
244 color->blue=(c)[2]; \
245 color->alpha=(c)[3]; \
248 #define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset]
250 #define VERT_SET_SPEC( v, c ) \
253 nouveau_color_t *color = (nouveau_color_t *)&((v)->f[specoffset]); \
254 UNCLAMPED_FLOAT_TO_UBYTE(color->red, (c)[0]); \
255 UNCLAMPED_FLOAT_TO_UBYTE(color->green, (c)[1]); \
256 UNCLAMPED_FLOAT_TO_UBYTE(color->blue, (c)[2]); \
259 #define VERT_COPY_SPEC( v0, v1 ) \
262 nouveau_color_t *spec0 = (nouveau_color_t *)&((v0)->ui[specoffset]); \
263 nouveau_color_t *spec1 = (nouveau_color_t *)&((v1)->ui[specoffset]); \
264 spec0->red = spec1->red; \
265 spec0->green = spec1->green; \
266 spec0->blue = spec1->blue; \
271 #define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->f[coloroffset]
272 #define VERT_RESTORE_RGBA( idx ) v[idx]->f[coloroffset] = color[idx]
273 #define VERT_SAVE_SPEC( idx ) if (specoffset) spec[idx] = v[idx]->f[specoffset]
274 #define VERT_RESTORE_SPEC( idx ) if (specoffset) v[idx]->f[specoffset] = spec[idx]
278 #define LOCAL_VARS(n) \
279 struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); \
280 GLuint color[n], spec[n]; \
281 GLuint coloroffset = nmesa->color_offset; \
282 GLuint specoffset = nmesa->specular_offset; \
283 (void)color; (void)spec; (void)coloroffset; (void)specoffset;
286 /***********************************************************************
287 * Helpers for rendering unfilled primitives *
288 ***********************************************************************/
290 static const GLuint hw_prim
[GL_POLYGON
+1] = {
303 #define RASTERIZE(x) nv10RasterPrimitive( ctx, x, hw_prim[x] )
304 #define RENDER_PRIMITIVE nmesa->current_primitive
306 #define IND NOUVEAU_FALLBACK_BIT
307 #include "tnl_dd/t_dd_unfilled.h"
311 /***********************************************************************
312 * Generate GL render functions *
313 ***********************************************************************/
318 #include "tnl_dd/t_dd_tritmp.h"
320 #define IND (NOUVEAU_OFFSET_BIT)
321 #define TAG(x) x##_offset
322 #include "tnl_dd/t_dd_tritmp.h"
324 #define IND (NOUVEAU_TWOSIDE_BIT)
325 #define TAG(x) x##_twoside
326 #include "tnl_dd/t_dd_tritmp.h"
328 #define IND (NOUVEAU_TWOSIDE_BIT|NOUVEAU_OFFSET_BIT)
329 #define TAG(x) x##_twoside_offset
330 #include "tnl_dd/t_dd_tritmp.h"
332 #define IND (NOUVEAU_UNFILLED_BIT)
333 #define TAG(x) x##_unfilled
334 #include "tnl_dd/t_dd_tritmp.h"
336 #define IND (NOUVEAU_OFFSET_BIT|NOUVEAU_UNFILLED_BIT)
337 #define TAG(x) x##_offset_unfilled
338 #include "tnl_dd/t_dd_tritmp.h"
340 #define IND (NOUVEAU_TWOSIDE_BIT|NOUVEAU_UNFILLED_BIT)
341 #define TAG(x) x##_twoside_unfilled
342 #include "tnl_dd/t_dd_tritmp.h"
344 #define IND (NOUVEAU_TWOSIDE_BIT|NOUVEAU_OFFSET_BIT|NOUVEAU_UNFILLED_BIT)
345 #define TAG(x) x##_twoside_offset_unfilled
346 #include "tnl_dd/t_dd_tritmp.h"
348 #define IND (NOUVEAU_FALLBACK_BIT)
349 #define TAG(x) x##_fallback
350 #include "tnl_dd/t_dd_tritmp.h"
352 #define IND (NOUVEAU_OFFSET_BIT|NOUVEAU_FALLBACK_BIT)
353 #define TAG(x) x##_offset_fallback
354 #include "tnl_dd/t_dd_tritmp.h"
356 #define IND (NOUVEAU_TWOSIDE_BIT|NOUVEAU_FALLBACK_BIT)
357 #define TAG(x) x##_twoside_fallback
358 #include "tnl_dd/t_dd_tritmp.h"
360 #define IND (NOUVEAU_TWOSIDE_BIT|NOUVEAU_OFFSET_BIT|NOUVEAU_FALLBACK_BIT)
361 #define TAG(x) x##_twoside_offset_fallback
362 #include "tnl_dd/t_dd_tritmp.h"
364 #define IND (NOUVEAU_UNFILLED_BIT|NOUVEAU_FALLBACK_BIT)
365 #define TAG(x) x##_unfilled_fallback
366 #include "tnl_dd/t_dd_tritmp.h"
368 #define IND (NOUVEAU_OFFSET_BIT|NOUVEAU_UNFILLED_BIT|NOUVEAU_FALLBACK_BIT)
369 #define TAG(x) x##_offset_unfilled_fallback
370 #include "tnl_dd/t_dd_tritmp.h"
372 #define IND (NOUVEAU_TWOSIDE_BIT|NOUVEAU_UNFILLED_BIT|NOUVEAU_FALLBACK_BIT)
373 #define TAG(x) x##_twoside_unfilled_fallback
374 #include "tnl_dd/t_dd_tritmp.h"
376 #define IND (NOUVEAU_TWOSIDE_BIT|NOUVEAU_OFFSET_BIT|NOUVEAU_UNFILLED_BIT| \
377 NOUVEAU_FALLBACK_BIT)
378 #define TAG(x) x##_twoside_offset_unfilled_fallback
379 #include "tnl_dd/t_dd_tritmp.h"
382 /* Catchall case for flat, separate specular triangles */
388 #define DO_FALLBACK (0)
389 #define DO_OFFSET (ctx->_TriangleCaps & DD_TRI_OFFSET)
390 #define DO_UNFILLED (ctx->_TriangleCaps & DD_TRI_UNFILLED)
391 #define DO_TWOSIDE (ctx->_TriangleCaps & DD_TRI_LIGHT_TWOSIDE)
393 #define TAG(x) x##_flat_specular
394 #define IND NOUVEAU_MAX_TRIFUNC
395 #include "tnl_dd/t_dd_tritmp.h"
398 static void init_rast_tab(void)
403 init_twoside_offset();
405 init_offset_unfilled();
406 init_twoside_unfilled();
407 init_twoside_offset_unfilled();
409 init_offset_fallback();
410 init_twoside_fallback();
411 init_twoside_offset_fallback();
412 init_unfilled_fallback();
413 init_offset_unfilled_fallback();
414 init_twoside_unfilled_fallback();
415 init_twoside_offset_unfilled_fallback();
417 init_flat_specular(); /* special! */
421 /**********************************************************************/
422 /* Render unclipped begin/end objects */
423 /**********************************************************************/
425 #define V(x) (nouveauVertex *)(vertptr + ((x) * vertsize * sizeof(int)))
426 #define RENDER_POINTS(start, count) \
427 for (; start < count; start++) POINT(V(ELT(start)));
428 #define RENDER_LINE(v0, v1) LINE(V(v0), V(v1))
429 #define RENDER_TRI( v0, v1, v2) TRI( V(v0), V(v1), V(v2))
430 #define RENDER_QUAD(v0, v1, v2, v3) QUAD(V(v0), V(v1), V(v2), V(v3))
431 #define INIT(x) nv10RasterPrimitive(ctx, x, hw_prim[x])
434 struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); \
435 GLubyte *vertptr = (GLubyte *)nmesa->verts; \
436 const GLuint vertsize = nmesa->vertex_size; \
437 const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \
438 const GLboolean stipple = ctx->Line.StippleFlag; \
439 (void) elt; (void) stipple;
440 #define RESET_STIPPLE if ( stipple ) nouveauResetLineStipple( ctx );
441 #define RESET_OCCLUSION
442 #define PRESERVE_VB_DEFS
444 #define TAG(x) nouveau_##x##_verts
445 #include "tnl/t_vb_rendertmp.h"
448 #define TAG(x) nouveau_##x##_elts
449 #define ELT(x) elt[x]
450 #include "tnl/t_vb_rendertmp.h"
453 #undef NEED_EDGEFLAG_SETUP
456 #undef RESET_OCCLUSION
459 /**********************************************************************/
460 /* Render clipped primitives */
461 /**********************************************************************/
465 static void nouveauRenderClippedPoly(GLcontext
*ctx
, const GLuint
*elts
,
468 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
469 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
470 GLuint prim
= NOUVEAU_CONTEXT(ctx
)->renderPrimitive
;
472 /* Render the new vertices as an unclipped polygon.
475 GLuint
*tmp
= VB
->Elts
;
476 VB
->Elts
= (GLuint
*)elts
;
477 tnl
->Driver
.Render
.PrimTabElts
[GL_POLYGON
](ctx
, 0, n
,
478 PRIM_BEGIN
|PRIM_END
);
482 /* Restore the render primitive
484 if (prim
!= GL_POLYGON
&&
485 prim
!= GL_POLYGON
+ 1)
486 tnl
->Driver
.Render
.PrimitiveNotify( ctx
, prim
);
489 static void nouveauRenderClippedLine(GLcontext
*ctx
, GLuint ii
, GLuint jj
)
491 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
492 tnl
->Driver
.Render
.Line(ctx
, ii
, jj
);
495 static void nouveauFastRenderClippedPoly(GLcontext
*ctx
, const GLuint
*elts
,
498 struct nouveau_context
*nmesa
= NOUVEAU_CONTEXT(ctx
);
499 GLuint vertsize
= nmesa
->vertex_size
;
500 nv10ExtendPrimitive(nmesa
, (n
- 2) * 3 * 4 * vertsize
);
501 GLubyte
*vertptr
= (GLubyte
*)nmesa
->verts
;
502 const GLuint
*start
= (const GLuint
*)V(elts
[0]);
505 for (i
= 2; i
< n
; i
++) {
506 OUT_RINGp(V(elts
[i
-1]),vertsize
);
507 OUT_RINGp(V(elts
[i
]),vertsize
);
508 OUT_RINGp(start
,vertsize
);
512 /**********************************************************************/
513 /* Choose render functions */
514 /**********************************************************************/
519 #define _NOUVEAU_NEW_VERTEX (_NEW_TEXTURE | \
520 _DD_NEW_SEPARATE_SPECULAR | \
521 _DD_NEW_TRI_UNFILLED | \
522 _DD_NEW_TRI_LIGHT_TWOSIDE | \
525 #define _NOUVEAU_NEW_RENDERSTATE (_DD_NEW_LINE_STIPPLE | \
526 _DD_NEW_TRI_UNFILLED | \
527 _DD_NEW_TRI_LIGHT_TWOSIDE | \
528 _DD_NEW_TRI_OFFSET | \
529 _DD_NEW_TRI_STIPPLE | \
532 #define EMIT_ATTR( ATTR, STYLE ) \
534 nmesa->vertex_attrs[nmesa->vertex_attr_count].attrib = (ATTR); \
535 nmesa->vertex_attrs[nmesa->vertex_attr_count].format = (STYLE); \
536 nmesa->vertex_attr_count++; \
540 static void nv10ChooseRenderState(GLcontext
*ctx
)
542 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
543 struct nouveau_context
*nmesa
= NOUVEAU_CONTEXT(ctx
);
544 GLuint flags
= ctx
->_TriangleCaps
;
547 nmesa
->draw_point
= nv10_draw_point
;
548 nmesa
->draw_line
= nv10_draw_line
;
549 nmesa
->draw_tri
= nv10_draw_triangle
;
551 if (flags
& (ANY_FALLBACK_FLAGS
|ANY_RASTER_FLAGS
)) {
552 if (flags
& DD_TRI_LIGHT_TWOSIDE
) index
|= NOUVEAU_TWOSIDE_BIT
;
553 if (flags
& DD_TRI_OFFSET
) index
|= NOUVEAU_OFFSET_BIT
;
554 if (flags
& DD_TRI_UNFILLED
) index
|= NOUVEAU_UNFILLED_BIT
;
555 if (flags
& ANY_FALLBACK_FLAGS
) index
|= NOUVEAU_FALLBACK_BIT
;
557 /* Hook in fallbacks for specific primitives.
559 if (flags
& POINT_FALLBACK
)
560 nmesa
->draw_point
= nouveau_fallback_point
;
562 if (flags
& LINE_FALLBACK
)
563 nmesa
->draw_line
= nouveau_fallback_line
;
565 if (flags
& TRI_FALLBACK
)
566 nmesa
->draw_tri
= nouveau_fallback_tri
;
570 if ((flags
& DD_SEPARATE_SPECULAR
) &&
571 ctx
->Light
.ShadeModel
== GL_FLAT
) {
572 index
= NOUVEAU_MAX_TRIFUNC
; /* flat specular */
575 if (nmesa
->render_index
!= index
) {
576 nmesa
->render_index
= index
;
578 tnl
->Driver
.Render
.Points
= rast_tab
[index
].points
;
579 tnl
->Driver
.Render
.Line
= rast_tab
[index
].line
;
580 tnl
->Driver
.Render
.Triangle
= rast_tab
[index
].triangle
;
581 tnl
->Driver
.Render
.Quad
= rast_tab
[index
].quad
;
584 tnl
->Driver
.Render
.PrimTabVerts
= nouveau_render_tab_verts
;
585 tnl
->Driver
.Render
.PrimTabElts
= nouveau_render_tab_elts
;
586 tnl
->Driver
.Render
.ClippedLine
= line
; /* from tritmp.h */
587 tnl
->Driver
.Render
.ClippedPolygon
= nouveauFastRenderClippedPoly
;
590 tnl
->Driver
.Render
.PrimTabVerts
= _tnl_render_tab_verts
;
591 tnl
->Driver
.Render
.PrimTabElts
= _tnl_render_tab_elts
;
592 tnl
->Driver
.Render
.ClippedLine
= nouveauRenderClippedLine
;
593 tnl
->Driver
.Render
.ClippedPolygon
= nouveauRenderClippedPoly
;
600 static inline void nv10OutputVertexFormat(struct nouveau_context
* nmesa
, GLuint index
)
602 GLcontext
* ctx
=nmesa
->glCtx
;
603 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
604 struct vertex_buffer
*VB
= &tnl
->vb
;
606 int default_attr_size
[8]={3,3,3,4,3,1,4,4};
612 * Determine attribute sizes
617 attr_size
[i
]=default_attr_size
[i
];
624 attr_size
[i
]=VB
->TexCoordPtr
[i
];
630 * Tell t_vertex about the vertex format
639 /* special-case POS */
640 EMIT_ATTR(_TNL_ATTRIB_POS
,EMIT_3F_VIEWPORT
);
647 EMIT_ATTR(i
,EMIT_1F
);
650 EMIT_ATTR(i
,EMIT_2F
);
653 EMIT_ATTR(i
,EMIT_3F
);
656 EMIT_ATTR(i
,EMIT_4F
);
660 if (i
==_TNL_ATTRIB_COLOR0
)
661 nmesa
->color_offset
=total_size
;
662 if (i
==_TNL_ATTRIB_COLOR1
)
663 nmesa
->specular_offset
=total_size
;
664 total_size
+=attr_size
[i
];
667 nmesa
->vertex_size
=total_size
;
670 * Tell the hardware about the vertex format
672 if (nmesa
->screen
->card_type
==NV_10
) {
673 // XXX needs some love
674 } else if (nmesa
->screen
->card_type
==NV_20
) {
677 int size
=attr_size
[i
];
678 BEGIN_RING_SIZE(channel
,NV20_VERTEX_ATTRIBUTE(i
),1);
679 OUT_RING(NV20_VERTEX_ATTRIBUTE_TYPE_FLOAT
|(size
*0x10));
682 BEGIN_RING_SIZE(channel
,NV30_VERTEX_ATTRIBUTES
,slots
);
685 int size
=attr_size
[i
];
686 OUT_RING(NV20_VERTEX_ATTRIBUTE_TYPE_FLOAT
|(size
*0x10));
688 BEGIN_RING_SIZE(channel
,NV30_UNKNOWN_0
,1);
690 BEGIN_RING_SIZE(channel
,NV30_UNKNOWN_0
,1);
692 BEGIN_RING_SIZE(channel
,NV30_UNKNOWN_0
,1);
698 static void nv10ChooseVertexState( GLcontext
*ctx
)
700 struct nouveau_context
*nmesa
= NOUVEAU_CONTEXT(ctx
);
701 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
702 GLuint index
= tnl
->render_inputs
;
704 if (index
!=nmesa
->render_inputs
)
706 nmesa
->render_inputs
=index
;
707 nv10OutputVertexFormat(nmesa
,index
);
712 /**********************************************************************/
713 /* High level hooks for t_vb_render.c */
714 /**********************************************************************/
717 static void nv10RenderStart(GLcontext
*ctx
)
719 struct nouveau_context
*nmesa
= NOUVEAU_CONTEXT(ctx
);
721 if (nmesa
->new_state
) {
722 nmesa
->new_render_state
|= nmesa
->new_state
;
725 if (nmesa
->Fallback
) {
726 tnl
->Driver
.Render
.Start(ctx
);
730 if (nmesa
->new_render_state
) {
731 nv10ChooseVertexState(ctx
);
732 nv10ChooseRenderState(ctx
);
733 nmesa
->new_render_state
= 0;
737 static void nv10RenderFinish(GLcontext
*ctx
)
739 struct nouveau_context
*nmesa
= NOUVEAU_CONTEXT(ctx
);
740 nv10FinishPrimitive(nmesa
);
744 /* System to flush dma and emit state changes based on the rasterized
747 void nv10RasterPrimitive(GLcontext
*ctx
,
751 struct nouveau_context
*nmesa
= NOUVEAU_CONTEXT(ctx
);
753 assert (!nmesa
->new_state
);
755 if (hwprim
!= nmesa
->current_primitive
)
757 nmesa
->current_primitive
=hwprim
;
762 /* Callback for mesa:
764 static void nv10RenderPrimitive( GLcontext
*ctx
, GLuint prim
)
766 nv10RasterPrimitive( ctx
, prim
, hw_prim
[prim
] );
770 /**********************************************************************/
771 /* Initialization. */
772 /**********************************************************************/
774 void nv10TriInitFunctions(GLcontext
*ctx
)
776 struct nouveau_context
*nmesa
= NOUVEAU_CONTEXT(ctx
);
777 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
778 static int firsttime
= 1;
785 tnl
->Driver
.RunPipeline
= nouveauRunPipeline
;
786 tnl
->Driver
.Render
.Start
= nv10RenderStart
;
787 tnl
->Driver
.Render
.Finish
= nv10RenderFinish
;
788 tnl
->Driver
.Render
.PrimitiveNotify
= nv10RenderPrimitive
;
789 tnl
->Driver
.Render
.ResetLineStipple
= nouveauResetLineStipple
;
790 tnl
->Driver
.Render
.BuildVertices
= _tnl_build_vertices
;
791 tnl
->Driver
.Render
.CopyPV
= _tnl_copy_pv
;
792 tnl
->Driver
.Render
.Interp
= _tnl_interp
;
794 _tnl_init_vertices( ctx
, ctx
->Const
.MaxArrayLockSize
+ 12,
795 (6 + 2*ctx
->Const
.MaxTextureUnits
) * sizeof(GLfloat
) );
797 nmesa
->verts
= (GLubyte
*)tnl
->clipspace
.vertex_buf
;