1 /* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_swtcl.c,v 1.5 2003/05/06 23:52:08 daenzer Exp $ */
3 Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
5 The Weather Channel (TM) funded Tungsten Graphics to develop the
6 initial release of the Radeon 8500 driver under the XFree86 license.
7 This notice must be preserved.
9 Permission is hereby granted, free of charge, to any person obtaining
10 a copy of this software and associated documentation files (the
11 "Software"), to deal in the Software without restriction, including
12 without limitation the rights to use, copy, modify, merge, publish,
13 distribute, sublicense, and/or sell copies of the Software, and to
14 permit persons to whom the Software is furnished to do so, subject to
15 the following conditions:
17 The above copyright notice and this permission notice (including the
18 next paragraph) shall be included in all copies or substantial
19 portions of the Software.
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
25 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 **************************************************************************/
33 * Keith Whitwell <keith@tungstengraphics.com>
44 #include "swrast/s_context.h"
45 #include "swrast/s_fog.h"
46 #include "swrast_setup/swrast_setup.h"
47 #include "math/m_translate.h"
49 #include "tnl/t_context.h"
50 #include "tnl/t_pipeline.h"
52 #include "r200_context.h"
53 #include "r200_ioctl.h"
54 #include "r200_state.h"
55 #include "r200_swtcl.h"
58 /***********************************************************************
59 * Build render functions from dd templates *
60 ***********************************************************************/
63 #define R200_XYZW_BIT 0x01
64 #define R200_RGBA_BIT 0x02
65 #define R200_SPEC_BIT 0x04
66 #define R200_TEX0_BIT 0x08
67 #define R200_TEX1_BIT 0x10
68 #define R200_PTEX_BIT 0x20
69 #define R200_MAX_SETUP 0x40
71 static void flush_last_swtcl_prim( r200ContextPtr rmesa
);
74 void (*emit
)( GLcontext
*, GLuint
, GLuint
, void *, GLuint
);
77 GLboolean (*check_tex_sizes
)( GLcontext
*ctx
);
79 GLuint vertex_stride_shift
;
81 } setup_tab
[R200_MAX_SETUP
];
84 static int se_vtx_fmt_0
[] = {
89 (R200_VTX_PK_RGBA
<< R200_VTX_COLOR_0_SHIFT
)),
94 (R200_VTX_PK_RGBA
<< R200_VTX_COLOR_0_SHIFT
) |
95 (R200_VTX_PK_RGBA
<< R200_VTX_COLOR_1_SHIFT
)),
100 (R200_VTX_PK_RGBA
<< R200_VTX_COLOR_0_SHIFT
) |
101 (R200_VTX_PK_RGBA
<< R200_VTX_COLOR_1_SHIFT
)),
106 (R200_VTX_PK_RGBA
<< R200_VTX_COLOR_0_SHIFT
) |
107 (R200_VTX_PK_RGBA
<< R200_VTX_COLOR_1_SHIFT
)),
112 (R200_VTX_PK_RGBA
<< R200_VTX_COLOR_0_SHIFT
) |
113 (R200_VTX_PK_RGBA
<< R200_VTX_COLOR_1_SHIFT
))
116 static int se_vtx_fmt_1
[] = {
120 ((2 << R200_VTX_TEX0_COMP_CNT_SHIFT
)),
121 ((2 << R200_VTX_TEX0_COMP_CNT_SHIFT
) |
122 (2 << R200_VTX_TEX1_COMP_CNT_SHIFT
)),
123 ((3 << R200_VTX_TEX0_COMP_CNT_SHIFT
) |
124 (3 << R200_VTX_TEX1_COMP_CNT_SHIFT
)),
127 #define TINY_VERTEX_FORMAT 1
128 #define NOTEX_VERTEX_FORMAT 2
129 #define TEX0_VERTEX_FORMAT 3
130 #define TEX1_VERTEX_FORMAT 4
131 #define PROJ_TEX1_VERTEX_FORMAT 5
132 #define TEX2_VERTEX_FORMAT 0
133 #define TEX3_VERTEX_FORMAT 0
134 #define PROJ_TEX3_VERTEX_FORMAT 0
136 #define DO_XYZW (IND & R200_XYZW_BIT)
137 #define DO_RGBA (IND & R200_RGBA_BIT)
138 #define DO_SPEC (IND & R200_SPEC_BIT)
139 #define DO_FOG (IND & R200_SPEC_BIT)
140 #define DO_TEX0 (IND & R200_TEX0_BIT)
141 #define DO_TEX1 (IND & R200_TEX1_BIT)
144 #define DO_PTEX (IND & R200_PTEX_BIT)
146 #define VERTEX r200Vertex
147 #define VERTEX_COLOR r200_color_t
148 #define GET_VIEWPORT_MAT() 0
149 #define GET_TEXSOURCE(n) n
150 #define GET_VERTEX_FORMAT() R200_CONTEXT(ctx)->swtcl.vertex_format
151 #define GET_VERTEX_STORE() R200_CONTEXT(ctx)->swtcl.verts
152 #define GET_VERTEX_STRIDE_SHIFT() R200_CONTEXT(ctx)->swtcl.vertex_stride_shift
153 #define GET_UBYTE_COLOR_STORE() &R200_CONTEXT(ctx)->UbyteColor
154 #define GET_UBYTE_SPEC_COLOR_STORE() &R200_CONTEXT(ctx)->UbyteSecondaryColor
156 #define HAVE_HW_VIEWPORT 1
157 #define HAVE_HW_DIVIDE (IND & ~(R200_XYZW_BIT|R200_RGBA_BIT))
158 #define HAVE_TINY_VERTICES 1
159 #define HAVE_RGBA_COLOR 1
160 #define HAVE_NOTEX_VERTICES 1
161 #define HAVE_TEX0_VERTICES 1
162 #define HAVE_TEX1_VERTICES 1
163 #define HAVE_TEX2_VERTICES 0
164 #define HAVE_TEX3_VERTICES 0
165 #define HAVE_PTEX_VERTICES 1
167 #define CHECK_HW_DIVIDE (!(ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE| \
170 #define IMPORT_QUALIFIER
171 #define IMPORT_FLOAT_COLORS r200_import_float_colors
172 #define IMPORT_FLOAT_SPEC_COLORS r200_import_float_spec_colors
174 #define INTERP_VERTEX setup_tab[R200_CONTEXT(ctx)->swtcl.SetupIndex].interp
175 #define COPY_PV_VERTEX setup_tab[R200_CONTEXT(ctx)->swtcl.SetupIndex].copy_pv
178 /***********************************************************************
179 * Generate pv-copying and translation functions *
180 ***********************************************************************/
182 #define TAG(x) r200_##x
184 #include "tnl_dd/t_dd_vb.c"
188 /***********************************************************************
189 * Generate vertex emit and interp functions *
190 ***********************************************************************/
192 #define IND (R200_XYZW_BIT|R200_RGBA_BIT)
193 #define TAG(x) x##_wg
194 #include "tnl_dd/t_dd_vbtmp.h"
196 #define IND (R200_XYZW_BIT|R200_RGBA_BIT|R200_TEX0_BIT)
197 #define TAG(x) x##_wgt0
198 #include "tnl_dd/t_dd_vbtmp.h"
200 #define IND (R200_XYZW_BIT|R200_RGBA_BIT|R200_TEX0_BIT|R200_PTEX_BIT)
201 #define TAG(x) x##_wgpt0
202 #include "tnl_dd/t_dd_vbtmp.h"
204 #define IND (R200_XYZW_BIT|R200_RGBA_BIT|R200_TEX0_BIT|R200_TEX1_BIT)
205 #define TAG(x) x##_wgt0t1
206 #include "tnl_dd/t_dd_vbtmp.h"
208 #define IND (R200_XYZW_BIT|R200_RGBA_BIT|R200_TEX0_BIT|R200_TEX1_BIT|\
210 #define TAG(x) x##_wgpt0t1
211 #include "tnl_dd/t_dd_vbtmp.h"
213 #define IND (R200_XYZW_BIT|R200_RGBA_BIT|R200_SPEC_BIT)
214 #define TAG(x) x##_wgfs
215 #include "tnl_dd/t_dd_vbtmp.h"
217 #define IND (R200_XYZW_BIT|R200_RGBA_BIT|R200_SPEC_BIT|\
219 #define TAG(x) x##_wgfst0
220 #include "tnl_dd/t_dd_vbtmp.h"
222 #define IND (R200_XYZW_BIT|R200_RGBA_BIT|R200_SPEC_BIT|\
223 R200_TEX0_BIT|R200_PTEX_BIT)
224 #define TAG(x) x##_wgfspt0
225 #include "tnl_dd/t_dd_vbtmp.h"
227 #define IND (R200_XYZW_BIT|R200_RGBA_BIT|R200_SPEC_BIT|\
228 R200_TEX0_BIT|R200_TEX1_BIT)
229 #define TAG(x) x##_wgfst0t1
230 #include "tnl_dd/t_dd_vbtmp.h"
232 #define IND (R200_XYZW_BIT|R200_RGBA_BIT|R200_SPEC_BIT|\
233 R200_TEX0_BIT|R200_TEX1_BIT|R200_PTEX_BIT)
234 #define TAG(x) x##_wgfspt0t1
235 #include "tnl_dd/t_dd_vbtmp.h"
238 /***********************************************************************
240 ***********************************************************************/
242 static void init_setup_tab( void )
258 void r200PrintSetupFlags(char *msg
, GLuint flags
)
260 fprintf(stderr
, "%s(%x): %s%s%s%s%s%s\n",
263 (flags
& R200_XYZW_BIT
) ? " xyzw," : "",
264 (flags
& R200_RGBA_BIT
) ? " rgba," : "",
265 (flags
& R200_SPEC_BIT
) ? " spec/fog," : "",
266 (flags
& R200_TEX0_BIT
) ? " tex-0," : "",
267 (flags
& R200_TEX1_BIT
) ? " tex-1," : "",
268 (flags
& R200_PTEX_BIT
) ? " proj-tex," : "");
273 static void r200SetVertexFormat( GLcontext
*ctx
, GLuint ind
)
275 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
276 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
278 rmesa
->swtcl
.SetupIndex
= ind
;
280 if (ctx
->_TriangleCaps
& (DD_TRI_LIGHT_TWOSIDE
|DD_TRI_UNFILLED
)) {
281 tnl
->Driver
.Render
.Interp
= r200_interp_extras
;
282 tnl
->Driver
.Render
.CopyPV
= r200_copy_pv_extras
;
285 tnl
->Driver
.Render
.Interp
= setup_tab
[ind
].interp
;
286 tnl
->Driver
.Render
.CopyPV
= setup_tab
[ind
].copy_pv
;
289 if (setup_tab
[ind
].vertex_format
!= rmesa
->swtcl
.vertex_format
) {
292 i
= rmesa
->swtcl
.vertex_format
= setup_tab
[ind
].vertex_format
;
293 rmesa
->swtcl
.vertex_size
= setup_tab
[ind
].vertex_size
;
294 rmesa
->swtcl
.vertex_stride_shift
= setup_tab
[ind
].vertex_stride_shift
;
296 R200_STATECHANGE( rmesa
, vtx
);
297 rmesa
->hw
.vtx
.cmd
[VTX_VTXFMT_0
] = se_vtx_fmt_0
[i
];
298 rmesa
->hw
.vtx
.cmd
[VTX_VTXFMT_1
] = se_vtx_fmt_1
[i
];
302 GLuint vte
= rmesa
->hw
.vte
.cmd
[VTE_SE_VTE_CNTL
];
303 GLuint vap
= rmesa
->hw
.vap
.cmd
[VAP_SE_VAP_CNTL
];
306 /* HW perspective divide is a win, but tiny vertex formats are a
309 if (setup_tab
[ind
].vertex_format
== TINY_VERTEX_FORMAT
||
310 (ctx
->_TriangleCaps
& (DD_TRI_LIGHT_TWOSIDE
|DD_TRI_UNFILLED
))) {
312 vte
|= R200_VTX_XY_FMT
| R200_VTX_Z_FMT
;
313 vte
&= ~R200_VTX_W0_FMT
;
314 vap
|= R200_VAP_FORCE_W_TO_ONE
;
318 vte
&= ~(R200_VTX_XY_FMT
| R200_VTX_Z_FMT
);
319 vte
|= R200_VTX_W0_FMT
;
320 vap
&= ~R200_VAP_FORCE_W_TO_ONE
;
323 _tnl_need_projected_coords( ctx
, needproj
);
324 if (vte
!= rmesa
->hw
.vte
.cmd
[VTE_SE_VTE_CNTL
]) {
325 R200_STATECHANGE( rmesa
, vte
);
326 rmesa
->hw
.vte
.cmd
[VTE_SE_VTE_CNTL
] = vte
;
328 if (vap
!= rmesa
->hw
.vap
.cmd
[VAP_SE_VAP_CNTL
]) {
329 R200_STATECHANGE( rmesa
, vap
);
330 rmesa
->hw
.vap
.cmd
[VAP_SE_VAP_CNTL
] = vap
;
335 static void r200RenderStart( GLcontext
*ctx
)
337 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
339 if (!setup_tab
[rmesa
->swtcl
.SetupIndex
].check_tex_sizes(ctx
)) {
340 r200SetVertexFormat( ctx
, rmesa
->swtcl
.SetupIndex
| R200_PTEX_BIT
);
343 if (rmesa
->dma
.flush
!= 0 &&
344 rmesa
->dma
.flush
!= flush_last_swtcl_prim
)
345 rmesa
->dma
.flush( rmesa
);
349 void r200BuildVertices( GLcontext
*ctx
, GLuint start
, GLuint count
,
352 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
353 GLubyte
*v
= ((GLubyte
*)rmesa
->swtcl
.verts
+
354 (start
<< rmesa
->swtcl
.vertex_stride_shift
));
355 GLuint stride
= 1 << rmesa
->swtcl
.vertex_stride_shift
;
357 newinputs
|= rmesa
->swtcl
.SetupNewInputs
;
358 rmesa
->swtcl
.SetupNewInputs
= 0;
363 setup_tab
[rmesa
->swtcl
.SetupIndex
].emit( ctx
, start
, count
, v
, stride
);
367 void r200ChooseVertexState( GLcontext
*ctx
)
369 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
370 GLuint ind
= (R200_XYZW_BIT
| R200_RGBA_BIT
);
372 if (!rmesa
->TclFallback
|| rmesa
->Fallback
)
375 if (ctx
->Fog
.Enabled
|| (ctx
->_TriangleCaps
& DD_SEPARATE_SPECULAR
))
376 ind
|= R200_SPEC_BIT
;
378 if (ctx
->Texture
._EnabledUnits
& 0x2) /* unit 1 enabled */
379 ind
|= R200_TEX0_BIT
|R200_TEX1_BIT
;
380 else if (ctx
->Texture
._EnabledUnits
& 0x1) /* unit 1 enabled */
381 ind
|= R200_TEX0_BIT
;
383 r200SetVertexFormat( ctx
, ind
);
387 /* Flush vertices in the current dma region.
389 static void flush_last_swtcl_prim( r200ContextPtr rmesa
)
391 if (R200_DEBUG
& DEBUG_IOCTL
)
392 fprintf(stderr
, "%s\n", __FUNCTION__
);
394 rmesa
->dma
.flush
= 0;
396 if (rmesa
->dma
.current
.buf
) {
397 struct r200_dma_region
*current
= &rmesa
->dma
.current
;
398 GLuint current_offset
= (rmesa
->r200Screen
->gart_buffer_offset
+
399 current
->buf
->buf
->idx
* RADEON_BUFFER_SIZE
+
402 assert (!(rmesa
->swtcl
.hw_primitive
& R200_VF_PRIM_WALK_IND
));
404 assert (current
->start
+
405 rmesa
->swtcl
.numverts
* rmesa
->swtcl
.vertex_size
* 4 ==
408 if (rmesa
->dma
.current
.start
!= rmesa
->dma
.current
.ptr
) {
409 r200EmitVertexAOS( rmesa
,
410 rmesa
->swtcl
.vertex_size
,
413 r200EmitVbufPrim( rmesa
,
414 rmesa
->swtcl
.hw_primitive
,
415 rmesa
->swtcl
.numverts
);
418 rmesa
->swtcl
.numverts
= 0;
419 current
->start
= current
->ptr
;
424 /* Alloc space in the current dma region.
426 static __inline
void *r200AllocDmaLowVerts( r200ContextPtr rmesa
,
427 int nverts
, int vsize
)
429 GLuint bytes
= vsize
* nverts
;
431 if ( rmesa
->dma
.current
.ptr
+ bytes
> rmesa
->dma
.current
.end
)
432 r200RefillCurrentDmaRegion( rmesa
);
434 if (!rmesa
->dma
.flush
) {
435 rmesa
->glCtx
->Driver
.NeedFlush
|= FLUSH_STORED_VERTICES
;
436 rmesa
->dma
.flush
= flush_last_swtcl_prim
;
439 ASSERT( vsize
== rmesa
->swtcl
.vertex_size
* 4 );
440 ASSERT( rmesa
->dma
.flush
== flush_last_swtcl_prim
);
441 ASSERT( rmesa
->dma
.current
.start
+
442 rmesa
->swtcl
.numverts
* rmesa
->swtcl
.vertex_size
* 4 ==
443 rmesa
->dma
.current
.ptr
);
447 GLubyte
*head
= (GLubyte
*) (rmesa
->dma
.current
.address
+ rmesa
->dma
.current
.ptr
);
448 rmesa
->dma
.current
.ptr
+= bytes
;
449 rmesa
->swtcl
.numverts
+= nverts
;
458 void r200_emit_contiguous_verts( GLcontext
*ctx
, GLuint start
, GLuint count
)
460 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
461 GLuint vertex_size
= rmesa
->swtcl
.vertex_size
* 4;
462 CARD32
*dest
= r200AllocDmaLowVerts( rmesa
, count
-start
, vertex_size
);
463 setup_tab
[rmesa
->swtcl
.SetupIndex
].emit( ctx
, start
, count
, dest
,
469 void r200_emit_indexed_verts( GLcontext
*ctx
, GLuint start
, GLuint count
)
471 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
473 r200AllocDmaRegionVerts( rmesa
,
474 &rmesa
->swtcl
.indexed_verts
,
476 rmesa
->swtcl
.vertex_size
* 4,
479 setup_tab
[rmesa
->swtcl
.SetupIndex
].emit(
481 rmesa
->swtcl
.indexed_verts
.address
+ rmesa
->swtcl
.indexed_verts
.start
,
482 rmesa
->swtcl
.vertex_size
* 4 );
487 * Render unclipped vertex buffers by emitting vertices directly to
488 * dma buffers. Use strip/fan hardware primitives where possible.
489 * Try to simulate missing primitives with indexed vertices.
491 #define HAVE_POINTS 1
493 #define HAVE_LINE_STRIPS 1
494 #define HAVE_TRIANGLES 1
495 #define HAVE_TRI_STRIPS 1
496 #define HAVE_TRI_STRIP_1 0
497 #define HAVE_TRI_FANS 1
499 #define HAVE_QUAD_STRIPS 1
500 #define HAVE_POLYGONS 1
503 static const GLuint hw_prim
[GL_POLYGON
+1] = {
507 R200_VF_PRIM_LINE_STRIP
,
508 R200_VF_PRIM_TRIANGLES
,
509 R200_VF_PRIM_TRIANGLE_STRIP
,
510 R200_VF_PRIM_TRIANGLE_FAN
,
512 R200_VF_PRIM_QUAD_STRIP
,
516 static __inline
void r200DmaPrimitive( r200ContextPtr rmesa
, GLenum prim
)
518 R200_NEWPRIM( rmesa
);
519 rmesa
->swtcl
.hw_primitive
= hw_prim
[prim
];
520 assert(rmesa
->dma
.current
.ptr
== rmesa
->dma
.current
.start
);
523 static __inline
void r200EltPrimitive( r200ContextPtr rmesa
, GLenum prim
)
525 R200_NEWPRIM( rmesa
);
526 rmesa
->swtcl
.hw_primitive
= hw_prim
[prim
] | R200_VF_PRIM_WALK_IND
;
530 static void VERT_FALLBACK( GLcontext
*ctx
,
535 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
536 tnl
->Driver
.Render
.PrimitiveNotify( ctx
, flags
& PRIM_MODE_MASK
);
537 tnl
->Driver
.Render
.BuildVertices( ctx
, start
, count
, ~0 );
538 tnl
->Driver
.Render
.PrimTabVerts
[flags
&PRIM_MODE_MASK
]( ctx
, start
, count
, flags
);
539 R200_CONTEXT(ctx
)->swtcl
.SetupNewInputs
= _TNL_BIT_POS
;
542 static void ELT_FALLBACK( GLcontext
*ctx
,
547 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
548 tnl
->Driver
.Render
.PrimitiveNotify( ctx
, flags
& PRIM_MODE_MASK
);
549 tnl
->Driver
.Render
.BuildVertices( ctx
, start
, count
, ~0 );
550 tnl
->Driver
.Render
.PrimTabElts
[flags
&PRIM_MODE_MASK
]( ctx
, start
, count
, flags
);
551 R200_CONTEXT(ctx
)->swtcl
.SetupNewInputs
= _TNL_BIT_POS
;
555 #define LOCAL_VARS r200ContextPtr rmesa = R200_CONTEXT(ctx)
556 #define ELTS_VARS GLushort *dest
557 #define INIT( prim ) r200DmaPrimitive( rmesa, prim )
558 #define ELT_INIT(prim) r200EltPrimitive( rmesa, prim )
559 #define NEW_PRIMITIVE() R200_NEWPRIM( rmesa )
560 #define NEW_BUFFER() r200RefillCurrentDmaRegion( rmesa )
561 #define GET_CURRENT_VB_MAX_VERTS() \
562 (((int)rmesa->dma.current.end - (int)rmesa->dma.current.ptr) / (rmesa->swtcl.vertex_size*4))
563 #define GET_SUBSEQUENT_VB_MAX_VERTS() \
564 ((RADEON_BUFFER_SIZE) / (rmesa->swtcl.vertex_size*4))
566 #define GET_CURRENT_VB_MAX_ELTS() \
567 ((R200_CMD_BUF_SZ - (rmesa->store.cmd_used + 16)) / 2)
568 #define GET_SUBSEQUENT_VB_MAX_ELTS() \
569 ((R200_CMD_BUF_SZ - 1024) / 2)
573 /* How do you extend an existing primitive?
575 #define ALLOC_ELTS(nr) \
577 if (rmesa->dma.flush == r200FlushElts && \
578 rmesa->store.cmd_used + nr*2 < R200_CMD_BUF_SZ) { \
580 dest = (GLushort *)(rmesa->store.cmd_buf + \
581 rmesa->store.cmd_used); \
582 rmesa->store.cmd_used += nr*2; \
585 if (rmesa->dma.flush) { \
586 rmesa->dma.flush( rmesa ); \
589 r200EmitVertexAOS( rmesa, \
590 rmesa->swtcl.vertex_size, \
591 (rmesa->r200Screen->gart_buffer_offset + \
592 rmesa->swtcl.indexed_verts.buf->buf->idx * \
593 RADEON_BUFFER_SIZE + \
594 rmesa->swtcl.indexed_verts.start)); \
596 dest = r200AllocEltsOpenEnded( rmesa, \
597 rmesa->swtcl.hw_primitive, \
602 #define ALLOC_ELTS_NEW_PRIMITIVE(nr) ALLOC_ELTS( nr )
604 #ifdef MESA_BIG_ENDIAN
605 /* We could do without (most of) this ugliness if dest was always 32 bit word aligned... */
606 #define EMIT_ELT(offset, x) do { \
607 int off = offset + ( ( (GLuint)dest & 0x2 ) >> 1 ); \
608 GLushort *des = (GLushort *)( (GLuint)dest & ~0x2 ); \
609 (des)[ off + 1 - 2 * ( off & 1 ) ] = (GLushort)(x); } while (0)
611 #define EMIT_ELT(offset, x) (dest)[offset] = (GLushort) (x)
613 #define EMIT_TWO_ELTS(offset, x, y) *(GLuint *)(dest+offset) = ((y)<<16)|(x);
614 #define INCR_ELTS( nr ) dest += nr
615 #define RELEASE_ELT_VERTS() \
616 r200ReleaseDmaRegion( rmesa, &rmesa->swtcl.indexed_verts, __FUNCTION__ )
617 #define EMIT_VERTS( ctx, j, nr ) \
618 r200_emit_contiguous_verts(ctx, j, (j)+(nr))
619 #define EMIT_INDEXED_VERTS( ctx, start, count ) \
620 r200_emit_indexed_verts( ctx, start, count )
623 #define TAG(x) r200_dma_##x
624 #include "tnl_dd/t_dd_dmatmp.h"
627 /**********************************************************************/
628 /* Render pipeline stage */
629 /**********************************************************************/
632 static GLboolean
r200_run_render( GLcontext
*ctx
,
633 struct tnl_pipeline_stage
*stage
)
635 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
636 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
637 struct vertex_buffer
*VB
= &tnl
->vb
;
639 render_func
*tab
= TAG(render_tab_verts
);
641 if (rmesa
->swtcl
.indexed_verts
.buf
&& (!VB
->Elts
|| stage
->changed_inputs
))
646 if ((R200_DEBUG
& DEBUG_VERTS
) || /* No debug */
647 VB
->ClipOrMask
|| /* No clipping */
648 rmesa
->swtcl
.RenderIndex
!= 0 || /* No per-vertex manipulations */
649 ctx
->Line
.StippleFlag
) /* No stipple -- fix me? */
653 tab
= TAG(render_tab_elts
);
654 if (!rmesa
->swtcl
.indexed_verts
.buf
)
655 if (!TAG(emit_elt_verts
)(ctx
, 0, VB
->Count
))
656 return GL_TRUE
; /* too many vertices */
659 tnl
->Driver
.Render
.Start( ctx
);
661 for (i
= 0 ; i
< VB
->PrimitiveCount
; i
++)
663 GLuint prim
= VB
->Primitive
[i
].mode
;
664 GLuint start
= VB
->Primitive
[i
].start
;
665 GLuint length
= VB
->Primitive
[i
].count
;
670 if (R200_DEBUG
& DEBUG_PRIMS
)
671 fprintf(stderr
, "r200_render.c: prim %s %d..%d\n",
672 _mesa_lookup_enum_by_nr(prim
& PRIM_MODE_MASK
),
673 start
, start
+length
);
675 tab
[prim
& PRIM_MODE_MASK
]( ctx
, start
, start
+ length
, prim
);
678 tnl
->Driver
.Render
.Finish( ctx
);
680 return GL_FALSE
; /* finished the pipe */
685 static void r200_check_render( GLcontext
*ctx
,
686 struct tnl_pipeline_stage
*stage
)
688 GLuint inputs
= _TNL_BIT_POS
| _TNL_BIT_COLOR0
;
690 if (ctx
->RenderMode
== GL_RENDER
) {
691 if (ctx
->_TriangleCaps
& DD_SEPARATE_SPECULAR
)
692 inputs
|= _TNL_BIT_COLOR1
;
694 if (ctx
->Texture
.Unit
[0]._ReallyEnabled
)
695 inputs
|= _TNL_BIT_TEX0
;
697 if (ctx
->Texture
.Unit
[1]._ReallyEnabled
)
698 inputs
|= _TNL_BIT_TEX1
;
700 if (ctx
->Fog
.Enabled
)
701 inputs
|= _TNL_BIT_FOG
;
704 stage
->inputs
= inputs
;
708 static void dtr( struct tnl_pipeline_stage
*stage
)
714 const struct tnl_pipeline_stage _r200_render_stage
=
717 (_DD_NEW_SEPARATE_SPECULAR
|
720 _NEW_RENDERMODE
), /* re-check (new inputs) */
721 0, /* re-run (always runs) */
722 GL_TRUE
, /* active */
723 0, 0, /* inputs (set in check_render), outputs */
724 0, 0, /* changed_inputs, private */
725 dtr
, /* destructor */
726 r200_check_render
, /* check - initially set to alloc data */
727 r200_run_render
/* run */
732 /**************************************************************************/
735 static const GLuint reduced_hw_prim
[GL_POLYGON
+1] = {
740 R200_VF_PRIM_TRIANGLES
,
741 R200_VF_PRIM_TRIANGLES
,
742 R200_VF_PRIM_TRIANGLES
,
743 R200_VF_PRIM_TRIANGLES
,
744 R200_VF_PRIM_TRIANGLES
,
745 R200_VF_PRIM_TRIANGLES
748 static void r200RasterPrimitive( GLcontext
*ctx
, GLuint hwprim
);
749 static void r200RenderPrimitive( GLcontext
*ctx
, GLenum prim
);
750 static void r200ResetLineStipple( GLcontext
*ctx
);
755 #undef HAVE_QUAD_STRIPS
756 #define HAVE_QUAD_STRIPS 0
758 /***********************************************************************
759 * Emit primitives as inline vertices *
760 ***********************************************************************/
763 #define CTX_ARG r200ContextPtr rmesa
764 #define CTX_ARG2 rmesa
765 #define GET_VERTEX_DWORDS() rmesa->swtcl.vertex_size
766 #define ALLOC_VERTS( n, size ) r200AllocDmaLowVerts( rmesa, n, size * 4 )
768 r200ContextPtr rmesa = R200_CONTEXT(ctx); \
769 const GLuint shift = rmesa->swtcl.vertex_stride_shift; \
770 const char *r200verts = (char *)rmesa->swtcl.verts;
771 #define VERT(x) (r200Vertex *)(r200verts + (x << shift))
772 #define VERTEX r200Vertex
773 #define DO_DEBUG_VERTS (1 && (R200_DEBUG & DEBUG_VERTS))
774 #define PRINT_VERTEX(v) r200_print_vertex(rmesa->glCtx, v)
776 #define TAG(x) r200_##x
777 #include "tnl_dd/t_dd_triemit.h"
780 /***********************************************************************
781 * Macros for t_dd_tritmp.h to draw basic primitives *
782 ***********************************************************************/
784 #define QUAD( a, b, c, d ) r200_quad( rmesa, a, b, c, d )
785 #define TRI( a, b, c ) r200_triangle( rmesa, a, b, c )
786 #define LINE( a, b ) r200_line( rmesa, a, b )
787 #define POINT( a ) r200_point( rmesa, a )
789 /***********************************************************************
790 * Build render functions from dd templates *
791 ***********************************************************************/
793 #define R200_TWOSIDE_BIT 0x01
794 #define R200_UNFILLED_BIT 0x02
795 #define R200_MAX_TRIFUNC 0x04
801 triangle_func triangle
;
803 } rast_tab
[R200_MAX_TRIFUNC
];
806 #define DO_FALLBACK 0
807 #define DO_UNFILLED (IND & R200_UNFILLED_BIT)
808 #define DO_TWOSIDE (IND & R200_TWOSIDE_BIT)
815 #define DO_FULL_QUAD 1
820 #define HAVE_BACK_COLORS 0
821 #define HAVE_HW_FLATSHADE 1
824 #define DEPTH_SCALE 1.0
825 #define UNFILLED_TRI unfilled_tri
826 #define UNFILLED_QUAD unfilled_quad
827 #define VERT_X(_v) _v->v.x
828 #define VERT_Y(_v) _v->v.y
829 #define VERT_Z(_v) _v->v.z
830 #define AREA_IS_CCW( a ) (a < 0)
831 #define GET_VERTEX(e) (rmesa->swtcl.verts + (e<<rmesa->swtcl.vertex_stride_shift))
833 #define VERT_SET_RGBA( v, c ) \
835 r200_color_t *color = (r200_color_t *)&((v)->ui[coloroffset]); \
836 UNCLAMPED_FLOAT_TO_UBYTE(color->red, (c)[0]); \
837 UNCLAMPED_FLOAT_TO_UBYTE(color->green, (c)[1]); \
838 UNCLAMPED_FLOAT_TO_UBYTE(color->blue, (c)[2]); \
839 UNCLAMPED_FLOAT_TO_UBYTE(color->alpha, (c)[3]); \
842 #define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset]
844 #define VERT_SET_SPEC( v0, c ) \
847 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.red, (c)[0]); \
848 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.green, (c)[1]); \
849 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.blue, (c)[2]); \
852 #define VERT_COPY_SPEC( v0, v1 ) \
855 v0->v.specular.red = v1->v.specular.red; \
856 v0->v.specular.green = v1->v.specular.green; \
857 v0->v.specular.blue = v1->v.specular.blue; \
861 /* These don't need LE32_TO_CPU() as they used to save and restore
862 * colors which are already in the correct format.
864 #define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->ui[coloroffset]
865 #define VERT_RESTORE_RGBA( idx ) v[idx]->ui[coloroffset] = color[idx]
866 #define VERT_SAVE_SPEC( idx ) if (havespec) spec[idx] = v[idx]->ui[5]
867 #define VERT_RESTORE_SPEC( idx ) if (havespec) v[idx]->ui[5] = spec[idx]
873 #define LOCAL_VARS(n) \
874 r200ContextPtr rmesa = R200_CONTEXT(ctx); \
875 GLuint color[n], spec[n]; \
876 GLuint coloroffset = (rmesa->swtcl.vertex_size == 4 ? 3 : 4); \
877 GLboolean havespec = (rmesa->swtcl.vertex_size > 4); \
878 (void) color; (void) spec; (void) coloroffset; (void) havespec;
880 /***********************************************************************
881 * Helpers for rendering unfilled primitives *
882 ***********************************************************************/
884 #define RASTERIZE(x) r200RasterPrimitive( ctx, reduced_hw_prim[x] )
885 #define RENDER_PRIMITIVE rmesa->swtcl.render_primitive
888 #include "tnl_dd/t_dd_unfilled.h"
892 /***********************************************************************
893 * Generate GL render functions *
894 ***********************************************************************/
899 #include "tnl_dd/t_dd_tritmp.h"
901 #define IND (R200_TWOSIDE_BIT)
902 #define TAG(x) x##_twoside
903 #include "tnl_dd/t_dd_tritmp.h"
905 #define IND (R200_UNFILLED_BIT)
906 #define TAG(x) x##_unfilled
907 #include "tnl_dd/t_dd_tritmp.h"
909 #define IND (R200_TWOSIDE_BIT|R200_UNFILLED_BIT)
910 #define TAG(x) x##_twoside_unfilled
911 #include "tnl_dd/t_dd_tritmp.h"
914 static void init_rast_tab( void )
919 init_twoside_unfilled();
922 /**********************************************************************/
923 /* Render unclipped begin/end objects */
924 /**********************************************************************/
926 #define VERT(x) (r200Vertex *)(r200verts + (x << shift))
927 #define RENDER_POINTS( start, count ) \
928 for ( ; start < count ; start++) \
929 r200_point( rmesa, VERT(start) )
930 #define RENDER_LINE( v0, v1 ) \
931 r200_line( rmesa, VERT(v0), VERT(v1) )
932 #define RENDER_TRI( v0, v1, v2 ) \
933 r200_triangle( rmesa, VERT(v0), VERT(v1), VERT(v2) )
934 #define RENDER_QUAD( v0, v1, v2, v3 ) \
935 r200_quad( rmesa, VERT(v0), VERT(v1), VERT(v2), VERT(v3) )
936 #define INIT(x) do { \
937 r200RenderPrimitive( ctx, x ); \
941 r200ContextPtr rmesa = R200_CONTEXT(ctx); \
942 const GLuint shift = rmesa->swtcl.vertex_stride_shift; \
943 const char *r200verts = (char *)rmesa->swtcl.verts; \
944 const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \
945 const GLboolean stipple = ctx->Line.StippleFlag; \
946 (void) elt; (void) stipple;
947 #define RESET_STIPPLE if ( stipple ) r200ResetLineStipple( ctx );
948 #define RESET_OCCLUSION
949 #define PRESERVE_VB_DEFS
951 #define TAG(x) r200_##x##_verts
952 #include "tnl/t_vb_rendertmp.h"
955 #define TAG(x) r200_##x##_elts
956 #define ELT(x) elt[x]
957 #include "tnl/t_vb_rendertmp.h"
961 /**********************************************************************/
962 /* Choose render functions */
963 /**********************************************************************/
965 void r200ChooseRenderState( GLcontext
*ctx
)
967 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
968 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
970 GLuint flags
= ctx
->_TriangleCaps
;
972 if (!rmesa
->TclFallback
|| rmesa
->Fallback
)
975 if (flags
& DD_TRI_LIGHT_TWOSIDE
) index
|= R200_TWOSIDE_BIT
;
976 if (flags
& DD_TRI_UNFILLED
) index
|= R200_UNFILLED_BIT
;
978 if (index
!= rmesa
->swtcl
.RenderIndex
) {
979 tnl
->Driver
.Render
.Points
= rast_tab
[index
].points
;
980 tnl
->Driver
.Render
.Line
= rast_tab
[index
].line
;
981 tnl
->Driver
.Render
.ClippedLine
= rast_tab
[index
].line
;
982 tnl
->Driver
.Render
.Triangle
= rast_tab
[index
].triangle
;
983 tnl
->Driver
.Render
.Quad
= rast_tab
[index
].quad
;
986 tnl
->Driver
.Render
.PrimTabVerts
= r200_render_tab_verts
;
987 tnl
->Driver
.Render
.PrimTabElts
= r200_render_tab_elts
;
988 tnl
->Driver
.Render
.ClippedPolygon
= r200_fast_clipped_poly
;
990 tnl
->Driver
.Render
.PrimTabVerts
= _tnl_render_tab_verts
;
991 tnl
->Driver
.Render
.PrimTabElts
= _tnl_render_tab_elts
;
992 tnl
->Driver
.Render
.ClippedPolygon
= _tnl_RenderClippedPolygon
;
995 rmesa
->swtcl
.RenderIndex
= index
;
1000 /**********************************************************************/
1001 /* High level hooks for t_vb_render.c */
1002 /**********************************************************************/
1005 static void r200RasterPrimitive( GLcontext
*ctx
, GLuint hwprim
)
1007 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1009 if (rmesa
->swtcl
.hw_primitive
!= hwprim
) {
1010 R200_NEWPRIM( rmesa
);
1011 rmesa
->swtcl
.hw_primitive
= hwprim
;
1015 static void r200RenderPrimitive( GLcontext
*ctx
, GLenum prim
)
1017 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1018 rmesa
->swtcl
.render_primitive
= prim
;
1019 if (prim
< GL_TRIANGLES
|| !(ctx
->_TriangleCaps
& DD_TRI_UNFILLED
))
1020 r200RasterPrimitive( ctx
, reduced_hw_prim
[prim
] );
1023 static void r200RenderFinish( GLcontext
*ctx
)
1027 static void r200ResetLineStipple( GLcontext
*ctx
)
1029 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1030 R200_STATECHANGE( rmesa
, lin
);
1034 /**********************************************************************/
1035 /* Transition to/from hardware rasterization. */
1036 /**********************************************************************/
1038 static const char * const fallbackStrings
[] = {
1040 "glDrawBuffer(GL_FRONT_AND_BACK)",
1041 "glEnable(GL_STENCIL) without hw stencil buffer",
1042 "glRenderMode(selection or feedback)",
1044 "glBlendFunc(mode != ADD)",
1046 "Mixing GL_CLAMP_TO_BORDER and GL_CLAMP (or GL_MIRROR_CLAMP_ATI)"
1050 static const char *getFallbackString(GLuint bit
)
1057 return fallbackStrings
[i
];
1061 void r200Fallback( GLcontext
*ctx
, GLuint bit
, GLboolean mode
)
1063 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1064 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
1065 GLuint oldfallback
= rmesa
->Fallback
;
1068 rmesa
->Fallback
|= bit
;
1069 if (oldfallback
== 0) {
1070 R200_FIREVERTICES( rmesa
);
1071 TCL_FALLBACK( ctx
, R200_TCL_FALLBACK_RASTER
, GL_TRUE
);
1072 _swsetup_Wakeup( ctx
);
1073 _tnl_need_projected_coords( ctx
, GL_TRUE
);
1074 rmesa
->swtcl
.RenderIndex
= ~0;
1075 if (R200_DEBUG
& DEBUG_FALLBACKS
) {
1076 fprintf(stderr
, "R200 begin rasterization fallback: 0x%x %s\n",
1077 bit
, getFallbackString(bit
));
1082 rmesa
->Fallback
&= ~bit
;
1083 if (oldfallback
== bit
) {
1084 _swrast_flush( ctx
);
1085 tnl
->Driver
.Render
.Start
= r200RenderStart
;
1086 tnl
->Driver
.Render
.PrimitiveNotify
= r200RenderPrimitive
;
1087 tnl
->Driver
.Render
.Finish
= r200RenderFinish
;
1088 tnl
->Driver
.Render
.BuildVertices
= r200BuildVertices
;
1089 tnl
->Driver
.Render
.ResetLineStipple
= r200ResetLineStipple
;
1090 TCL_FALLBACK( ctx
, R200_TCL_FALLBACK_RASTER
, GL_FALSE
);
1091 if (rmesa
->TclFallback
) {
1092 /* These are already done if rmesa->TclFallback goes to
1093 * zero above. But not if it doesn't (R200_NO_TCL for
1096 r200ChooseVertexState( ctx
);
1097 r200ChooseRenderState( ctx
);
1099 if (R200_DEBUG
& DEBUG_FALLBACKS
) {
1100 fprintf(stderr
, "R200 end rasterization fallback: 0x%x %s\n",
1101 bit
, getFallbackString(bit
));
1110 /* Cope with depth operations by drawing individual pixels as points???
1113 r200PointsBitmap( GLcontext
*ctx
, GLint px
, GLint py
,
1114 GLsizei width
, GLsizei height
,
1115 const struct gl_pixelstore_attrib
*unpack
,
1116 const GLubyte
*bitmap
)
1118 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1119 const GLfloat
*rc
= ctx
->Current
.RasterColor
;
1128 TCL_FALLBACK( ctx
, R200_TCL_FALLBACK_BITMAP
, 1 );
1130 /* Choose tiny vertex format
1132 r200SetVertexFormat( ctx
, R200_XYZW_BIT
| R200_RGBA_BIT
);
1134 /* Ready for point primitives:
1136 r200RenderPrimitive( ctx
, GL_POINTS
);
1138 /* Turn off the hw viewport transformation:
1140 R200_STATECHANGE( rmesa
, vte
);
1141 orig_vte
= rmesa
->hw
.vte
.cmd
[VTE_SE_VTE_CNTL
];
1142 rmesa
->hw
.vte
.cmd
[VTE_SE_VTE_CNTL
] &= ~(R200_VPORT_X_SCALE_ENA
|
1143 R200_VPORT_Y_SCALE_ENA
|
1144 R200_VPORT_Z_SCALE_ENA
|
1145 R200_VPORT_X_OFFSET_ENA
|
1146 R200_VPORT_Y_OFFSET_ENA
|
1147 R200_VPORT_Z_OFFSET_ENA
);
1149 /* Turn off other stuff: Stipple?, texture?, blending?, etc.
1153 /* Populate the vertex
1155 * Incorporate FOG into RGBA
1157 if (ctx
->Fog
.Enabled
) {
1158 const GLfloat
*fc
= ctx
->Fog
.Color
;
1162 if (ctx
->Fog
.FogCoordinateSource
== GL_FOG_COORDINATE_EXT
)
1163 f
= _swrast_z_to_fogfactor(ctx
, ctx
->Current
.Attrib
[VERT_ATTRIB_FOG
][0]);
1165 f
= _swrast_z_to_fogfactor(ctx
, ctx
->Current
.RasterDistance
);
1167 color
[0] = f
* rc
[0] + (1.F
- f
) * fc
[0];
1168 color
[1] = f
* rc
[1] + (1.F
- f
) * fc
[1];
1169 color
[2] = f
* rc
[2] + (1.F
- f
) * fc
[2];
1172 UNCLAMPED_FLOAT_TO_CHAN(vert
.tv
.color
.red
, color
[0]);
1173 UNCLAMPED_FLOAT_TO_CHAN(vert
.tv
.color
.green
, color
[1]);
1174 UNCLAMPED_FLOAT_TO_CHAN(vert
.tv
.color
.blue
, color
[2]);
1175 UNCLAMPED_FLOAT_TO_CHAN(vert
.tv
.color
.alpha
, color
[3]);
1178 UNCLAMPED_FLOAT_TO_CHAN(vert
.tv
.color
.red
, rc
[0]);
1179 UNCLAMPED_FLOAT_TO_CHAN(vert
.tv
.color
.green
, rc
[1]);
1180 UNCLAMPED_FLOAT_TO_CHAN(vert
.tv
.color
.blue
, rc
[2]);
1181 UNCLAMPED_FLOAT_TO_CHAN(vert
.tv
.color
.alpha
, rc
[3]);
1185 vert
.tv
.z
= ctx
->Current
.RasterPos
[2];
1188 /* Update window height
1190 LOCK_HARDWARE( rmesa
);
1191 UNLOCK_HARDWARE( rmesa
);
1192 h
= rmesa
->dri
.drawable
->h
+ rmesa
->dri
.drawable
->y
;
1193 px
+= rmesa
->dri
.drawable
->x
;
1195 /* Clipping handled by existing mechansims in r200_ioctl.c?
1197 for (row
=0; row
<height
; row
++) {
1198 const GLubyte
*src
= (const GLubyte
*)
1199 _mesa_image_address( unpack
, bitmap
, width
, height
,
1200 GL_COLOR_INDEX
, GL_BITMAP
, 0, row
, 0 );
1202 if (unpack
->LsbFirst
) {
1204 GLubyte mask
= 1U << (unpack
->SkipPixels
& 0x7);
1205 for (col
=0; col
<width
; col
++) {
1208 vert
.tv
.y
= h
- (py
+row
) - 1;
1209 r200_point( rmesa
, &vert
);
1212 mask
= ((mask
<< 1) & 0xff) | (mask
>> 7);
1215 /* get ready for next row */
1221 GLubyte mask
= 128U >> (unpack
->SkipPixels
& 0x7);
1222 for (col
=0; col
<width
; col
++) {
1225 vert
.tv
.y
= h
- (py
+row
) - 1;
1226 r200_point( rmesa
, &vert
);
1229 mask
= ((mask
<< 7) & 0xff) | (mask
>> 1);
1231 /* get ready for next row */
1237 /* Fire outstanding vertices, restore state
1239 R200_STATECHANGE( rmesa
, vte
);
1240 rmesa
->hw
.vte
.cmd
[VTE_SE_VTE_CNTL
] = orig_vte
;
1244 TCL_FALLBACK( ctx
, R200_TCL_FALLBACK_BITMAP
, 0 );
1246 /* Need to restore vertexformat?
1248 if (rmesa
->TclFallback
)
1249 r200ChooseVertexState( ctx
);
1253 void r200FlushVertices( GLcontext
*ctx
, GLuint flags
)
1255 _tnl_FlushVertices( ctx
, flags
);
1257 if (flags
& FLUSH_STORED_VERTICES
)
1258 R200_NEWPRIM( R200_CONTEXT( ctx
) );
1261 /**********************************************************************/
1262 /* Initialization. */
1263 /**********************************************************************/
1265 void r200InitSwtcl( GLcontext
*ctx
)
1267 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
1268 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1269 GLuint size
= TNL_CONTEXT(ctx
)->vb
.Size
;
1270 static int firsttime
= 1;
1278 tnl
->Driver
.Render
.Start
= r200RenderStart
;
1279 tnl
->Driver
.Render
.Finish
= r200RenderFinish
;
1280 tnl
->Driver
.Render
.PrimitiveNotify
= r200RenderPrimitive
;
1281 tnl
->Driver
.Render
.ResetLineStipple
= r200ResetLineStipple
;
1282 tnl
->Driver
.Render
.BuildVertices
= r200BuildVertices
;
1284 rmesa
->swtcl
.verts
= (GLubyte
*)ALIGN_MALLOC( size
* 16 * 4, 32 );
1285 rmesa
->swtcl
.RenderIndex
= ~0;
1286 rmesa
->swtcl
.render_primitive
= GL_TRIANGLES
;
1287 rmesa
->swtcl
.hw_primitive
= 0;
1291 void r200DestroySwtcl( GLcontext
*ctx
)
1293 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
1295 if (rmesa
->swtcl
.indexed_verts
.buf
)
1296 r200ReleaseDmaRegion( rmesa
, &rmesa
->swtcl
.indexed_verts
, __FUNCTION__
);
1298 if (rmesa
->swtcl
.verts
) {
1299 ALIGN_FREE(rmesa
->swtcl
.verts
);
1300 rmesa
->swtcl
.verts
= 0;
1303 if (rmesa
->UbyteSecondaryColor
.Ptr
) {
1304 ALIGN_FREE(rmesa
->UbyteSecondaryColor
.Ptr
);
1305 rmesa
->UbyteSecondaryColor
.Ptr
= 0;
1308 if (rmesa
->UbyteColor
.Ptr
) {
1309 ALIGN_FREE(rmesa
->UbyteColor
.Ptr
);
1310 rmesa
->UbyteColor
.Ptr
= 0;