Disable leftover debug statements
[mesa.git] / src / mesa / drivers / dri / i915 / intel_tris.c
1 /**************************************************************************
2 *
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * 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
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:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
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.
25 *
26 **************************************************************************/
27
28 #include "glheader.h"
29 #include "context.h"
30 #include "macros.h"
31 #include "enums.h"
32 #include "dd.h"
33
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"
39
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"
45
46 static void intelRenderPrimitive( GLcontext *ctx, GLenum prim );
47 static void intelRasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim );
48
49 /***********************************************************************
50 * Emit primitives as inline vertices *
51 ***********************************************************************/
52
53 #ifdef __i386__
54 #define COPY_DWORDS( j, vb, vertsize, v ) \
55 do { \
56 int __tmp; \
57 __asm__ __volatile__( "rep ; movsl" \
58 : "=%c" (j), "=D" (vb), "=S" (__tmp) \
59 : "0" (vertsize), \
60 "D" ((long)vb), \
61 "S" ((long)v) ); \
62 } while (0)
63 #else
64 #define COPY_DWORDS( j, vb, vertsize, v ) \
65 do { \
66 if (0) fprintf(stderr, "\n"); \
67 for ( j = 0 ; j < vertsize ; j++ ) { \
68 if (0) fprintf(stderr, " -- v(%d): %x/%f\n",j, \
69 ((GLuint *)v)[j], \
70 ((GLfloat *)v)[j]); \
71 vb[j] = ((GLuint *)v)[j]; \
72 } \
73 vb += vertsize; \
74 } while (0)
75 #endif
76
77 static void __inline__ intel_draw_quad( intelContextPtr intel,
78 intelVertexPtr v0,
79 intelVertexPtr v1,
80 intelVertexPtr v2,
81 intelVertexPtr v3 )
82 {
83 GLuint vertsize = intel->vertex_size;
84 GLuint *vb = intelExtendInlinePrimitive( intel, 6 * vertsize );
85 int j;
86
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 );
93 }
94
95 static void __inline__ intel_draw_triangle( intelContextPtr intel,
96 intelVertexPtr v0,
97 intelVertexPtr v1,
98 intelVertexPtr v2 )
99 {
100 GLuint vertsize = intel->vertex_size;
101 GLuint *vb = intelExtendInlinePrimitive( intel, 3 * vertsize );
102 int j;
103
104 COPY_DWORDS( j, vb, vertsize, v0 );
105 COPY_DWORDS( j, vb, vertsize, v1 );
106 COPY_DWORDS( j, vb, vertsize, v2 );
107 }
108
109
110 static __inline__ void intel_draw_line( intelContextPtr intel,
111 intelVertexPtr v0,
112 intelVertexPtr v1 )
113 {
114 GLuint vertsize = intel->vertex_size;
115 GLuint *vb = intelExtendInlinePrimitive( intel, 2 * vertsize );
116 int j;
117
118 COPY_DWORDS( j, vb, vertsize, v0 );
119 COPY_DWORDS( j, vb, vertsize, v1 );
120 }
121
122
123 static __inline__ void intel_draw_point( intelContextPtr intel,
124 intelVertexPtr v0 )
125 {
126 GLuint vertsize = intel->vertex_size;
127 GLuint *vb = intelExtendInlinePrimitive( intel, vertsize );
128 int j;
129
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++)
134 vb[j] = v0->ui[j];
135 }
136
137
138
139 /***********************************************************************
140 * Fixup for ARB_point_parameters *
141 ***********************************************************************/
142
143 static void intel_atten_point( intelContextPtr intel, intelVertexPtr v0 )
144 {
145 GLcontext *ctx = &intel->ctx;
146 GLfloat psz[4], col[4], restore_psz, restore_alpha;
147
148 _tnl_get_attr( ctx, v0, _TNL_ATTRIB_POINTSIZE, psz );
149 _tnl_get_attr( ctx, v0, _TNL_ATTRIB_COLOR0, col );
150
151 restore_psz = psz[0];
152 restore_alpha = col[3];
153
154 if (psz[0] >= ctx->Point.Threshold) {
155 psz[0] = MIN2(psz[0], ctx->Point.MaxSize);
156 }
157 else {
158 GLfloat dsize = psz[0] / ctx->Point.Threshold;
159 psz[0] = MAX2(ctx->Point.Threshold, ctx->Point.MinSize);
160 col[3] *= dsize * dsize;
161 }
162
163 if (psz[0] < 1.0)
164 psz[0] = 1.0;
165
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);
169
170 intel_draw_point( intel, v0 );
171
172 psz[0] = restore_psz;
173 col[3] = restore_alpha;
174
175 _tnl_set_attr( ctx, v0, _TNL_ATTRIB_POINTSIZE, psz);
176 _tnl_set_attr( ctx, v0, _TNL_ATTRIB_COLOR0, col);
177 }
178 else
179 intel_draw_point( intel, v0 );
180 }
181
182
183
184
185
186 /***********************************************************************
187 * Fixup for I915 WPOS texture coordinate *
188 ***********************************************************************/
189
190
191
192 static void intel_wpos_triangle( intelContextPtr intel,
193 intelVertexPtr v0,
194 intelVertexPtr v1,
195 intelVertexPtr v2 )
196 {
197 GLuint offset = intel->wpos_offset;
198 GLuint size = intel->wpos_size;
199
200 __memcpy( ((char *)v0) + offset, v0, size );
201 __memcpy( ((char *)v1) + offset, v1, size );
202 __memcpy( ((char *)v2) + offset, v2, size );
203
204 intel_draw_triangle( intel, v0, v1, v2 );
205 }
206
207
208 static void intel_wpos_line( intelContextPtr intel,
209 intelVertexPtr v0,
210 intelVertexPtr v1 )
211 {
212 GLuint offset = intel->wpos_offset;
213 GLuint size = intel->wpos_size;
214
215 __memcpy( ((char *)v0) + offset, v0, size );
216 __memcpy( ((char *)v1) + offset, v1, size );
217
218 intel_draw_line( intel, v0, v1 );
219 }
220
221
222 static void intel_wpos_point( intelContextPtr intel,
223 intelVertexPtr v0 )
224 {
225 GLuint offset = intel->wpos_offset;
226 GLuint size = intel->wpos_size;
227
228 __memcpy( ((char *)v0) + offset, v0, size );
229
230 intel_draw_point( intel, v0 );
231 }
232
233
234
235
236
237
238 /***********************************************************************
239 * Macros for t_dd_tritmp.h to draw basic primitives *
240 ***********************************************************************/
241
242 #define TRI( a, b, c ) \
243 do { \
244 if (DO_FALLBACK) \
245 intel->draw_tri( intel, a, b, c ); \
246 else \
247 intel_draw_triangle( intel, a, b, c ); \
248 } while (0)
249
250 #define QUAD( a, b, c, d ) \
251 do { \
252 if (DO_FALLBACK) { \
253 intel->draw_tri( intel, a, b, d ); \
254 intel->draw_tri( intel, b, c, d ); \
255 } else \
256 intel_draw_quad( intel, a, b, c, d ); \
257 } while (0)
258
259 #define LINE( v0, v1 ) \
260 do { \
261 if (DO_FALLBACK) \
262 intel->draw_line( intel, v0, v1 ); \
263 else \
264 intel_draw_line( intel, v0, v1 ); \
265 } while (0)
266
267 #define POINT( v0 ) \
268 do { \
269 if (DO_FALLBACK) \
270 intel->draw_point( intel, v0 ); \
271 else \
272 intel_draw_point( intel, v0 ); \
273 } while (0)
274
275
276 /***********************************************************************
277 * Build render functions from dd templates *
278 ***********************************************************************/
279
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
285
286
287 static struct {
288 tnl_points_func points;
289 tnl_line_func line;
290 tnl_triangle_func triangle;
291 tnl_quad_func quad;
292 } rast_tab[INTEL_MAX_TRIFUNC];
293
294
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)
299 #define DO_FLAT 0
300 #define DO_TRI 1
301 #define DO_QUAD 1
302 #define DO_LINE 1
303 #define DO_POINTS 1
304 #define DO_FULL_QUAD 1
305
306 #define HAVE_RGBA 1
307 #define HAVE_SPEC 1
308 #define HAVE_BACK_COLORS 0
309 #define HAVE_HW_FLATSHADE 1
310 #define VERTEX intelVertex
311 #define TAB rast_tab
312
313 /* Only used to pull back colors into vertices (ie, we know color is
314 * floating point).
315 */
316 #define INTEL_COLOR( dst, src ) \
317 do { \
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]); \
322 } while (0)
323
324 #define INTEL_SPEC( dst, src ) \
325 do { \
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]); \
329 } while (0)
330
331
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)))
340
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]
345
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]
350
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;
357
358
359 /***********************************************************************
360 * Helpers for rendering unfilled primitives *
361 ***********************************************************************/
362
363 static const GLuint hw_prim[GL_POLYGON+1] = {
364 PRIM3D_POINTLIST,
365 PRIM3D_LINELIST,
366 PRIM3D_LINELIST,
367 PRIM3D_LINELIST,
368 PRIM3D_TRILIST,
369 PRIM3D_TRILIST,
370 PRIM3D_TRILIST,
371 PRIM3D_TRILIST,
372 PRIM3D_TRILIST,
373 PRIM3D_TRILIST
374 };
375
376 #define RASTERIZE(x) intelRasterPrimitive( ctx, x, hw_prim[x] )
377 #define RENDER_PRIMITIVE intel->render_primitive
378 #define TAG(x) x
379 #define IND INTEL_FALLBACK_BIT
380 #include "tnl_dd/t_dd_unfilled.h"
381 #undef IND
382
383 /***********************************************************************
384 * Generate GL render functions *
385 ***********************************************************************/
386
387 #define IND (0)
388 #define TAG(x) x
389 #include "tnl_dd/t_dd_tritmp.h"
390
391 #define IND (INTEL_OFFSET_BIT)
392 #define TAG(x) x##_offset
393 #include "tnl_dd/t_dd_tritmp.h"
394
395 #define IND (INTEL_TWOSIDE_BIT)
396 #define TAG(x) x##_twoside
397 #include "tnl_dd/t_dd_tritmp.h"
398
399 #define IND (INTEL_TWOSIDE_BIT|INTEL_OFFSET_BIT)
400 #define TAG(x) x##_twoside_offset
401 #include "tnl_dd/t_dd_tritmp.h"
402
403 #define IND (INTEL_UNFILLED_BIT)
404 #define TAG(x) x##_unfilled
405 #include "tnl_dd/t_dd_tritmp.h"
406
407 #define IND (INTEL_OFFSET_BIT|INTEL_UNFILLED_BIT)
408 #define TAG(x) x##_offset_unfilled
409 #include "tnl_dd/t_dd_tritmp.h"
410
411 #define IND (INTEL_TWOSIDE_BIT|INTEL_UNFILLED_BIT)
412 #define TAG(x) x##_twoside_unfilled
413 #include "tnl_dd/t_dd_tritmp.h"
414
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"
418
419 #define IND (INTEL_FALLBACK_BIT)
420 #define TAG(x) x##_fallback
421 #include "tnl_dd/t_dd_tritmp.h"
422
423 #define IND (INTEL_OFFSET_BIT|INTEL_FALLBACK_BIT)
424 #define TAG(x) x##_offset_fallback
425 #include "tnl_dd/t_dd_tritmp.h"
426
427 #define IND (INTEL_TWOSIDE_BIT|INTEL_FALLBACK_BIT)
428 #define TAG(x) x##_twoside_fallback
429 #include "tnl_dd/t_dd_tritmp.h"
430
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"
434
435 #define IND (INTEL_UNFILLED_BIT|INTEL_FALLBACK_BIT)
436 #define TAG(x) x##_unfilled_fallback
437 #include "tnl_dd/t_dd_tritmp.h"
438
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"
442
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"
446
447 #define IND (INTEL_TWOSIDE_BIT|INTEL_OFFSET_BIT|INTEL_UNFILLED_BIT| \
448 INTEL_FALLBACK_BIT)
449 #define TAG(x) x##_twoside_offset_unfilled_fallback
450 #include "tnl_dd/t_dd_tritmp.h"
451
452
453 static void init_rast_tab( void )
454 {
455 init();
456 init_offset();
457 init_twoside();
458 init_twoside_offset();
459 init_unfilled();
460 init_offset_unfilled();
461 init_twoside_unfilled();
462 init_twoside_offset_unfilled();
463 init_fallback();
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();
471 }
472
473
474 /***********************************************************************
475 * Rasterization fallback helpers *
476 ***********************************************************************/
477
478
479 /* This code is hit only when a mix of accelerated and unaccelerated
480 * primitives are being drawn, and only for the unaccelerated
481 * primitives.
482 */
483 static void
484 intel_fallback_tri( intelContextPtr intel,
485 intelVertex *v0,
486 intelVertex *v1,
487 intelVertex *v2 )
488 {
489 GLcontext *ctx = &intel->ctx;
490 SWvertex v[3];
491
492 if (0)
493 fprintf(stderr, "\n%s\n", __FUNCTION__);
494
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 );
501 }
502
503
504 static void
505 intel_fallback_line( intelContextPtr intel,
506 intelVertex *v0,
507 intelVertex *v1 )
508 {
509 GLcontext *ctx = &intel->ctx;
510 SWvertex v[2];
511
512 if (0)
513 fprintf(stderr, "\n%s\n", __FUNCTION__);
514
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 );
520 }
521
522
523 static void
524 intel_fallback_point( intelContextPtr intel,
525 intelVertex *v0 )
526 {
527 GLcontext *ctx = &intel->ctx;
528 SWvertex v[1];
529
530 if (0)
531 fprintf(stderr, "\n%s\n", __FUNCTION__);
532
533 _swsetup_Translate( ctx, v0, &v[0] );
534 intelSpanRenderStart( ctx );
535 _swrast_Point( ctx, &v[0] );
536 intelSpanRenderFinish( ctx );
537 }
538
539
540
541 /**********************************************************************/
542 /* Render unclipped begin/end objects */
543 /**********************************************************************/
544
545 #define IND 0
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 )
553 #undef LOCAL_VARS
554 #define LOCAL_VARS \
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; \
559 (void) elt;
560 #define RESET_STIPPLE
561 #define RESET_OCCLUSION
562 #define PRESERVE_VB_DEFS
563 #define ELT(x) x
564 #define TAG(x) intel_##x##_verts
565 #include "tnl/t_vb_rendertmp.h"
566 #undef ELT
567 #undef TAG
568 #define TAG(x) intel_##x##_elts
569 #define ELT(x) elt[x]
570 #include "tnl/t_vb_rendertmp.h"
571
572 /**********************************************************************/
573 /* Render clipped primitives */
574 /**********************************************************************/
575
576
577
578 static void intelRenderClippedPoly( GLcontext *ctx, const GLuint *elts,
579 GLuint n )
580 {
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;
585
586 /* Render the new vertices as an unclipped polygon.
587 */
588 {
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 );
593 VB->Elts = tmp;
594 }
595
596 /* Restore the render primitive
597 */
598 if (prim != GL_POLYGON)
599 tnl->Driver.Render.PrimitiveNotify( ctx, prim );
600 }
601
602 static void intelRenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj )
603 {
604 TNLcontext *tnl = TNL_CONTEXT(ctx);
605
606 tnl->Driver.Render.Line( ctx, ii, jj );
607 }
608
609 static void intelFastRenderClippedPoly( GLcontext *ctx, const GLuint *elts,
610 GLuint n )
611 {
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]);
617 int i,j;
618
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 );
623 }
624 }
625
626 /**********************************************************************/
627 /* Choose render functions */
628 /**********************************************************************/
629
630
631
632
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)
639
640 void intelChooseRenderState(GLcontext *ctx)
641 {
642 TNLcontext *tnl = TNL_CONTEXT(ctx);
643 intelContextPtr intel = INTEL_CONTEXT(ctx);
644 GLuint flags = ctx->_TriangleCaps;
645 struct fragment_program *program = ctx->FragmentProgram._Current;
646 GLboolean have_wpos = (program && (program->InputsRead & FRAG_BIT_WPOS));
647 GLuint index = 0;
648
649 if (INTEL_DEBUG & DEBUG_STATE)
650 fprintf(stderr,"\n%s\n",__FUNCTION__);
651
652 if ((flags & (ANY_FALLBACK_FLAGS|ANY_RASTER_FLAGS)) || have_wpos) {
653
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;
658 }
659
660 if (have_wpos) {
661 intel->draw_point = intel_wpos_point;
662 intel->draw_line = intel_wpos_line;
663 intel->draw_tri = intel_wpos_triangle;
664
665 /* Make sure these get called:
666 */
667 index |= INTEL_FALLBACK_BIT;
668 }
669 else {
670 intel->draw_point = intel_draw_point;
671 intel->draw_line = intel_draw_line;
672 intel->draw_tri = intel_draw_triangle;
673 }
674
675 /* Hook in fallbacks for specific primitives.
676 */
677 if (flags & ANY_FALLBACK_FLAGS)
678 {
679 if (flags & POINT_FALLBACK)
680 intel->draw_point = intel_fallback_point;
681
682 if (flags & LINE_FALLBACK)
683 intel->draw_line = intel_fallback_line;
684
685 if (flags & TRI_FALLBACK)
686 intel->draw_tri = intel_fallback_tri;
687
688 if ((flags & DD_TRI_STIPPLE) && !intel->hw_stipple)
689 intel->draw_tri = intel_fallback_tri;
690
691 if (flags & DD_POINT_ATTEN)
692 intel->draw_point = intel_atten_point;
693
694 index |= INTEL_FALLBACK_BIT;
695 }
696 }
697
698 if (intel->RenderIndex != index) {
699 intel->RenderIndex = index;
700
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;
705
706 if (index == 0) {
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;
711 } else {
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;
716 }
717 }
718 }
719
720 static const GLenum reduced_prim[GL_POLYGON+1] = {
721 GL_POINTS,
722 GL_LINES,
723 GL_LINES,
724 GL_LINES,
725 GL_TRIANGLES,
726 GL_TRIANGLES,
727 GL_TRIANGLES,
728 GL_TRIANGLES,
729 GL_TRIANGLES,
730 GL_TRIANGLES
731 };
732
733
734 /**********************************************************************/
735 /* High level hooks for t_vb_render.c */
736 /**********************************************************************/
737
738
739
740
741 static void intelRunPipeline( GLcontext *ctx )
742 {
743 intelContextPtr intel = INTEL_CONTEXT(ctx);
744
745 if (intel->NewGLState) {
746 if (intel->NewGLState & _NEW_TEXTURE) {
747 intel->vtbl.update_texture_state( intel );
748 }
749
750 if (!intel->Fallback) {
751 if (intel->NewGLState & _INTEL_NEW_RENDERSTATE)
752 intelChooseRenderState( ctx );
753 }
754
755 intel->NewGLState = 0;
756 }
757
758 _tnl_run_pipeline( ctx );
759 }
760
761 static void intelRenderStart( GLcontext *ctx )
762 {
763 INTEL_CONTEXT(ctx)->vtbl.render_start( INTEL_CONTEXT(ctx) );
764 }
765
766 static void intelRenderFinish( GLcontext *ctx )
767 {
768 if (INTEL_CONTEXT(ctx)->RenderIndex & INTEL_FALLBACK_BIT)
769 _swrast_flush( ctx );
770 }
771
772
773
774
775 /* System to flush dma and emit state changes based on the rasterized
776 * primitive.
777 */
778 static void intelRasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim )
779 {
780 intelContextPtr intel = INTEL_CONTEXT(ctx);
781
782 if (0)
783 fprintf(stderr, "%s %s %x\n", __FUNCTION__,
784 _mesa_lookup_enum_by_nr(rprim), hwprim);
785
786 intel->vtbl.reduced_primitive_state( intel, rprim );
787
788 /* Start a new primitive. Arrange to have it flushed later on.
789 */
790 if (hwprim != intel->prim.primitive)
791 intelStartInlinePrimitive( intel, hwprim );
792 }
793
794
795 /*
796 */
797 static void intelRenderPrimitive( GLcontext *ctx, GLenum prim )
798 {
799 intelContextPtr intel = INTEL_CONTEXT(ctx);
800
801 if (0)
802 fprintf(stderr, "%s %s\n", __FUNCTION__, _mesa_lookup_enum_by_nr(prim));
803
804 /* Let some clipping routines know which primitive they're dealing
805 * with.
806 */
807 intel->render_primitive = prim;
808
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
812 * state:
813 */
814 if (reduced_prim[prim] == GL_TRIANGLES &&
815 (ctx->_TriangleCaps & DD_TRI_UNFILLED))
816 return;
817
818 /* Set some primitive-dependent state and Start? a new primitive.
819 */
820 intelRasterPrimitive( ctx, reduced_prim[prim], hw_prim[prim] );
821 }
822
823
824 /**********************************************************************/
825 /* Transition to/from hardware rasterization. */
826 /**********************************************************************/
827
828 static char *fallbackStrings[] = {
829 "Texture",
830 "Draw buffer",
831 "Read buffer",
832 "Color mask",
833 "Render mode",
834 "Stencil",
835 "Stipple",
836 "User disable"
837 };
838
839
840 static char *getFallbackString(GLuint bit)
841 {
842 int i = 0;
843 while (bit > 1) {
844 i++;
845 bit >>= 1;
846 }
847 return fallbackStrings[i];
848 }
849
850
851
852 void intelFallback( intelContextPtr intel, GLuint bit, GLboolean mode )
853 {
854 GLcontext *ctx = &intel->ctx;
855 TNLcontext *tnl = TNL_CONTEXT(ctx);
856 GLuint oldfallback = intel->Fallback;
857
858 if (mode) {
859 intel->Fallback |= bit;
860 if (oldfallback == 0) {
861 intelFlush(ctx);
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;
867 }
868 }
869 else {
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;
881
882 _tnl_invalidate_vertex_state( ctx, ~0 );
883 _tnl_invalidate_vertices( ctx, ~0 );
884 _tnl_install_attrs( ctx,
885 intel->vertex_attrs,
886 intel->vertex_attr_count,
887 intel->ViewportMatrix.m, 0 );
888
889 intel->NewGLState |= _INTEL_NEW_RENDERSTATE;
890 }
891 }
892 }
893
894
895
896
897 /**********************************************************************/
898 /* Initialization. */
899 /**********************************************************************/
900
901
902 void intelInitTriFuncs( GLcontext *ctx )
903 {
904 TNLcontext *tnl = TNL_CONTEXT(ctx);
905 static int firsttime = 1;
906
907 if (firsttime) {
908 init_rast_tab();
909 firsttime = 0;
910 }
911
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;
920 }