Initial add of some (disabled) SiS 6326 drawing code integrated from Alan Cox's
[mesa.git] / src / mesa / drivers / dri / sis / sis_tris.c
1 /* $XFree86*/ /* -*- c-basic-offset: 3 -*- */
2 /**************************************************************************
3
4 Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
5 Copyright 2003 Eric Anholt
6 All Rights Reserved.
7
8 Permission is hereby granted, free of charge, to any person obtaining a
9 copy of this software and associated documentation files (the "Software"),
10 to deal in the Software without restriction, including without limitation
11 on the rights to use, copy, modify, merge, publish, distribute, sub
12 license, and/or sell copies of the Software, and to permit persons to whom
13 the Software is furnished to do so, subject to the following conditions:
14
15 The above copyright notice and this permission notice (including the next
16 paragraph) shall be included in all copies or substantial portions of the
17 Software.
18
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
22 ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM,
23 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
25 USE OR OTHER DEALINGS IN THE SOFTWARE.
26
27 **************************************************************************/
28
29 /*
30 * Authors:
31 * Sung-Ching Lin <sclin@sis.com.tw>
32 * Eric Anholt <anholt@FreeBSD.org>
33 */
34
35 #include "glheader.h"
36 #include "mtypes.h"
37 #include "colormac.h"
38 #include "macros.h"
39
40 #include "swrast/swrast.h"
41 #include "swrast_setup/swrast_setup.h"
42 #include "tnl/t_context.h"
43 #include "tnl/t_pipeline.h"
44
45 #include "sis_context.h"
46 #include "sis_tris.h"
47 #include "sis_state.h"
48 #include "sis_lock.h"
49 #include "sis_span.h"
50 #include "sis_alloc.h"
51 #include "sis_tex.h"
52
53 /* 6326 and 300-series shared */
54 static const GLuint hw_prim[GL_POLYGON+1] = {
55 OP_3D_POINT_DRAW, /* GL_POINTS */
56 OP_3D_LINE_DRAW, /* GL_LINES */
57 OP_3D_LINE_DRAW, /* GL_LINE_LOOP */
58 OP_3D_LINE_DRAW, /* GL_LINE_STRIP */
59 OP_3D_TRIANGLE_DRAW, /* GL_TRIANGLES */
60 OP_3D_TRIANGLE_DRAW, /* GL_TRIANGLE_STRIP */
61 OP_3D_TRIANGLE_DRAW, /* GL_TRIANGLE_FAN */
62 OP_3D_TRIANGLE_DRAW, /* GL_QUADS */
63 OP_3D_TRIANGLE_DRAW, /* GL_QUAD_STRIP */
64 OP_3D_TRIANGLE_DRAW /* GL_POLYGON */
65 };
66
67 static const GLuint hw_prim_mmio_fire[OP_3D_TRIANGLE_DRAW+1] = {
68 OP_3D_FIRE_TSARGBa,
69 OP_3D_FIRE_TSARGBb,
70 OP_3D_FIRE_TSARGBc
71 };
72 static const GLuint hw_prim_6326_mmio_fire[OP_3D_TRIANGLE_DRAW+1] = {
73 OP_6326_3D_FIRE_TSARGBa,
74 OP_6326_3D_FIRE_TSARGBb,
75 OP_6326_3D_FIRE_TSARGBc
76 };
77
78 static const GLuint hw_prim_mmio_shade[OP_3D_TRIANGLE_DRAW+1] = {
79 SHADE_FLAT_VertexA,
80 SHADE_FLAT_VertexB,
81 SHADE_FLAT_VertexC
82 };
83
84 static const GLuint hw_prim_agp_type[OP_3D_TRIANGLE_DRAW+1] = {
85 MASK_PsPointList,
86 MASK_PsLineList,
87 MASK_PsTriangleList
88 };
89
90 static const GLuint hw_prim_agp_shade[OP_3D_TRIANGLE_DRAW+1] = {
91 MASK_PsShadingFlatA,
92 MASK_PsShadingFlatB,
93 MASK_PsShadingFlatC
94 };
95
96 static void sisRasterPrimitive( GLcontext *ctx, GLuint hwprim );
97 static void sisRenderPrimitive( GLcontext *ctx, GLenum prim );
98
99 /***********************************************************************
100 * Emit primitives as inline vertices *
101 ***********************************************************************/
102
103 #define HAVE_QUADS 0
104 #define HAVE_LINES 1
105 #define HAVE_POINTS 1
106 #define CTX_ARG sisContextPtr smesa
107 #define GET_VERTEX_DWORDS() smesa->vertex_size
108 #define ALLOC_VERTS( n, size ) sisAllocDmaLow( smesa, n * size * sizeof(int) )
109 #undef LOCAL_VARS
110 #define LOCAL_VARS \
111 sisContextPtr smesa = SIS_CONTEXT(ctx); \
112 const char *vertptr = smesa->verts;
113 #define VERT(x) (sisVertex *)(vertptr + (x * vertsize * sizeof(int)))
114 #define VERTEX sisVertex
115 #undef TAG
116 #define TAG(x) sis_##x
117 #include "tnl_dd/t_dd_triemit.h"
118 #undef TAG
119 #undef LOCAL_VARS
120
121 /***********************************************************************
122 * Dispatch vertices to hardware through MMIO *
123 ***********************************************************************/
124
125 /* The ARGB write of the last vertex of the primitive fires the 3d engine, so
126 * save it until the end.
127 */
128 #define SIS_MMIO_WRITE_VERTEX(_v, i, lastvert) \
129 do { \
130 GLuint __color, __i = 0; \
131 MMIO(REG_3D_TSXa+(i)*0x30, _v->ui[__i++]); \
132 MMIO(REG_3D_TSYa+(i)*0x30, _v->ui[__i++]); \
133 MMIO(REG_3D_TSZa+(i)*0x30, _v->ui[__i++]); \
134 if (SIS_STATES & VERT_W) \
135 MMIO(REG_3D_TSWGa+(i)*0x30, _v->ui[__i++]); \
136 __color = _v->ui[__i++]; \
137 if (SIS_STATES & VERT_SPEC) \
138 MMIO(REG_3D_TSFSa+(i)*0x30, _v->ui[__i++]); \
139 if (SIS_STATES & VERT_UV0) { \
140 MMIO(REG_3D_TSUAa+(i)*0x30, _v->ui[__i++]); \
141 MMIO(REG_3D_TSVAa+(i)*0x30, _v->ui[__i++]); \
142 } \
143 if (SIS_STATES & VERT_UV1) { \
144 MMIO(REG_3D_TSUBa+(i)*0x30, _v->ui[__i++]); \
145 MMIO(REG_3D_TSVBa+(i)*0x30, _v->ui[__i++]); \
146 } \
147 if (lastvert || (SIS_STATES & VERT_SMOOTH)) \
148 MMIO(REG_3D_TSARGBa+(i)*0x30, __color); \
149 } while (0)
150
151 #define SIS6326_MMIO_WRITE_VERTEX(_v, i, lastvert) \
152 do { \
153 GLuint __color, __i = 0; \
154 MMIO(REG_6326_3D_TSXa+(i)*0x20, _v->ui[__i++]); \
155 MMIO(REG_6326_3D_TSYa+(i)*0x20, _v->ui[__i++]); \
156 MMIO(REG_6326_3D_TSZa+(i)*0x20, _v->ui[__i++]); \
157 if (SIS_STATES & VERT_W) \
158 MMIO(REG_6326_3D_TSWa+(i)*0x20, _v->ui[__i++]); \
159 __color = _v->ui[__i++]; \
160 if (SIS_STATES & VERT_SPEC) \
161 MMIO(REG_6326_3D_TSFSa+(i)*0x20, _v->ui[__i++]); \
162 if (SIS_STATES & VERT_UV0) { \
163 MMIO(REG_6326_3D_TSUa+(i)*0x20, _v->ui[__i++]); \
164 MMIO(REG_6326_3D_TSVa+(i)*0x20, _v->ui[__i++]); \
165 } \
166 if (lastvert || (SIS_STATES & VERT_SMOOTH)) \
167 MMIO(REG_6326_3D_TSARGBa+(i)*0x30, __color); \
168 } while (0)
169
170 #define MMIO_VERT_REG_COUNT 10
171
172 #define VERT_SMOOTH 0x01
173 #define VERT_W 0x02
174 #define VERT_SPEC 0x04
175 #define VERT_UV0 0x08
176 #define VERT_UV1 0x10
177 #define VERT_6326 0x20 /* Right after UV1, but won't have a UV1 set */
178
179 typedef void (*mmio_draw_func)(sisContextPtr smesa, char *verts);
180 static mmio_draw_func sis_tri_func_mmio[48];
181 static mmio_draw_func sis_line_func_mmio[48];
182 static mmio_draw_func sis_point_func_mmio[48];
183
184 #define SIS_STATES (0)
185 #define TAG(x) x##_none
186 #include "sis_tritmp.h"
187
188 #define SIS_STATES (VERT_SMOOTH)
189 #define TAG(x) x##_g
190 #include "sis_tritmp.h"
191
192 #define SIS_STATES (VERT_W)
193 #define TAG(x) x##_w
194 #include "sis_tritmp.h"
195
196 #define SIS_STATES (VERT_SMOOTH | VERT_W)
197 #define TAG(x) x##_gw
198 #include "sis_tritmp.h"
199
200 #define SIS_STATES (VERT_SPEC)
201 #define TAG(x) x##_s
202 #include "sis_tritmp.h"
203
204 #define SIS_STATES (VERT_SMOOTH | VERT_SPEC)
205 #define TAG(x) x##_gs
206 #include "sis_tritmp.h"
207
208 #define SIS_STATES (VERT_W | VERT_SPEC)
209 #define TAG(x) x##_ws
210 #include "sis_tritmp.h"
211
212 #define SIS_STATES (VERT_SMOOTH | VERT_W | VERT_SPEC)
213 #define TAG(x) x##_gws
214 #include "sis_tritmp.h"
215
216 #define SIS_STATES (VERT_UV0)
217 #define TAG(x) x##_t0
218 #include "sis_tritmp.h"
219
220 #define SIS_STATES (VERT_SMOOTH | VERT_UV0)
221 #define TAG(x) x##_gt0
222 #include "sis_tritmp.h"
223
224 #define SIS_STATES (VERT_W | VERT_UV0)
225 #define TAG(x) x##_wt0
226 #include "sis_tritmp.h"
227
228 #define SIS_STATES (VERT_SMOOTH | VERT_W | VERT_UV0)
229 #define TAG(x) x##_gwt0
230 #include "sis_tritmp.h"
231
232 #define SIS_STATES (VERT_SPEC | VERT_UV0)
233 #define TAG(x) x##_st0
234 #include "sis_tritmp.h"
235
236 #define SIS_STATES (VERT_SMOOTH | VERT_SPEC | VERT_UV0)
237 #define TAG(x) x##_gst0
238 #include "sis_tritmp.h"
239
240 #define SIS_STATES (VERT_W | VERT_SPEC | VERT_UV0)
241 #define TAG(x) x##_wst0
242 #include "sis_tritmp.h"
243
244 #define SIS_STATES (VERT_SMOOTH | VERT_W | VERT_SPEC | VERT_UV0)
245 #define TAG(x) x##_gwst0
246 #include "sis_tritmp.h"
247
248 #define SIS_STATES (VERT_UV1)
249 #define TAG(x) x##_t1
250 #include "sis_tritmp.h"
251
252 #define SIS_STATES (VERT_SMOOTH | VERT_UV1)
253 #define TAG(x) x##_gt1
254 #include "sis_tritmp.h"
255
256 #define SIS_STATES (VERT_W | VERT_UV1)
257 #define TAG(x) x##_wt1
258 #include "sis_tritmp.h"
259
260 #define SIS_STATES (VERT_SMOOTH | VERT_W | VERT_UV1)
261 #define TAG(x) x##_gwt1
262 #include "sis_tritmp.h"
263
264 #define SIS_STATES (VERT_SPEC | VERT_UV1)
265 #define TAG(x) x##_st1
266 #include "sis_tritmp.h"
267
268 #define SIS_STATES (VERT_SMOOTH | VERT_SPEC | VERT_UV1)
269 #define TAG(x) x##_gst1
270 #include "sis_tritmp.h"
271
272 #define SIS_STATES (VERT_W | VERT_SPEC | VERT_UV1)
273 #define TAG(x) x##_wst1
274 #include "sis_tritmp.h"
275
276 #define SIS_STATES (VERT_SMOOTH | VERT_W | VERT_SPEC | VERT_UV1)
277 #define TAG(x) x##_gwst1
278 #include "sis_tritmp.h"
279
280 #define SIS_STATES (VERT_UV0 | VERT_UV1)
281 #define TAG(x) x##_t0t1
282 #include "sis_tritmp.h"
283
284 #define SIS_STATES (VERT_SMOOTH | VERT_UV0 | VERT_UV1)
285 #define TAG(x) x##_gt0t1
286 #include "sis_tritmp.h"
287
288 #define SIS_STATES (VERT_W | VERT_UV0 | VERT_UV1)
289 #define TAG(x) x##_wt0t1
290 #include "sis_tritmp.h"
291
292 #define SIS_STATES (VERT_SMOOTH | VERT_W | VERT_UV0 | VERT_UV1)
293 #define TAG(x) x##_gwt0t1
294 #include "sis_tritmp.h"
295
296 #define SIS_STATES (VERT_SPEC | VERT_UV0 | VERT_UV1)
297 #define TAG(x) x##_st0t1
298 #include "sis_tritmp.h"
299
300 #define SIS_STATES (VERT_SMOOTH | VERT_SPEC | VERT_UV0 | VERT_UV1)
301 #define TAG(x) x##_gst0t1
302 #include "sis_tritmp.h"
303
304 #define SIS_STATES (VERT_W | VERT_SPEC | VERT_UV0 | VERT_UV1)
305 #define TAG(x) x##_wst0t1
306 #include "sis_tritmp.h"
307
308 #define SIS_STATES (VERT_SMOOTH | VERT_W | VERT_SPEC | VERT_UV0 | VERT_UV1)
309 #define TAG(x) x##_gwst0t1
310 #include "sis_tritmp.h"
311
312 /***********************************************************************
313 * Macros for t_dd_tritmp.h to draw basic primitives *
314 ***********************************************************************/
315
316 #define TRI( a, b, c ) \
317 do { \
318 if (DO_FALLBACK) \
319 smesa->draw_tri( smesa, a, b, c ); \
320 else \
321 sis_triangle( smesa, a, b, c ); \
322 } while (0)
323
324 #define QUAD( a, b, c, d ) \
325 do { \
326 if (DO_FALLBACK) { \
327 smesa->draw_tri( smesa, a, b, d ); \
328 smesa->draw_tri( smesa, b, c, d ); \
329 } else \
330 sis_quad( smesa, a, b, c, d ); \
331 } while (0)
332
333 #define LINE( v0, v1 ) \
334 do { \
335 if (DO_FALLBACK) \
336 smesa->draw_line( smesa, v0, v1 ); \
337 else \
338 sis_line( smesa, v0, v1 ); \
339 } while (0)
340
341 #define POINT( v0 ) \
342 do { \
343 if (DO_FALLBACK) \
344 smesa->draw_point( smesa, v0 ); \
345 else \
346 sis_point( smesa, v0 ); \
347 } while (0)
348
349 /***********************************************************************
350 * Build render functions from dd templates *
351 ***********************************************************************/
352
353 #define SIS_OFFSET_BIT 0x01
354 #define SIS_TWOSIDE_BIT 0x02
355 #define SIS_UNFILLED_BIT 0x04
356 #define SIS_FALLBACK_BIT 0x08
357 #define SIS_MAX_TRIFUNC 0x10
358
359
360 static struct {
361 tnl_points_func points;
362 tnl_line_func line;
363 tnl_triangle_func triangle;
364 tnl_quad_func quad;
365 } rast_tab[SIS_MAX_TRIFUNC];
366
367
368 #define DO_FALLBACK (IND & SIS_FALLBACK_BIT)
369 #define DO_OFFSET (IND & SIS_OFFSET_BIT)
370 #define DO_UNFILLED (IND & SIS_UNFILLED_BIT)
371 #define DO_TWOSIDE (IND & SIS_TWOSIDE_BIT)
372 #define DO_FLAT 0
373 #define DO_TRI 1
374 #define DO_QUAD 1
375 #define DO_LINE 1
376 #define DO_POINTS 1
377 #define DO_FULL_QUAD 1
378
379 #define HAVE_RGBA 1
380 #define HAVE_SPEC 1
381 #define HAVE_BACK_COLORS 0
382 #define HAVE_HW_FLATSHADE 1
383 #define VERTEX sisVertex
384 #define TAB rast_tab
385
386 #define DEPTH_SCALE smesa->depth_scale
387 #define UNFILLED_TRI unfilled_tri
388 #define UNFILLED_QUAD unfilled_quad
389 #define VERT_X(_v) _v->v.x
390 #define VERT_Y(_v) _v->v.y
391 #define VERT_Z(_v) _v->v.z
392 #define AREA_IS_CCW( a ) (a > 0)
393 #define GET_VERTEX(e) (smesa->verts + (e * smesa->vertex_size * sizeof(int)))
394
395 #define VERT_SET_RGBA( v, c ) \
396 do { \
397 sis_color_t *color = (sis_color_t *)&((v)->ui[coloroffset]); \
398 UNCLAMPED_FLOAT_TO_UBYTE(color->red, (c)[0]); \
399 UNCLAMPED_FLOAT_TO_UBYTE(color->green, (c)[1]); \
400 UNCLAMPED_FLOAT_TO_UBYTE(color->blue, (c)[2]); \
401 UNCLAMPED_FLOAT_TO_UBYTE(color->alpha, (c)[3]); \
402 } while (0)
403
404 #define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset]
405
406 #define VERT_SET_SPEC( v0, c ) \
407 do { \
408 if (specoffset != 0) { \
409 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.red, (c)[0]); \
410 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.green, (c)[1]); \
411 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.blue, (c)[2]); \
412 } \
413 } while (0)
414 #define VERT_COPY_SPEC( v0, v1 ) \
415 do { \
416 if (specoffset != 0) { \
417 v0->v.specular.red = v1->v.specular.red; \
418 v0->v.specular.green = v1->v.specular.green; \
419 v0->v.specular.blue = v1->v.specular.blue; \
420 } \
421 } while (0)
422
423 #define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->ui[coloroffset]
424 #define VERT_RESTORE_RGBA( idx ) v[idx]->ui[coloroffset] = color[idx]
425 #define VERT_SAVE_SPEC( idx ) if (specoffset != 0) spec[idx] = v[idx]->ui[specoffset]
426 #define VERT_RESTORE_SPEC( idx ) if (specoffset != 0) v[idx]->ui[specoffset] = spec[idx]
427
428 #define LOCAL_VARS(n) \
429 sisContextPtr smesa = SIS_CONTEXT(ctx); \
430 GLuint color[n], spec[n]; \
431 GLuint coloroffset = smesa->coloroffset; \
432 GLuint specoffset = smesa->specoffset; \
433 (void) color; (void) spec; (void) coloroffset; (void) specoffset;
434
435 /***********************************************************************
436 * Helpers for rendering unfilled primitives *
437 ***********************************************************************/
438
439 #define RASTERIZE(x) if (smesa->hw_primitive != hw_prim[x]) \
440 sisRasterPrimitive( ctx, hw_prim[x] )
441 #define RENDER_PRIMITIVE smesa->render_primitive
442 #define IND SIS_FALLBACK_BIT
443 #define TAG(x) x
444 #include "tnl_dd/t_dd_unfilled.h"
445 #undef IND
446
447
448 /***********************************************************************
449 * Generate GL render functions *
450 ***********************************************************************/
451
452
453 #define IND (0)
454 #define TAG(x) x
455 #include "tnl_dd/t_dd_tritmp.h"
456
457 #define IND (SIS_OFFSET_BIT)
458 #define TAG(x) x##_offset
459 #include "tnl_dd/t_dd_tritmp.h"
460
461 #define IND (SIS_TWOSIDE_BIT)
462 #define TAG(x) x##_twoside
463 #include "tnl_dd/t_dd_tritmp.h"
464
465 #define IND (SIS_TWOSIDE_BIT|SIS_OFFSET_BIT)
466 #define TAG(x) x##_twoside_offset
467 #include "tnl_dd/t_dd_tritmp.h"
468
469 #define IND (SIS_UNFILLED_BIT)
470 #define TAG(x) x##_unfilled
471 #include "tnl_dd/t_dd_tritmp.h"
472
473 #define IND (SIS_OFFSET_BIT|SIS_UNFILLED_BIT)
474 #define TAG(x) x##_offset_unfilled
475 #include "tnl_dd/t_dd_tritmp.h"
476
477 #define IND (SIS_TWOSIDE_BIT|SIS_UNFILLED_BIT)
478 #define TAG(x) x##_twoside_unfilled
479 #include "tnl_dd/t_dd_tritmp.h"
480
481 #define IND (SIS_TWOSIDE_BIT|SIS_OFFSET_BIT|SIS_UNFILLED_BIT)
482 #define TAG(x) x##_twoside_offset_unfilled
483 #include "tnl_dd/t_dd_tritmp.h"
484
485 #define IND (SIS_FALLBACK_BIT)
486 #define TAG(x) x##_fallback
487 #include "tnl_dd/t_dd_tritmp.h"
488
489 #define IND (SIS_OFFSET_BIT|SIS_FALLBACK_BIT)
490 #define TAG(x) x##_offset_fallback
491 #include "tnl_dd/t_dd_tritmp.h"
492
493 #define IND (SIS_TWOSIDE_BIT|SIS_FALLBACK_BIT)
494 #define TAG(x) x##_twoside_fallback
495 #include "tnl_dd/t_dd_tritmp.h"
496
497 #define IND (SIS_TWOSIDE_BIT|SIS_OFFSET_BIT|SIS_FALLBACK_BIT)
498 #define TAG(x) x##_twoside_offset_fallback
499 #include "tnl_dd/t_dd_tritmp.h"
500
501 #define IND (SIS_UNFILLED_BIT|SIS_FALLBACK_BIT)
502 #define TAG(x) x##_unfilled_fallback
503 #include "tnl_dd/t_dd_tritmp.h"
504
505 #define IND (SIS_OFFSET_BIT|SIS_UNFILLED_BIT|SIS_FALLBACK_BIT)
506 #define TAG(x) x##_offset_unfilled_fallback
507 #include "tnl_dd/t_dd_tritmp.h"
508
509 #define IND (SIS_TWOSIDE_BIT|SIS_UNFILLED_BIT|SIS_FALLBACK_BIT)
510 #define TAG(x) x##_twoside_unfilled_fallback
511 #include "tnl_dd/t_dd_tritmp.h"
512
513 #define IND (SIS_TWOSIDE_BIT|SIS_OFFSET_BIT|SIS_UNFILLED_BIT| \
514 SIS_FALLBACK_BIT)
515 #define TAG(x) x##_twoside_offset_unfilled_fallback
516 #include "tnl_dd/t_dd_tritmp.h"
517
518
519 static void init_rast_tab( void )
520 {
521 init();
522 init_offset();
523 init_twoside();
524 init_twoside_offset();
525 init_unfilled();
526 init_offset_unfilled();
527 init_twoside_unfilled();
528 init_twoside_offset_unfilled();
529 init_fallback();
530 init_offset_fallback();
531 init_twoside_fallback();
532 init_twoside_offset_fallback();
533 init_unfilled_fallback();
534 init_offset_unfilled_fallback();
535 init_twoside_unfilled_fallback();
536 init_twoside_offset_unfilled_fallback();
537 }
538
539
540
541 /***********************************************************************
542 * Rasterization fallback helpers *
543 ***********************************************************************/
544
545
546 /* This code is hit only when a mix of accelerated and unaccelerated
547 * primitives are being drawn, and only for the unaccelerated
548 * primitives.
549 */
550
551 static void
552 sis_fallback_tri( sisContextPtr smesa,
553 sisVertex *v0,
554 sisVertex *v1,
555 sisVertex *v2 )
556 {
557 GLcontext *ctx = smesa->glCtx;
558 SWvertex v[3];
559 _swsetup_Translate( ctx, v0, &v[0] );
560 _swsetup_Translate( ctx, v1, &v[1] );
561 _swsetup_Translate( ctx, v2, &v[2] );
562 sisSpanRenderStart( ctx );
563 _swrast_Triangle( ctx, &v[0], &v[1], &v[2] );
564 sisSpanRenderFinish( ctx );
565 _swrast_flush( ctx );
566 }
567
568
569 static void
570 sis_fallback_line( sisContextPtr smesa,
571 sisVertex *v0,
572 sisVertex *v1 )
573 {
574 GLcontext *ctx = smesa->glCtx;
575 SWvertex v[2];
576 _swsetup_Translate( ctx, v0, &v[0] );
577 _swsetup_Translate( ctx, v1, &v[1] );
578 sisSpanRenderStart( ctx );
579 _swrast_Line( ctx, &v[0], &v[1] );
580 sisSpanRenderFinish( ctx );
581 _swrast_flush( ctx );
582 }
583
584
585 static void
586 sis_fallback_point( sisContextPtr smesa,
587 sisVertex *v0 )
588 {
589 GLcontext *ctx = smesa->glCtx;
590 SWvertex v[1];
591 _swsetup_Translate( ctx, v0, &v[0] );
592 sisSpanRenderStart( ctx );
593 _swrast_Point( ctx, &v[0] );
594 sisSpanRenderFinish( ctx );
595 _swrast_flush( ctx );
596 }
597
598
599
600 /**********************************************************************/
601 /* Render unclipped begin/end objects */
602 /**********************************************************************/
603
604 #define IND 0
605 #define V(x) (sisVertex *)(vertptr + (x * vertsize * sizeof(int)))
606 #define RENDER_POINTS( start, count ) \
607 for ( ; start < count ; start++) \
608 POINT( V(ELT(start)) )
609 #define RENDER_LINE( v0, v1 ) LINE( V(v0), V(v1) )
610 #define RENDER_TRI( v0, v1, v2 ) TRI( V(v0), V(v1), V(v2) )
611 #define RENDER_QUAD( v0, v1, v2, v3 ) QUAD( V(v0), V(v1), V(v2), V(v3) )
612 #define INIT(x) sisRenderPrimitive( ctx, x )
613 #undef LOCAL_VARS
614 #define LOCAL_VARS \
615 sisContextPtr smesa = SIS_CONTEXT(ctx); \
616 const GLuint vertsize = smesa->vertex_size; \
617 const char *vertptr = (char *)smesa->verts; \
618 const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \
619 (void) elt;
620 #define RESET_STIPPLE
621 #define RESET_OCCLUSION
622 #define PRESERVE_VB_DEFS
623 #define ELT(x) (x)
624 #define TAG(x) sis_##x##_verts
625 #include "tnl/t_vb_rendertmp.h"
626 #undef ELT
627 #undef TAG
628 #define TAG(x) sis_##x##_elts
629 #define ELT(x) elt[x]
630 #include "tnl/t_vb_rendertmp.h"
631
632
633 /**********************************************************************/
634 /* Choose render functions */
635 /**********************************************************************/
636
637 #define POINT_FALLBACK (DD_POINT_SMOOTH)
638 #define LINE_FALLBACK (DD_LINE_STIPPLE|DD_LINE_SMOOTH)
639 #define TRI_FALLBACK (DD_TRI_STIPPLE|DD_TRI_SMOOTH)
640 #define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK)
641 #define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_TRI_UNFILLED)
642 #define _SIS_NEW_RENDER_STATE (ANY_RASTER_FLAGS | ANY_FALLBACK_FLAGS)
643
644 static void sisChooseRenderState(GLcontext *ctx)
645 {
646 TNLcontext *tnl = TNL_CONTEXT(ctx);
647 sisContextPtr smesa = SIS_CONTEXT( ctx );
648 GLuint flags = ctx->_TriangleCaps;
649 GLuint index = 0;
650
651 if (smesa->Fallback)
652 return;
653
654 if (flags & (ANY_RASTER_FLAGS|ANY_FALLBACK_FLAGS)) {
655
656 if (flags & ANY_RASTER_FLAGS) {
657 if (flags & DD_TRI_LIGHT_TWOSIDE) index |= SIS_TWOSIDE_BIT;
658 if (flags & DD_TRI_OFFSET) index |= SIS_OFFSET_BIT;
659 if (flags & DD_TRI_UNFILLED) index |= SIS_UNFILLED_BIT;
660 }
661
662 smesa->draw_point = sis_point;
663 smesa->draw_line = sis_line;
664 smesa->draw_tri = sis_triangle;
665 /* Hook in fallbacks for specific primitives.
666 */
667 if (flags & ANY_FALLBACK_FLAGS) {
668 if (flags & POINT_FALLBACK)
669 smesa->draw_point = sis_fallback_point;
670 if (flags & LINE_FALLBACK)
671 smesa->draw_line = sis_fallback_line;
672 if (flags & TRI_FALLBACK)
673 smesa->draw_tri = sis_fallback_tri;
674 index |= SIS_FALLBACK_BIT;
675 }
676 }
677
678 if (index != smesa->RenderIndex) {
679 smesa->RenderIndex = index;
680
681 tnl->Driver.Render.Points = rast_tab[index].points;
682 tnl->Driver.Render.Line = rast_tab[index].line;
683 tnl->Driver.Render.ClippedLine = rast_tab[index].line;
684 tnl->Driver.Render.Triangle = rast_tab[index].triangle;
685 tnl->Driver.Render.Quad = rast_tab[index].quad;
686
687 if (index == 0) {
688 tnl->Driver.Render.PrimTabVerts = sis_render_tab_verts;
689 tnl->Driver.Render.PrimTabElts = sis_render_tab_elts;
690 tnl->Driver.Render.ClippedPolygon = sis_fast_clipped_poly;
691 } else {
692 tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
693 tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
694 tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon;
695 }
696 }
697 }
698
699 /**********************************************************************/
700 /* Multipass rendering for front buffering */
701 /**********************************************************************/
702 static GLboolean multipass_cliprect( GLcontext *ctx, GLuint pass )
703 {
704 sisContextPtr smesa = SIS_CONTEXT( ctx );
705
706 if (pass >= smesa->driDrawable->numClipRects) {
707 return GL_FALSE;
708 } else {
709 GLint x1, y1, x2, y2;
710
711 x1 = smesa->driDrawable->pClipRects[pass].x1 - smesa->driDrawable->x;
712 y1 = smesa->driDrawable->pClipRects[pass].y1 - smesa->driDrawable->y;
713 x2 = smesa->driDrawable->pClipRects[pass].x2 - smesa->driDrawable->x;
714 y2 = smesa->driDrawable->pClipRects[pass].y2 - smesa->driDrawable->y;
715
716 if (ctx->Scissor.Enabled) {
717 GLint scisy1 = Y_FLIP(ctx->Scissor.Y + ctx->Scissor.Height - 1);
718 GLint scisy2 = Y_FLIP(ctx->Scissor.Y);
719
720 if (ctx->Scissor.X > x1)
721 x1 = ctx->Scissor.X;
722 if (scisy1 > y1)
723 y1 = scisy1;
724 if (ctx->Scissor.X + ctx->Scissor.Width - 1 < x2)
725 x2 = ctx->Scissor.X + ctx->Scissor.Width - 1;
726 if (scisy2 < y2)
727 y2 = scisy2;
728 }
729
730 MMIO(REG_3D_ClipTopBottom, y1 << 13 | y2);
731 MMIO(REG_3D_ClipLeftRight, x1 << 13 | x2);
732 /* Mark that we clobbered these registers */
733 smesa->GlobalFlag |= GFLAG_CLIPPING;
734 return GL_TRUE;
735 }
736 }
737
738
739
740 /**********************************************************************/
741 /* Validate state at pipeline start */
742 /**********************************************************************/
743
744 static void sisRunPipeline( GLcontext *ctx )
745 {
746 sisContextPtr smesa = SIS_CONTEXT( ctx );
747
748 if (smesa->NewGLState) {
749 SIS_FIREVERTICES(smesa);
750 if (smesa->NewGLState & _NEW_TEXTURE) {
751 sisUpdateTextureState(ctx);
752 }
753
754 if (smesa->NewGLState & _SIS_NEW_RENDER_STATE)
755 sisChooseRenderState( ctx );
756
757 smesa->NewGLState = 0;
758 }
759
760 _tnl_run_pipeline( ctx );
761
762 /* XXX: If we put flushing in sis_state.c and friends, we can avoid this.
763 * Is it worth it?
764 */
765 SIS_FIREVERTICES(smesa);
766 }
767
768 /**********************************************************************/
769 /* High level hooks for t_vb_render.c */
770 /**********************************************************************/
771
772 /* This is called when Mesa switches between rendering triangle
773 * primitives (such as GL_POLYGON, GL_QUADS, GL_TRIANGLE_STRIP, etc),
774 * and lines, points and bitmaps.
775 */
776
777 static void sisRasterPrimitive( GLcontext *ctx, GLuint hwprim )
778 {
779 sisContextPtr smesa = SIS_CONTEXT(ctx);
780 if (smesa->hw_primitive != hwprim) {
781 SIS_FIREVERTICES(smesa);
782 smesa->hw_primitive = hwprim;
783
784 smesa->AGPParseSet &= ~(MASK_PsDataType | MASK_PsShadingMode);
785 smesa->AGPParseSet |= hw_prim_agp_type[hwprim];
786
787 if (smesa->is6326) {
788 smesa->dwPrimitiveSet &= ~(MASK_6326_DrawPrimitiveCommand |
789 MASK_6326_SetFirePosition | MASK_6326_ShadingMode);
790 smesa->dwPrimitiveSet |= hwprim | hw_prim_6326_mmio_fire[hwprim];
791 } else {
792 smesa->dwPrimitiveSet &= ~(MASK_DrawPrimitiveCommand |
793 MASK_SetFirePosition | MASK_ShadingMode);
794 smesa->dwPrimitiveSet |= hwprim | hw_prim_mmio_fire[hwprim];
795 }
796
797 if (ctx->Light.ShadeModel == GL_FLAT) {
798 smesa->AGPParseSet |= hw_prim_agp_shade[hwprim];
799 smesa->dwPrimitiveSet |= hw_prim_mmio_shade[hwprim];
800 } else {
801 smesa->AGPParseSet |= MASK_PsShadingSmooth;
802 if (smesa->is6326) {
803 smesa->dwPrimitiveSet |= OP_6326_3D_SHADE_FLAT_GOURAUD;
804 } else {
805 smesa->dwPrimitiveSet |= SHADE_GOURAUD;
806 }
807 }
808 }
809 }
810
811 static void sisRenderPrimitive( GLcontext *ctx, GLenum prim )
812 {
813 sisContextPtr smesa = SIS_CONTEXT(ctx);
814
815 smesa->render_primitive = prim;
816
817 if (prim >= GL_TRIANGLES && (ctx->_TriangleCaps & DD_TRI_UNFILLED))
818 return;
819 sisRasterPrimitive( ctx, hw_prim[prim] );
820 }
821
822 #define EMIT_ATTR( ATTR, STYLE) \
823 do { \
824 smesa->vertex_attrs[smesa->vertex_attr_count].attrib = (ATTR); \
825 smesa->vertex_attrs[smesa->vertex_attr_count].format = (STYLE); \
826 smesa->vertex_attr_count++; \
827 } while (0)
828
829 #define EMIT_PAD( N ) \
830 do { \
831 smesa->vertex_attrs[smesa->vertex_attr_count].attrib = 0; \
832 smesa->vertex_attrs[smesa->vertex_attr_count].format = EMIT_PAD; \
833 smesa->vertex_attrs[smesa->vertex_attr_count].offset = (N); \
834 smesa->vertex_attr_count++; \
835 } while (0)
836
837 #define SIS_TCL_STATE_BITS \
838 (_TNL_BITS_TEX_ANY | _TNL_BIT_COLOR1 | _TNL_BIT_FOG)
839
840 static void sisRenderStart( GLcontext *ctx )
841 {
842 TNLcontext *tnl = TNL_CONTEXT(ctx);
843 sisContextPtr smesa = SIS_CONTEXT(ctx);
844 struct vertex_buffer *VB = &tnl->vb;
845 GLuint index = tnl->render_inputs;
846 GLuint AGPParseSet = smesa->AGPParseSet;
847 GLboolean tex_fallback = GL_FALSE;
848
849 if (ctx->DrawBuffer->_ColorDrawBufferMask[0] == BUFFER_BIT_FRONT_LEFT &&
850 smesa->driDrawable->numClipRects != 0)
851 {
852 multipass_cliprect(ctx, 0);
853 if (smesa->driDrawable->numClipRects > 1)
854 tnl->Driver.Render.Multipass = multipass_cliprect;
855 else
856 tnl->Driver.Render.Multipass = NULL;
857 } else {
858 tnl->Driver.Render.Multipass = NULL;
859 }
860
861 /* Important:
862 */
863 VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr;
864 smesa->vertex_attr_count = 0;
865
866 /* EMIT_ATTR's must be in order as they tell t_vertex.c how to build up a
867 * hardware vertex.
868 */
869
870 AGPParseSet &= ~(MASK_VertexDWSize | MASK_VertexDataFormat);
871 AGPParseSet |= SiS_PS_HAS_XYZ | SiS_PS_HAS_DIFFUSE;
872 if (index & _TNL_BITS_TEX_ANY) {
873 EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_4F_VIEWPORT);
874 AGPParseSet |= SiS_PS_HAS_W;
875 smesa->coloroffset = 4;
876 } else {
877 EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_3F_VIEWPORT);
878 smesa->coloroffset = 3;
879 }
880
881 EMIT_ATTR(_TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA);
882
883 if (index & (_TNL_BIT_COLOR1|_TNL_BIT_FOG)) {
884 AGPParseSet |= SiS_PS_HAS_SPECULAR;
885 smesa->specoffset = smesa->coloroffset + 1;
886
887 if (index & _TNL_BIT_COLOR1) {
888 EMIT_ATTR(_TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR);
889 } else {
890 EMIT_PAD(3);
891 }
892
893 if (index & _TNL_BIT_FOG) {
894 EMIT_ATTR(_TNL_ATTRIB_FOG, EMIT_1UB_1F);
895 } else {
896 EMIT_PAD(1);
897 }
898 } else {
899 smesa->specoffset = 0;
900 }
901
902 /* projective textures are not supported by the hardware */
903 if (index & _TNL_BIT_TEX(0)) {
904 if (VB->TexCoordPtr[0]->size > 2)
905 tex_fallback = GL_TRUE;
906 EMIT_ATTR(_TNL_ATTRIB_TEX0, EMIT_2F);
907 AGPParseSet |= SiS_PS_HAS_UV0;
908 }
909 /* Will only hit tex1 on SiS300 */
910 if (index & _TNL_BIT_TEX(1)) {
911 if (VB->TexCoordPtr[1]->size > 2)
912 tex_fallback = GL_TRUE;
913 EMIT_ATTR(_TNL_ATTRIB_TEX1, EMIT_2F);
914 AGPParseSet |= SiS_PS_HAS_UV1;
915 }
916 FALLBACK(smesa, SIS_FALLBACK_TEXTURE, tex_fallback);
917
918 if (smesa->last_tcl_state != index) {
919 smesa->AGPParseSet = AGPParseSet;
920
921 smesa->vertex_size = _tnl_install_attrs( ctx, smesa->vertex_attrs,
922 smesa->vertex_attr_count, smesa->hw_viewport, 0 );
923
924 smesa->vertex_size >>= 2;
925 smesa->AGPParseSet |= smesa->vertex_size << 28;
926 }
927 }
928
929 static void sisRenderFinish( GLcontext *ctx )
930 {
931 }
932
933 /**********************************************************************/
934 /* AGP/PCI vertex submission */
935 /**********************************************************************/
936
937 void
938 sisFlushPrimsLocked(sisContextPtr smesa)
939 {
940 if (smesa->vb_cur == smesa->vb_last)
941 return;
942
943 if (smesa->is6326)
944 sis6326UpdateHWState(smesa->glCtx);
945 else
946 sisUpdateHWState(smesa->glCtx);
947
948 if (smesa->using_agp) {
949 mWait3DCmdQueue(8);
950 mEndPrimitive();
951 MMIO(REG_3D_AGPCmBase, (smesa->vb_last - smesa->vb) +
952 smesa->vb_agp_offset);
953 MMIO(REG_3D_AGPTtDwNum, ((smesa->vb_cur - smesa->vb_last) / 4) |
954 0x50000000);
955 MMIO(REG_3D_ParsingSet, smesa->AGPParseSet);
956 MMIO(REG_3D_AGPCmFire, (GLint)(-1));
957 mEndPrimitive();
958 } else {
959 int mmio_index = 0, incr = 0;
960 void (*sis_emit_func)(sisContextPtr smesa, char *verts) = NULL;
961
962 if (smesa->AGPParseSet & MASK_PsShadingSmooth)
963 mmio_index |= VERT_SMOOTH;
964 if (smesa->AGPParseSet & SiS_PS_HAS_SPECULAR)
965 mmio_index |= VERT_SPEC;
966 if (smesa->AGPParseSet & SiS_PS_HAS_W)
967 mmio_index |= VERT_W;
968 if (smesa->AGPParseSet & SiS_PS_HAS_UV0)
969 mmio_index |= VERT_UV0;
970 if (smesa->AGPParseSet & SiS_PS_HAS_UV1)
971 mmio_index |= VERT_UV1;
972 if (smesa->is6326)
973 mmio_index |= VERT_6326;
974
975 switch (smesa->AGPParseSet & MASK_PsDataType) {
976 case MASK_PsPointList:
977 incr = smesa->vertex_size * 4;
978 sis_emit_func = sis_point_func_mmio[mmio_index];
979 break;
980 case MASK_PsLineList:
981 incr = smesa->vertex_size * 4 * 2;
982 sis_emit_func = sis_line_func_mmio[mmio_index];
983 break;
984 case MASK_PsTriangleList:
985 incr = smesa->vertex_size * 4 * 3;
986 sis_emit_func = sis_tri_func_mmio[mmio_index];
987 break;
988 }
989
990 if (!smesa->is6326) {
991 mWait3DCmdQueue(1);
992 MMIO(REG_3D_PrimitiveSet, smesa->dwPrimitiveSet);
993 }
994 while (smesa->vb_last < smesa->vb_cur) {
995 sis_emit_func(smesa, smesa->vb_last);
996 smesa->vb_last += incr;
997 }
998 mWait3DCmdQueue(1);
999 mEndPrimitive();
1000
1001 /* With PCI, we can just start writing to the start of the VB again. */
1002 smesa->vb_cur = smesa->vb;
1003 }
1004 smesa->vb_last = smesa->vb_cur;
1005 }
1006
1007 void sisFlushPrims(sisContextPtr smesa)
1008 {
1009 LOCK_HARDWARE();
1010 sisFlushPrimsLocked(smesa);
1011 UNLOCK_HARDWARE();
1012 }
1013
1014 /**********************************************************************/
1015 /* Transition to/from hardware rasterization. */
1016 /**********************************************************************/
1017
1018 static const char * const fallbackStrings[] = {
1019 "Texture mode",
1020 "Texture 0 mode",
1021 "Texture 1 mode",
1022 "Texture 0 env", /* Note: unused */
1023 "Texture 1 env", /* Note: unused */
1024 "glDrawBuffer(GL_FRONT_AND_BACK)",
1025 "glEnable(GL_STENCIL) without hw stencil buffer",
1026 "write mask",
1027 "no_rast",
1028 };
1029
1030 static const char *getFallbackString(GLuint bit)
1031 {
1032 int i = 0;
1033 while (bit > 1) {
1034 i++;
1035 bit >>= 1;
1036 }
1037 return fallbackStrings[i];
1038 }
1039
1040 void sisFallback( GLcontext *ctx, GLuint bit, GLboolean mode )
1041 {
1042 TNLcontext *tnl = TNL_CONTEXT(ctx);
1043 sisContextPtr smesa = SIS_CONTEXT(ctx);
1044 GLuint oldfallback = smesa->Fallback;
1045
1046 if (mode) {
1047 smesa->Fallback |= bit;
1048 if (oldfallback == 0) {
1049 SIS_FIREVERTICES(smesa);
1050 _swsetup_Wakeup( ctx );
1051 smesa->RenderIndex = ~0;
1052 if (SIS_DEBUG & DEBUG_FALLBACKS) {
1053 fprintf(stderr, "SiS begin rasterization fallback: 0x%x %s\n",
1054 bit, getFallbackString(bit));
1055 }
1056 }
1057 }
1058 else {
1059 smesa->Fallback &= ~bit;
1060 if (oldfallback == bit) {
1061 _swrast_flush( ctx );
1062 tnl->Driver.Render.Start = sisRenderStart;
1063 tnl->Driver.Render.PrimitiveNotify = sisRenderPrimitive;
1064 tnl->Driver.Render.Finish = sisRenderFinish;
1065
1066 tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
1067 tnl->Driver.Render.CopyPV = _tnl_copy_pv;
1068 tnl->Driver.Render.Interp = _tnl_interp;
1069
1070 _tnl_invalidate_vertex_state( ctx, ~0 );
1071 _tnl_invalidate_vertices( ctx, ~0 );
1072 _tnl_install_attrs( ctx,
1073 smesa->vertex_attrs,
1074 smesa->vertex_attr_count,
1075 smesa->hw_viewport, 0 );
1076
1077 smesa->NewGLState |= _SIS_NEW_RENDER_STATE;
1078 if (SIS_DEBUG & DEBUG_FALLBACKS) {
1079 fprintf(stderr, "SiS end rasterization fallback: 0x%x %s\n",
1080 bit, getFallbackString(bit));
1081 }
1082 }
1083 }
1084 }
1085
1086
1087 /**********************************************************************/
1088 /* Initialization. */
1089 /**********************************************************************/
1090
1091 void sisInitTriFuncs( GLcontext *ctx )
1092 {
1093 sisContextPtr smesa = SIS_CONTEXT(ctx);
1094 TNLcontext *tnl = TNL_CONTEXT(ctx);
1095 static int firsttime = 1;
1096
1097 if (firsttime) {
1098 init_rast_tab();
1099 firsttime = 0;
1100
1101 sis_vert_init_none();
1102 sis_vert_init_g();
1103 sis_vert_init_w();
1104 sis_vert_init_gw();
1105 sis_vert_init_s();
1106 sis_vert_init_gs();
1107 sis_vert_init_ws();
1108 sis_vert_init_gws();
1109 sis_vert_init_t0();
1110 sis_vert_init_gt0();
1111 sis_vert_init_wt0();
1112 sis_vert_init_gwt0();
1113 sis_vert_init_st0();
1114 sis_vert_init_gst0();
1115 sis_vert_init_wst0();
1116 sis_vert_init_gwst0();
1117 sis_vert_init_t1();
1118 sis_vert_init_gt1();
1119 sis_vert_init_wt1();
1120 sis_vert_init_gwt1();
1121 sis_vert_init_st1();
1122 sis_vert_init_gst1();
1123 sis_vert_init_wst1();
1124 sis_vert_init_gwst1();
1125 sis_vert_init_t0t1();
1126 sis_vert_init_gt0t1();
1127 sis_vert_init_wt0t1();
1128 sis_vert_init_gwt0t1();
1129 sis_vert_init_st0t1();
1130 sis_vert_init_gst0t1();
1131 sis_vert_init_wst0t1();
1132 sis_vert_init_gwst0t1();
1133 }
1134
1135 smesa->RenderIndex = ~0;
1136 smesa->NewGLState |= _SIS_NEW_RENDER_STATE;
1137
1138 tnl->Driver.RunPipeline = sisRunPipeline;
1139 tnl->Driver.Render.Start = sisRenderStart;
1140 tnl->Driver.Render.Finish = sisRenderFinish;
1141 tnl->Driver.Render.PrimitiveNotify = sisRenderPrimitive;
1142 tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple;
1143
1144 tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
1145 tnl->Driver.Render.CopyPV = _tnl_copy_pv;
1146 tnl->Driver.Render.Interp = _tnl_interp;
1147
1148 _tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12,
1149 (6 + 2*ctx->Const.MaxTextureUnits) * sizeof(GLfloat) );
1150
1151 smesa->verts = (char *)tnl->clipspace.vertex_buf;
1152 }