1 /**************************************************************************
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
34 #include "swrast/swrast.h"
35 #include "swrast_setup/swrast_setup.h"
36 #include "tnl/t_context.h"
37 #include "tnl/t_pipeline.h"
38 #include "tnl/t_vertex.h"
40 #include "intel_screen.h"
41 #include "intel_tris.h"
42 #include "intel_batchbuffer.h"
43 #include "intel_reg.h"
44 #include "intel_span.h"
46 static void intelRenderPrimitive( GLcontext
*ctx
, GLenum prim
);
47 static void intelRasterPrimitive( GLcontext
*ctx
, GLenum rprim
, GLuint hwprim
);
49 /***********************************************************************
50 * Emit primitives as inline vertices *
51 ***********************************************************************/
54 #define COPY_DWORDS( j, vb, vertsize, v ) \
57 __asm__ __volatile__( "rep ; movsl" \
58 : "=%c" (j), "=D" (vb), "=S" (__tmp) \
64 #define COPY_DWORDS( j, vb, vertsize, v ) \
66 if (0) fprintf(stderr, "\n"); \
67 for ( j = 0 ; j < vertsize ; j++ ) { \
68 if (0) fprintf(stderr, " -- v(%d): %x/%f\n",j, \
71 vb[j] = ((GLuint *)v)[j]; \
77 static void __inline__
intel_draw_quad( intelContextPtr intel
,
83 GLuint vertsize
= intel
->vertex_size
;
84 GLuint
*vb
= intelExtendInlinePrimitive( intel
, 6 * vertsize
);
87 COPY_DWORDS( j
, vb
, vertsize
, v0
);
88 COPY_DWORDS( j
, vb
, vertsize
, v1
);
89 COPY_DWORDS( j
, vb
, vertsize
, v3
);
90 COPY_DWORDS( j
, vb
, vertsize
, v1
);
91 COPY_DWORDS( j
, vb
, vertsize
, v2
);
92 COPY_DWORDS( j
, vb
, vertsize
, v3
);
95 static void __inline__
intel_draw_triangle( intelContextPtr intel
,
100 GLuint vertsize
= intel
->vertex_size
;
101 GLuint
*vb
= intelExtendInlinePrimitive( intel
, 3 * vertsize
);
104 COPY_DWORDS( j
, vb
, vertsize
, v0
);
105 COPY_DWORDS( j
, vb
, vertsize
, v1
);
106 COPY_DWORDS( j
, vb
, vertsize
, v2
);
110 static __inline__
void intel_draw_line( intelContextPtr intel
,
114 GLuint vertsize
= intel
->vertex_size
;
115 GLuint
*vb
= intelExtendInlinePrimitive( intel
, 2 * vertsize
);
118 COPY_DWORDS( j
, vb
, vertsize
, v0
);
119 COPY_DWORDS( j
, vb
, vertsize
, v1
);
123 static __inline__
void intel_draw_point( intelContextPtr intel
,
126 GLuint vertsize
= intel
->vertex_size
;
127 GLuint
*vb
= intelExtendInlinePrimitive( intel
, vertsize
);
130 /* Adjust for sub pixel position -- still required for conform. */
131 *(float *)&vb
[0] = v0
->v
.x
- 0.125;
132 *(float *)&vb
[1] = v0
->v
.y
- 0.125;
133 for (j
= 2 ; j
< vertsize
; j
++)
139 /***********************************************************************
140 * Fixup for ARB_point_parameters *
141 ***********************************************************************/
143 static void intel_atten_point( intelContextPtr intel
, intelVertexPtr v0
)
145 GLcontext
*ctx
= &intel
->ctx
;
146 GLfloat psz
[4], col
[4], restore_psz
, restore_alpha
;
148 _tnl_get_attr( ctx
, v0
, _TNL_ATTRIB_POINTSIZE
, psz
);
149 _tnl_get_attr( ctx
, v0
, _TNL_ATTRIB_COLOR0
, col
);
151 restore_psz
= psz
[0];
152 restore_alpha
= col
[3];
154 if (psz
[0] >= ctx
->Point
.Threshold
) {
155 psz
[0] = MIN2(psz
[0], ctx
->Point
.MaxSize
);
158 GLfloat dsize
= psz
[0] / ctx
->Point
.Threshold
;
159 psz
[0] = MAX2(ctx
->Point
.Threshold
, ctx
->Point
.MinSize
);
160 col
[3] *= dsize
* dsize
;
166 if (restore_psz
!= psz
[0] || restore_alpha
!= col
[3]) {
167 _tnl_set_attr( ctx
, v0
, _TNL_ATTRIB_POINTSIZE
, psz
);
168 _tnl_set_attr( ctx
, v0
, _TNL_ATTRIB_COLOR0
, col
);
170 intel_draw_point( intel
, v0
);
172 psz
[0] = restore_psz
;
173 col
[3] = restore_alpha
;
175 _tnl_set_attr( ctx
, v0
, _TNL_ATTRIB_POINTSIZE
, psz
);
176 _tnl_set_attr( ctx
, v0
, _TNL_ATTRIB_COLOR0
, col
);
179 intel_draw_point( intel
, v0
);
186 /***********************************************************************
187 * Fixup for I915 WPOS texture coordinate *
188 ***********************************************************************/
192 static void intel_wpos_triangle( intelContextPtr intel
,
197 GLuint offset
= intel
->wpos_offset
;
198 GLuint size
= intel
->wpos_size
;
200 __memcpy( ((char *)v0
) + offset
, v0
, size
);
201 __memcpy( ((char *)v1
) + offset
, v1
, size
);
202 __memcpy( ((char *)v2
) + offset
, v2
, size
);
204 intel_draw_triangle( intel
, v0
, v1
, v2
);
208 static void intel_wpos_line( intelContextPtr intel
,
212 GLuint offset
= intel
->wpos_offset
;
213 GLuint size
= intel
->wpos_size
;
215 __memcpy( ((char *)v0
) + offset
, v0
, size
);
216 __memcpy( ((char *)v1
) + offset
, v1
, size
);
218 intel_draw_line( intel
, v0
, v1
);
222 static void intel_wpos_point( intelContextPtr intel
,
225 GLuint offset
= intel
->wpos_offset
;
226 GLuint size
= intel
->wpos_size
;
228 __memcpy( ((char *)v0
) + offset
, v0
, size
);
230 intel_draw_point( intel
, v0
);
238 /***********************************************************************
239 * Macros for t_dd_tritmp.h to draw basic primitives *
240 ***********************************************************************/
242 #define TRI( a, b, c ) \
245 intel->draw_tri( intel, a, b, c ); \
247 intel_draw_triangle( intel, a, b, c ); \
250 #define QUAD( a, b, c, d ) \
253 intel->draw_tri( intel, a, b, d ); \
254 intel->draw_tri( intel, b, c, d ); \
256 intel_draw_quad( intel, a, b, c, d ); \
259 #define LINE( v0, v1 ) \
262 intel->draw_line( intel, v0, v1 ); \
264 intel_draw_line( intel, v0, v1 ); \
267 #define POINT( v0 ) \
270 intel->draw_point( intel, v0 ); \
272 intel_draw_point( intel, v0 ); \
276 /***********************************************************************
277 * Build render functions from dd templates *
278 ***********************************************************************/
280 #define INTEL_OFFSET_BIT 0x01
281 #define INTEL_TWOSIDE_BIT 0x02
282 #define INTEL_UNFILLED_BIT 0x04
283 #define INTEL_FALLBACK_BIT 0x08
284 #define INTEL_MAX_TRIFUNC 0x10
288 tnl_points_func points
;
290 tnl_triangle_func triangle
;
292 } rast_tab
[INTEL_MAX_TRIFUNC
];
295 #define DO_FALLBACK (IND & INTEL_FALLBACK_BIT)
296 #define DO_OFFSET (IND & INTEL_OFFSET_BIT)
297 #define DO_UNFILLED (IND & INTEL_UNFILLED_BIT)
298 #define DO_TWOSIDE (IND & INTEL_TWOSIDE_BIT)
304 #define DO_FULL_QUAD 1
308 #define HAVE_BACK_COLORS 0
309 #define HAVE_HW_FLATSHADE 1
310 #define VERTEX intelVertex
313 /* Only used to pull back colors into vertices (ie, we know color is
316 #define INTEL_COLOR( dst, src ) \
318 UNCLAMPED_FLOAT_TO_UBYTE((dst)[0], (src)[2]); \
319 UNCLAMPED_FLOAT_TO_UBYTE((dst)[1], (src)[1]); \
320 UNCLAMPED_FLOAT_TO_UBYTE((dst)[2], (src)[0]); \
321 UNCLAMPED_FLOAT_TO_UBYTE((dst)[3], (src)[3]); \
324 #define INTEL_SPEC( dst, src ) \
326 UNCLAMPED_FLOAT_TO_UBYTE((dst)[0], (src)[2]); \
327 UNCLAMPED_FLOAT_TO_UBYTE((dst)[1], (src)[1]); \
328 UNCLAMPED_FLOAT_TO_UBYTE((dst)[2], (src)[0]); \
332 #define DEPTH_SCALE intel->polygon_offset_scale
333 #define UNFILLED_TRI unfilled_tri
334 #define UNFILLED_QUAD unfilled_quad
335 #define VERT_X(_v) _v->v.x
336 #define VERT_Y(_v) _v->v.y
337 #define VERT_Z(_v) _v->v.z
338 #define AREA_IS_CCW( a ) (a > 0)
339 #define GET_VERTEX(e) (intel->verts + (e * intel->vertex_size * sizeof(GLuint)))
341 #define VERT_SET_RGBA( v, c ) if (coloroffset) INTEL_COLOR( v->ub4[coloroffset], c )
342 #define VERT_COPY_RGBA( v0, v1 ) if (coloroffset) v0->ui[coloroffset] = v1->ui[coloroffset]
343 #define VERT_SAVE_RGBA( idx ) if (coloroffset) color[idx] = v[idx]->ui[coloroffset]
344 #define VERT_RESTORE_RGBA( idx ) if (coloroffset) v[idx]->ui[coloroffset] = color[idx]
346 #define VERT_SET_SPEC( v, c ) if (specoffset) INTEL_SPEC( v->ub4[specoffset], c )
347 #define VERT_COPY_SPEC( v0, v1 ) if (specoffset) COPY_3V(v0->ub4[specoffset], v1->ub4[specoffset])
348 #define VERT_SAVE_SPEC( idx ) if (specoffset) spec[idx] = v[idx]->ui[specoffset]
349 #define VERT_RESTORE_SPEC( idx ) if (specoffset) v[idx]->ui[specoffset] = spec[idx]
351 #define LOCAL_VARS(n) \
352 intelContextPtr intel = INTEL_CONTEXT(ctx); \
353 GLuint color[n], spec[n]; \
354 GLuint coloroffset = intel->coloroffset; \
355 GLboolean specoffset = intel->specoffset; \
356 (void) color; (void) spec; (void) coloroffset; (void) specoffset;
359 /***********************************************************************
360 * Helpers for rendering unfilled primitives *
361 ***********************************************************************/
363 static const GLuint hw_prim
[GL_POLYGON
+1] = {
376 #define RASTERIZE(x) intelRasterPrimitive( ctx, x, hw_prim[x] )
377 #define RENDER_PRIMITIVE intel->render_primitive
379 #define IND INTEL_FALLBACK_BIT
380 #include "tnl_dd/t_dd_unfilled.h"
383 /***********************************************************************
384 * Generate GL render functions *
385 ***********************************************************************/
389 #include "tnl_dd/t_dd_tritmp.h"
391 #define IND (INTEL_OFFSET_BIT)
392 #define TAG(x) x##_offset
393 #include "tnl_dd/t_dd_tritmp.h"
395 #define IND (INTEL_TWOSIDE_BIT)
396 #define TAG(x) x##_twoside
397 #include "tnl_dd/t_dd_tritmp.h"
399 #define IND (INTEL_TWOSIDE_BIT|INTEL_OFFSET_BIT)
400 #define TAG(x) x##_twoside_offset
401 #include "tnl_dd/t_dd_tritmp.h"
403 #define IND (INTEL_UNFILLED_BIT)
404 #define TAG(x) x##_unfilled
405 #include "tnl_dd/t_dd_tritmp.h"
407 #define IND (INTEL_OFFSET_BIT|INTEL_UNFILLED_BIT)
408 #define TAG(x) x##_offset_unfilled
409 #include "tnl_dd/t_dd_tritmp.h"
411 #define IND (INTEL_TWOSIDE_BIT|INTEL_UNFILLED_BIT)
412 #define TAG(x) x##_twoside_unfilled
413 #include "tnl_dd/t_dd_tritmp.h"
415 #define IND (INTEL_TWOSIDE_BIT|INTEL_OFFSET_BIT|INTEL_UNFILLED_BIT)
416 #define TAG(x) x##_twoside_offset_unfilled
417 #include "tnl_dd/t_dd_tritmp.h"
419 #define IND (INTEL_FALLBACK_BIT)
420 #define TAG(x) x##_fallback
421 #include "tnl_dd/t_dd_tritmp.h"
423 #define IND (INTEL_OFFSET_BIT|INTEL_FALLBACK_BIT)
424 #define TAG(x) x##_offset_fallback
425 #include "tnl_dd/t_dd_tritmp.h"
427 #define IND (INTEL_TWOSIDE_BIT|INTEL_FALLBACK_BIT)
428 #define TAG(x) x##_twoside_fallback
429 #include "tnl_dd/t_dd_tritmp.h"
431 #define IND (INTEL_TWOSIDE_BIT|INTEL_OFFSET_BIT|INTEL_FALLBACK_BIT)
432 #define TAG(x) x##_twoside_offset_fallback
433 #include "tnl_dd/t_dd_tritmp.h"
435 #define IND (INTEL_UNFILLED_BIT|INTEL_FALLBACK_BIT)
436 #define TAG(x) x##_unfilled_fallback
437 #include "tnl_dd/t_dd_tritmp.h"
439 #define IND (INTEL_OFFSET_BIT|INTEL_UNFILLED_BIT|INTEL_FALLBACK_BIT)
440 #define TAG(x) x##_offset_unfilled_fallback
441 #include "tnl_dd/t_dd_tritmp.h"
443 #define IND (INTEL_TWOSIDE_BIT|INTEL_UNFILLED_BIT|INTEL_FALLBACK_BIT)
444 #define TAG(x) x##_twoside_unfilled_fallback
445 #include "tnl_dd/t_dd_tritmp.h"
447 #define IND (INTEL_TWOSIDE_BIT|INTEL_OFFSET_BIT|INTEL_UNFILLED_BIT| \
449 #define TAG(x) x##_twoside_offset_unfilled_fallback
450 #include "tnl_dd/t_dd_tritmp.h"
453 static void init_rast_tab( void )
458 init_twoside_offset();
460 init_offset_unfilled();
461 init_twoside_unfilled();
462 init_twoside_offset_unfilled();
464 init_offset_fallback();
465 init_twoside_fallback();
466 init_twoside_offset_fallback();
467 init_unfilled_fallback();
468 init_offset_unfilled_fallback();
469 init_twoside_unfilled_fallback();
470 init_twoside_offset_unfilled_fallback();
474 /***********************************************************************
475 * Rasterization fallback helpers *
476 ***********************************************************************/
479 /* This code is hit only when a mix of accelerated and unaccelerated
480 * primitives are being drawn, and only for the unaccelerated
484 intel_fallback_tri( intelContextPtr intel
,
489 GLcontext
*ctx
= &intel
->ctx
;
493 fprintf(stderr
, "\n%s\n", __FUNCTION__
);
495 _swsetup_Translate( ctx
, v0
, &v
[0] );
496 _swsetup_Translate( ctx
, v1
, &v
[1] );
497 _swsetup_Translate( ctx
, v2
, &v
[2] );
498 intelSpanRenderStart( ctx
);
499 _swrast_Triangle( ctx
, &v
[0], &v
[1], &v
[2] );
500 intelSpanRenderFinish( ctx
);
505 intel_fallback_line( intelContextPtr intel
,
509 GLcontext
*ctx
= &intel
->ctx
;
513 fprintf(stderr
, "\n%s\n", __FUNCTION__
);
515 _swsetup_Translate( ctx
, v0
, &v
[0] );
516 _swsetup_Translate( ctx
, v1
, &v
[1] );
517 intelSpanRenderStart( ctx
);
518 _swrast_Line( ctx
, &v
[0], &v
[1] );
519 intelSpanRenderFinish( ctx
);
524 intel_fallback_point( intelContextPtr intel
,
527 GLcontext
*ctx
= &intel
->ctx
;
531 fprintf(stderr
, "\n%s\n", __FUNCTION__
);
533 _swsetup_Translate( ctx
, v0
, &v
[0] );
534 intelSpanRenderStart( ctx
);
535 _swrast_Point( ctx
, &v
[0] );
536 intelSpanRenderFinish( ctx
);
541 /**********************************************************************/
542 /* Render unclipped begin/end objects */
543 /**********************************************************************/
546 #define V(x) (intelVertex *)(vertptr + ((x)*vertsize*sizeof(GLuint)))
547 #define RENDER_POINTS( start, count ) \
548 for ( ; start < count ; start++) POINT( V(ELT(start)) );
549 #define RENDER_LINE( v0, v1 ) LINE( V(v0), V(v1) )
550 #define RENDER_TRI( v0, v1, v2 ) TRI( V(v0), V(v1), V(v2) )
551 #define RENDER_QUAD( v0, v1, v2, v3 ) QUAD( V(v0), V(v1), V(v2), V(v3) )
552 #define INIT(x) intelRenderPrimitive( ctx, x )
555 intelContextPtr intel = INTEL_CONTEXT(ctx); \
556 GLubyte *vertptr = (GLubyte *)intel->verts; \
557 const GLuint vertsize = intel->vertex_size; \
558 const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \
560 #define RESET_STIPPLE
561 #define RESET_OCCLUSION
562 #define PRESERVE_VB_DEFS
564 #define TAG(x) intel_##x##_verts
565 #include "tnl/t_vb_rendertmp.h"
568 #define TAG(x) intel_##x##_elts
569 #define ELT(x) elt[x]
570 #include "tnl/t_vb_rendertmp.h"
572 /**********************************************************************/
573 /* Render clipped primitives */
574 /**********************************************************************/
578 static void intelRenderClippedPoly( GLcontext
*ctx
, const GLuint
*elts
,
581 intelContextPtr intel
= INTEL_CONTEXT(ctx
);
582 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
583 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
584 GLuint prim
= intel
->render_primitive
;
586 /* Render the new vertices as an unclipped polygon.
589 GLuint
*tmp
= VB
->Elts
;
590 VB
->Elts
= (GLuint
*)elts
;
591 tnl
->Driver
.Render
.PrimTabElts
[GL_POLYGON
]( ctx
, 0, n
,
592 PRIM_BEGIN
|PRIM_END
);
596 /* Restore the render primitive
598 if (prim
!= GL_POLYGON
)
599 tnl
->Driver
.Render
.PrimitiveNotify( ctx
, prim
);
602 static void intelRenderClippedLine( GLcontext
*ctx
, GLuint ii
, GLuint jj
)
604 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
606 tnl
->Driver
.Render
.Line( ctx
, ii
, jj
);
609 static void intelFastRenderClippedPoly( GLcontext
*ctx
, const GLuint
*elts
,
612 intelContextPtr intel
= INTEL_CONTEXT( ctx
);
613 const GLuint vertsize
= intel
->vertex_size
;
614 GLuint
*vb
= intelExtendInlinePrimitive( intel
, (n
-2) * 3 * vertsize
);
615 GLubyte
*vertptr
= (GLubyte
*)intel
->verts
;
616 const GLuint
*start
= (const GLuint
*)V(elts
[0]);
619 for (i
= 2 ; i
< n
; i
++) {
620 COPY_DWORDS( j
, vb
, vertsize
, V(elts
[i
-1]) );
621 COPY_DWORDS( j
, vb
, vertsize
, V(elts
[i
]) );
622 COPY_DWORDS( j
, vb
, vertsize
, start
);
626 /**********************************************************************/
627 /* Choose render functions */
628 /**********************************************************************/
633 #define POINT_FALLBACK (0)
634 #define LINE_FALLBACK (DD_LINE_STIPPLE)
635 #define TRI_FALLBACK (0)
636 #define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK|\
637 DD_TRI_STIPPLE|DD_POINT_ATTEN)
638 #define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_TRI_UNFILLED)
640 void intelChooseRenderState(GLcontext
*ctx
)
642 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
643 intelContextPtr intel
= INTEL_CONTEXT(ctx
);
644 GLuint flags
= ctx
->_TriangleCaps
;
645 struct fragment_program
*fprog
= ctx
->FragmentProgram
._Current
;
646 GLboolean have_wpos
= (fprog
&& (fprog
->Base
.InputsRead
& FRAG_BIT_WPOS
));
649 if (INTEL_DEBUG
& DEBUG_STATE
)
650 fprintf(stderr
,"\n%s\n",__FUNCTION__
);
652 if ((flags
& (ANY_FALLBACK_FLAGS
|ANY_RASTER_FLAGS
)) || have_wpos
) {
654 if (flags
& ANY_RASTER_FLAGS
) {
655 if (flags
& DD_TRI_LIGHT_TWOSIDE
) index
|= INTEL_TWOSIDE_BIT
;
656 if (flags
& DD_TRI_OFFSET
) index
|= INTEL_OFFSET_BIT
;
657 if (flags
& DD_TRI_UNFILLED
) index
|= INTEL_UNFILLED_BIT
;
661 intel
->draw_point
= intel_wpos_point
;
662 intel
->draw_line
= intel_wpos_line
;
663 intel
->draw_tri
= intel_wpos_triangle
;
665 /* Make sure these get called:
667 index
|= INTEL_FALLBACK_BIT
;
670 intel
->draw_point
= intel_draw_point
;
671 intel
->draw_line
= intel_draw_line
;
672 intel
->draw_tri
= intel_draw_triangle
;
675 /* Hook in fallbacks for specific primitives.
677 if (flags
& ANY_FALLBACK_FLAGS
)
679 if (flags
& POINT_FALLBACK
)
680 intel
->draw_point
= intel_fallback_point
;
682 if (flags
& LINE_FALLBACK
)
683 intel
->draw_line
= intel_fallback_line
;
685 if (flags
& TRI_FALLBACK
)
686 intel
->draw_tri
= intel_fallback_tri
;
688 if ((flags
& DD_TRI_STIPPLE
) && !intel
->hw_stipple
)
689 intel
->draw_tri
= intel_fallback_tri
;
691 if (flags
& DD_POINT_ATTEN
)
692 intel
->draw_point
= intel_atten_point
;
694 index
|= INTEL_FALLBACK_BIT
;
698 if (intel
->RenderIndex
!= index
) {
699 intel
->RenderIndex
= index
;
701 tnl
->Driver
.Render
.Points
= rast_tab
[index
].points
;
702 tnl
->Driver
.Render
.Line
= rast_tab
[index
].line
;
703 tnl
->Driver
.Render
.Triangle
= rast_tab
[index
].triangle
;
704 tnl
->Driver
.Render
.Quad
= rast_tab
[index
].quad
;
707 tnl
->Driver
.Render
.PrimTabVerts
= intel_render_tab_verts
;
708 tnl
->Driver
.Render
.PrimTabElts
= intel_render_tab_elts
;
709 tnl
->Driver
.Render
.ClippedLine
= line
; /* from tritmp.h */
710 tnl
->Driver
.Render
.ClippedPolygon
= intelFastRenderClippedPoly
;
712 tnl
->Driver
.Render
.PrimTabVerts
= _tnl_render_tab_verts
;
713 tnl
->Driver
.Render
.PrimTabElts
= _tnl_render_tab_elts
;
714 tnl
->Driver
.Render
.ClippedLine
= intelRenderClippedLine
;
715 tnl
->Driver
.Render
.ClippedPolygon
= intelRenderClippedPoly
;
720 static const GLenum reduced_prim
[GL_POLYGON
+1] = {
734 /**********************************************************************/
735 /* High level hooks for t_vb_render.c */
736 /**********************************************************************/
741 static void intelRunPipeline( GLcontext
*ctx
)
743 intelContextPtr intel
= INTEL_CONTEXT(ctx
);
745 if (intel
->NewGLState
) {
746 if (intel
->NewGLState
& _NEW_TEXTURE
) {
747 intel
->vtbl
.update_texture_state( intel
);
750 if (!intel
->Fallback
) {
751 if (intel
->NewGLState
& _INTEL_NEW_RENDERSTATE
)
752 intelChooseRenderState( ctx
);
755 intel
->NewGLState
= 0;
758 _tnl_run_pipeline( ctx
);
761 static void intelRenderStart( GLcontext
*ctx
)
763 INTEL_CONTEXT(ctx
)->vtbl
.render_start( INTEL_CONTEXT(ctx
) );
766 static void intelRenderFinish( GLcontext
*ctx
)
768 if (INTEL_CONTEXT(ctx
)->RenderIndex
& INTEL_FALLBACK_BIT
)
769 _swrast_flush( ctx
);
775 /* System to flush dma and emit state changes based on the rasterized
778 static void intelRasterPrimitive( GLcontext
*ctx
, GLenum rprim
, GLuint hwprim
)
780 intelContextPtr intel
= INTEL_CONTEXT(ctx
);
783 fprintf(stderr
, "%s %s %x\n", __FUNCTION__
,
784 _mesa_lookup_enum_by_nr(rprim
), hwprim
);
786 intel
->vtbl
.reduced_primitive_state( intel
, rprim
);
788 /* Start a new primitive. Arrange to have it flushed later on.
790 if (hwprim
!= intel
->prim
.primitive
)
791 intelStartInlinePrimitive( intel
, hwprim
);
797 static void intelRenderPrimitive( GLcontext
*ctx
, GLenum prim
)
799 intelContextPtr intel
= INTEL_CONTEXT(ctx
);
802 fprintf(stderr
, "%s %s\n", __FUNCTION__
, _mesa_lookup_enum_by_nr(prim
));
804 /* Let some clipping routines know which primitive they're dealing
807 intel
->render_primitive
= prim
;
809 /* Shortcircuit this when called from t_dd_rendertmp.h for unfilled
810 * triangles. The rasterized primitive will always be reset by
811 * lower level functions in that case, potentially pingponging the
814 if (reduced_prim
[prim
] == GL_TRIANGLES
&&
815 (ctx
->_TriangleCaps
& DD_TRI_UNFILLED
))
818 /* Set some primitive-dependent state and Start? a new primitive.
820 intelRasterPrimitive( ctx
, reduced_prim
[prim
], hw_prim
[prim
] );
824 /**********************************************************************/
825 /* Transition to/from hardware rasterization. */
826 /**********************************************************************/
828 static char *fallbackStrings
[] = {
840 static char *getFallbackString(GLuint bit
)
847 return fallbackStrings
[i
];
852 void intelFallback( intelContextPtr intel
, GLuint bit
, GLboolean mode
)
854 GLcontext
*ctx
= &intel
->ctx
;
855 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
856 GLuint oldfallback
= intel
->Fallback
;
859 intel
->Fallback
|= bit
;
860 if (oldfallback
== 0) {
862 if (INTEL_DEBUG
& DEBUG_FALLBACKS
)
863 fprintf(stderr
, "ENTER FALLBACK %x: %s\n",
864 bit
, getFallbackString( bit
));
865 _swsetup_Wakeup( ctx
);
866 intel
->RenderIndex
= ~0;
870 intel
->Fallback
&= ~bit
;
871 if (oldfallback
== bit
) {
872 _swrast_flush( ctx
);
873 if (INTEL_DEBUG
& DEBUG_FALLBACKS
)
874 fprintf(stderr
, "LEAVE FALLBACK %s\n", getFallbackString( bit
));
875 tnl
->Driver
.Render
.Start
= intelRenderStart
;
876 tnl
->Driver
.Render
.PrimitiveNotify
= intelRenderPrimitive
;
877 tnl
->Driver
.Render
.Finish
= intelRenderFinish
;
878 tnl
->Driver
.Render
.BuildVertices
= _tnl_build_vertices
;
879 tnl
->Driver
.Render
.CopyPV
= _tnl_copy_pv
;
880 tnl
->Driver
.Render
.Interp
= _tnl_interp
;
882 _tnl_invalidate_vertex_state( ctx
, ~0 );
883 _tnl_invalidate_vertices( ctx
, ~0 );
884 _tnl_install_attrs( ctx
,
886 intel
->vertex_attr_count
,
887 intel
->ViewportMatrix
.m
, 0 );
889 intel
->NewGLState
|= _INTEL_NEW_RENDERSTATE
;
897 /**********************************************************************/
898 /* Initialization. */
899 /**********************************************************************/
902 void intelInitTriFuncs( GLcontext
*ctx
)
904 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
905 static int firsttime
= 1;
912 tnl
->Driver
.RunPipeline
= intelRunPipeline
;
913 tnl
->Driver
.Render
.Start
= intelRenderStart
;
914 tnl
->Driver
.Render
.Finish
= intelRenderFinish
;
915 tnl
->Driver
.Render
.PrimitiveNotify
= intelRenderPrimitive
;
916 tnl
->Driver
.Render
.ResetLineStipple
= _swrast_ResetLineStipple
;
917 tnl
->Driver
.Render
.BuildVertices
= _tnl_build_vertices
;
918 tnl
->Driver
.Render
.CopyPV
= _tnl_copy_pv
;
919 tnl
->Driver
.Render
.Interp
= _tnl_interp
;