Close some races with locking on R100 and R200 which could manifest as rendering
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_swtcl.c
1 /* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_swtcl.c,v 1.6 2003/05/06 23:52:08 daenzer Exp $ */
2 /**************************************************************************
3
4 Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
5 VA Linux Systems Inc., Fremont, California.
6
7 All Rights Reserved.
8
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:
16
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.
20
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.
28
29 **************************************************************************/
30
31 /*
32 * Authors:
33 * Keith Whitwell <keith@tungstengraphics.com>
34 */
35
36 #include "glheader.h"
37 #include "mtypes.h"
38 #include "colormac.h"
39 #include "enums.h"
40 #include "imports.h"
41 #include "macros.h"
42
43 #include "swrast_setup/swrast_setup.h"
44 #include "math/m_translate.h"
45 #include "tnl/tnl.h"
46 #include "tnl/t_context.h"
47 #include "tnl/t_pipeline.h"
48 #include "tnl/t_vtx_api.h" /* for _tnl_FlushVertices */
49
50 #include "radeon_context.h"
51 #include "radeon_ioctl.h"
52 #include "radeon_state.h"
53 #include "radeon_swtcl.h"
54 #include "radeon_tcl.h"
55
56 /***********************************************************************
57 * Build render functions from dd templates *
58 ***********************************************************************/
59
60
61 #define RADEON_XYZW_BIT 0x01
62 #define RADEON_RGBA_BIT 0x02
63 #define RADEON_SPEC_BIT 0x04
64 #define RADEON_TEX0_BIT 0x08
65 #define RADEON_TEX1_BIT 0x10
66 #define RADEON_PTEX_BIT 0x20
67 #define RADEON_MAX_SETUP 0x40
68
69 static void flush_last_swtcl_prim( radeonContextPtr rmesa );
70
71 static struct {
72 void (*emit)( GLcontext *, GLuint, GLuint, void *, GLuint );
73 tnl_interp_func interp;
74 tnl_copy_pv_func copy_pv;
75 GLboolean (*check_tex_sizes)( GLcontext *ctx );
76 GLuint vertex_size;
77 GLuint vertex_format;
78 } setup_tab[RADEON_MAX_SETUP];
79
80
81 #define TINY_VERTEX_FORMAT (RADEON_CP_VC_FRMT_XY | \
82 RADEON_CP_VC_FRMT_Z | \
83 RADEON_CP_VC_FRMT_PKCOLOR)
84
85 #define NOTEX_VERTEX_FORMAT (RADEON_CP_VC_FRMT_XY | \
86 RADEON_CP_VC_FRMT_Z | \
87 RADEON_CP_VC_FRMT_W0 | \
88 RADEON_CP_VC_FRMT_PKCOLOR | \
89 RADEON_CP_VC_FRMT_PKSPEC)
90
91 #define TEX0_VERTEX_FORMAT (RADEON_CP_VC_FRMT_XY | \
92 RADEON_CP_VC_FRMT_Z | \
93 RADEON_CP_VC_FRMT_W0 | \
94 RADEON_CP_VC_FRMT_PKCOLOR | \
95 RADEON_CP_VC_FRMT_PKSPEC | \
96 RADEON_CP_VC_FRMT_ST0)
97
98 #define TEX1_VERTEX_FORMAT (RADEON_CP_VC_FRMT_XY | \
99 RADEON_CP_VC_FRMT_Z | \
100 RADEON_CP_VC_FRMT_W0 | \
101 RADEON_CP_VC_FRMT_PKCOLOR | \
102 RADEON_CP_VC_FRMT_PKSPEC | \
103 RADEON_CP_VC_FRMT_ST0 | \
104 RADEON_CP_VC_FRMT_ST1)
105
106 #define PROJ_TEX1_VERTEX_FORMAT (RADEON_CP_VC_FRMT_XY | \
107 RADEON_CP_VC_FRMT_Z | \
108 RADEON_CP_VC_FRMT_W0 | \
109 RADEON_CP_VC_FRMT_PKCOLOR | \
110 RADEON_CP_VC_FRMT_PKSPEC | \
111 RADEON_CP_VC_FRMT_ST0 | \
112 RADEON_CP_VC_FRMT_Q0 | \
113 RADEON_CP_VC_FRMT_ST1 | \
114 RADEON_CP_VC_FRMT_Q1)
115
116 #define TEX2_VERTEX_FORMAT 0
117 #define TEX3_VERTEX_FORMAT 0
118 #define PROJ_TEX3_VERTEX_FORMAT 0
119
120 #define DO_XYZW (IND & RADEON_XYZW_BIT)
121 #define DO_RGBA (IND & RADEON_RGBA_BIT)
122 #define DO_SPEC (IND & RADEON_SPEC_BIT)
123 #define DO_FOG (IND & RADEON_SPEC_BIT)
124 #define DO_TEX0 (IND & RADEON_TEX0_BIT)
125 #define DO_TEX1 (IND & RADEON_TEX1_BIT)
126 #define DO_TEX2 0
127 #define DO_TEX3 0
128 #define DO_PTEX (IND & RADEON_PTEX_BIT)
129
130 #define VERTEX radeonVertex
131 #define VERTEX_COLOR radeon_color_t
132 #define GET_VIEWPORT_MAT() 0
133 #define GET_TEXSOURCE(n) n
134 #define GET_VERTEX_FORMAT() RADEON_CONTEXT(ctx)->swtcl.vertex_format
135 #define GET_VERTEX_STORE() RADEON_CONTEXT(ctx)->swtcl.verts
136 #define GET_VERTEX_SIZE() RADEON_CONTEXT(ctx)->swtcl.vertex_size * sizeof(GLuint)
137
138 #define HAVE_HW_VIEWPORT 1
139 /* Tiny vertices don't seem to work atm - haven't looked into why.
140 */
141 #define HAVE_HW_DIVIDE (IND & ~(RADEON_XYZW_BIT|RADEON_RGBA_BIT))
142 #define HAVE_TINY_VERTICES 1
143 #define HAVE_RGBA_COLOR 1
144 #define HAVE_NOTEX_VERTICES 1
145 #define HAVE_TEX0_VERTICES 1
146 #define HAVE_TEX1_VERTICES 1
147 #define HAVE_TEX2_VERTICES 0
148 #define HAVE_TEX3_VERTICES 0
149 #define HAVE_PTEX_VERTICES 1
150
151 #define CHECK_HW_DIVIDE (!(ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE| \
152 DD_TRI_UNFILLED)))
153
154 #define INTERP_VERTEX setup_tab[RADEON_CONTEXT(ctx)->swtcl.SetupIndex].interp
155 #define COPY_PV_VERTEX setup_tab[RADEON_CONTEXT(ctx)->swtcl.SetupIndex].copy_pv
156
157
158 /***********************************************************************
159 * Generate pv-copying and translation functions *
160 ***********************************************************************/
161
162 #define TAG(x) radeon_##x
163 #define IND ~0
164 #include "tnl_dd/t_dd_vb.c"
165 #undef IND
166
167
168 /***********************************************************************
169 * Generate vertex emit and interp functions *
170 ***********************************************************************/
171
172 #define IND (RADEON_XYZW_BIT|RADEON_RGBA_BIT)
173 #define TAG(x) x##_wg
174 #include "tnl_dd/t_dd_vbtmp.h"
175
176 #define IND (RADEON_XYZW_BIT|RADEON_RGBA_BIT|RADEON_TEX0_BIT)
177 #define TAG(x) x##_wgt0
178 #include "tnl_dd/t_dd_vbtmp.h"
179
180 #define IND (RADEON_XYZW_BIT|RADEON_RGBA_BIT|RADEON_TEX0_BIT|RADEON_PTEX_BIT)
181 #define TAG(x) x##_wgpt0
182 #include "tnl_dd/t_dd_vbtmp.h"
183
184 #define IND (RADEON_XYZW_BIT|RADEON_RGBA_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT)
185 #define TAG(x) x##_wgt0t1
186 #include "tnl_dd/t_dd_vbtmp.h"
187
188 #define IND (RADEON_XYZW_BIT|RADEON_RGBA_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT|\
189 RADEON_PTEX_BIT)
190 #define TAG(x) x##_wgpt0t1
191 #include "tnl_dd/t_dd_vbtmp.h"
192
193 #define IND (RADEON_XYZW_BIT|RADEON_RGBA_BIT|RADEON_SPEC_BIT)
194 #define TAG(x) x##_wgfs
195 #include "tnl_dd/t_dd_vbtmp.h"
196
197 #define IND (RADEON_XYZW_BIT|RADEON_RGBA_BIT|RADEON_SPEC_BIT|\
198 RADEON_TEX0_BIT)
199 #define TAG(x) x##_wgfst0
200 #include "tnl_dd/t_dd_vbtmp.h"
201
202 #define IND (RADEON_XYZW_BIT|RADEON_RGBA_BIT|RADEON_SPEC_BIT|\
203 RADEON_TEX0_BIT|RADEON_PTEX_BIT)
204 #define TAG(x) x##_wgfspt0
205 #include "tnl_dd/t_dd_vbtmp.h"
206
207 #define IND (RADEON_XYZW_BIT|RADEON_RGBA_BIT|RADEON_SPEC_BIT|\
208 RADEON_TEX0_BIT|RADEON_TEX1_BIT)
209 #define TAG(x) x##_wgfst0t1
210 #include "tnl_dd/t_dd_vbtmp.h"
211
212 #define IND (RADEON_XYZW_BIT|RADEON_RGBA_BIT|RADEON_SPEC_BIT|\
213 RADEON_TEX0_BIT|RADEON_TEX1_BIT|RADEON_PTEX_BIT)
214 #define TAG(x) x##_wgfspt0t1
215 #include "tnl_dd/t_dd_vbtmp.h"
216
217
218 /***********************************************************************
219 * Initialization
220 ***********************************************************************/
221
222 static void init_setup_tab( void )
223 {
224 init_wg();
225 init_wgt0();
226 init_wgpt0();
227 init_wgt0t1();
228 init_wgpt0t1();
229 init_wgfs();
230 init_wgfst0();
231 init_wgfspt0();
232 init_wgfst0t1();
233 init_wgfspt0t1();
234 }
235
236
237
238 void radeonPrintSetupFlags(char *msg, GLuint flags )
239 {
240 fprintf(stderr, "%s(%x): %s%s%s%s%s%s\n",
241 msg,
242 (int)flags,
243 (flags & RADEON_XYZW_BIT) ? " xyzw," : "",
244 (flags & RADEON_RGBA_BIT) ? " rgba," : "",
245 (flags & RADEON_SPEC_BIT) ? " spec/fog," : "",
246 (flags & RADEON_TEX0_BIT) ? " tex-0," : "",
247 (flags & RADEON_TEX1_BIT) ? " tex-1," : "",
248 (flags & RADEON_PTEX_BIT) ? " proj-tex," : "");
249 }
250
251
252 static void radeonRenderStart( GLcontext *ctx )
253 {
254 TNLcontext *tnl = TNL_CONTEXT(ctx);
255 radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
256
257 if (!setup_tab[rmesa->swtcl.SetupIndex].check_tex_sizes(ctx)) {
258 GLuint ind = rmesa->swtcl.SetupIndex |= (RADEON_PTEX_BIT|RADEON_RGBA_BIT);
259
260 /* Projective textures are handled nicely; just have to change
261 * up to the new vertex format.
262 */
263 if (setup_tab[ind].vertex_format != rmesa->swtcl.vertex_format) {
264 RADEON_NEWPRIM(rmesa);
265 rmesa->swtcl.vertex_format = setup_tab[ind].vertex_format;
266 rmesa->swtcl.vertex_size = setup_tab[ind].vertex_size;
267 }
268
269 if (!(ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) {
270 tnl->Driver.Render.Interp = setup_tab[rmesa->swtcl.SetupIndex].interp;
271 tnl->Driver.Render.CopyPV = setup_tab[rmesa->swtcl.SetupIndex].copy_pv;
272 }
273 }
274
275 if (rmesa->dma.flush != 0 &&
276 rmesa->dma.flush != flush_last_swtcl_prim)
277 rmesa->dma.flush( rmesa );
278 }
279
280
281 void radeonBuildVertices( GLcontext *ctx, GLuint start, GLuint count,
282 GLuint newinputs )
283 {
284 radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
285 GLuint stride = rmesa->swtcl.vertex_size * sizeof(int);
286 GLubyte *v = ((GLubyte *)rmesa->swtcl.verts + (start * stride));
287
288 newinputs |= rmesa->swtcl.SetupNewInputs;
289 rmesa->swtcl.SetupNewInputs = 0;
290
291 if (!newinputs)
292 return;
293
294 setup_tab[rmesa->swtcl.SetupIndex].emit( ctx, start, count, v, stride );
295 }
296
297 void radeonChooseVertexState( GLcontext *ctx )
298 {
299 radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
300 TNLcontext *tnl = TNL_CONTEXT(ctx);
301 GLuint ind = (RADEON_XYZW_BIT | RADEON_RGBA_BIT);
302
303 if (!rmesa->TclFallback || rmesa->Fallback)
304 return;
305
306 if (ctx->Fog.Enabled || (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR))
307 ind |= RADEON_SPEC_BIT;
308
309 if (ctx->Texture._EnabledUnits & 0x2)
310 /* unit 1 enabled */
311 ind |= RADEON_TEX0_BIT|RADEON_TEX1_BIT;
312 else if (ctx->Texture._EnabledUnits & 0x1)
313 /* unit 0 enabled */
314 ind |= RADEON_TEX0_BIT;
315
316 rmesa->swtcl.SetupIndex = ind;
317
318 if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED)) {
319 tnl->Driver.Render.Interp = radeon_interp_extras;
320 tnl->Driver.Render.CopyPV = radeon_copy_pv_extras;
321 }
322 else {
323 tnl->Driver.Render.Interp = setup_tab[ind].interp;
324 tnl->Driver.Render.CopyPV = setup_tab[ind].copy_pv;
325 }
326
327 if (setup_tab[ind].vertex_format != rmesa->swtcl.vertex_format) {
328 RADEON_NEWPRIM(rmesa);
329 rmesa->swtcl.vertex_format = setup_tab[ind].vertex_format;
330 rmesa->swtcl.vertex_size = setup_tab[ind].vertex_size;
331 }
332
333 {
334 GLuint se_coord_fmt, needproj;
335
336 /* HW perspective divide is a win, but tiny vertex formats are a
337 * bigger one.
338 */
339 if (setup_tab[ind].vertex_format == TINY_VERTEX_FORMAT ||
340 (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) {
341 needproj = GL_TRUE;
342 se_coord_fmt = (RADEON_VTX_XY_PRE_MULT_1_OVER_W0 |
343 RADEON_VTX_Z_PRE_MULT_1_OVER_W0 |
344 RADEON_TEX1_W_ROUTING_USE_Q1);
345 }
346 else {
347 needproj = GL_FALSE;
348 se_coord_fmt = (RADEON_VTX_W0_IS_NOT_1_OVER_W0 |
349 RADEON_TEX1_W_ROUTING_USE_Q1);
350 }
351
352 if ( se_coord_fmt != rmesa->hw.set.cmd[SET_SE_COORDFMT] ) {
353 RADEON_STATECHANGE( rmesa, set );
354 rmesa->hw.set.cmd[SET_SE_COORDFMT] = se_coord_fmt;
355 }
356 _tnl_need_projected_coords( ctx, needproj );
357 }
358 }
359
360
361 /* Flush vertices in the current dma region.
362 */
363 static void flush_last_swtcl_prim( radeonContextPtr rmesa )
364 {
365 if (RADEON_DEBUG & DEBUG_IOCTL)
366 fprintf(stderr, "%s\n", __FUNCTION__);
367
368 rmesa->dma.flush = 0;
369
370 if (rmesa->dma.current.buf) {
371 struct radeon_dma_region *current = &rmesa->dma.current;
372 GLuint current_offset = (rmesa->radeonScreen->gart_buffer_offset +
373 current->buf->buf->idx * RADEON_BUFFER_SIZE +
374 current->start);
375
376 assert (!(rmesa->swtcl.hw_primitive & RADEON_CP_VC_CNTL_PRIM_WALK_IND));
377
378 assert (current->start +
379 rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 ==
380 current->ptr);
381
382 if (rmesa->dma.current.start != rmesa->dma.current.ptr) {
383 radeonEnsureCmdBufSpace( rmesa, VERT_AOS_BUFSZ +
384 rmesa->hw.max_state_size + VBUF_BUFSZ );
385 radeonEmitVertexAOS( rmesa,
386 rmesa->swtcl.vertex_size,
387 current_offset);
388
389 radeonEmitVbufPrim( rmesa,
390 rmesa->swtcl.vertex_format,
391 rmesa->swtcl.hw_primitive,
392 rmesa->swtcl.numverts);
393 }
394
395 rmesa->swtcl.numverts = 0;
396 current->start = current->ptr;
397 }
398 }
399
400
401 /* Alloc space in the current dma region.
402 */
403 static __inline void *radeonAllocDmaLowVerts( radeonContextPtr rmesa,
404 int nverts, int vsize )
405 {
406 GLuint bytes = vsize * nverts;
407
408 if ( rmesa->dma.current.ptr + bytes > rmesa->dma.current.end )
409 radeonRefillCurrentDmaRegion( rmesa );
410
411 if (!rmesa->dma.flush) {
412 rmesa->glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
413 rmesa->dma.flush = flush_last_swtcl_prim;
414 }
415
416 assert( vsize == rmesa->swtcl.vertex_size * 4 );
417 assert( rmesa->dma.flush == flush_last_swtcl_prim );
418 assert (rmesa->dma.current.start +
419 rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 ==
420 rmesa->dma.current.ptr);
421
422
423 {
424 GLubyte *head = (GLubyte *)(rmesa->dma.current.address + rmesa->dma.current.ptr);
425 rmesa->dma.current.ptr += bytes;
426 rmesa->swtcl.numverts += nverts;
427 return head;
428 }
429
430 }
431
432
433
434
435 static void *radeon_emit_contiguous_verts( GLcontext *ctx,
436 GLuint start,
437 GLuint count,
438 void *dest)
439 {
440 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
441 GLuint stride = rmesa->swtcl.vertex_size * 4;
442 setup_tab[rmesa->swtcl.SetupIndex].emit( ctx, start, count, dest, stride );
443 return (void *)((char *)dest + stride * (count - start));
444 }
445
446
447
448 void radeon_emit_indexed_verts( GLcontext *ctx, GLuint start, GLuint count )
449 {
450 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
451
452 radeonAllocDmaRegionVerts( rmesa,
453 &rmesa->swtcl.indexed_verts,
454 count - start,
455 rmesa->swtcl.vertex_size * 4,
456 64);
457
458 setup_tab[rmesa->swtcl.SetupIndex].emit(
459 ctx, start, count,
460 rmesa->swtcl.indexed_verts.address + rmesa->swtcl.indexed_verts.start,
461 rmesa->swtcl.vertex_size * 4 );
462 }
463
464
465 /*
466 * Render unclipped vertex buffers by emitting vertices directly to
467 * dma buffers. Use strip/fan hardware primitives where possible.
468 * Try to simulate missing primitives with indexed vertices.
469 */
470 #define HAVE_POINTS 1
471 #define HAVE_LINES 1
472 #define HAVE_LINE_STRIPS 1
473 #define HAVE_TRIANGLES 1
474 #define HAVE_TRI_STRIPS 1
475 #define HAVE_TRI_STRIP_1 0
476 #define HAVE_TRI_FANS 1
477 #define HAVE_QUADS 0
478 #define HAVE_QUAD_STRIPS 0
479 #define HAVE_POLYGONS 0
480 #define HAVE_ELTS 1
481
482 static const GLuint hw_prim[GL_POLYGON+1] = {
483 RADEON_CP_VC_CNTL_PRIM_TYPE_POINT,
484 RADEON_CP_VC_CNTL_PRIM_TYPE_LINE,
485 0,
486 RADEON_CP_VC_CNTL_PRIM_TYPE_LINE_STRIP,
487 RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST,
488 RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_STRIP,
489 RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN,
490 0,
491 0,
492 0
493 };
494
495 static __inline void radeonDmaPrimitive( radeonContextPtr rmesa, GLenum prim )
496 {
497 RADEON_NEWPRIM( rmesa );
498 rmesa->swtcl.hw_primitive = hw_prim[prim];
499 assert(rmesa->dma.current.ptr == rmesa->dma.current.start);
500 }
501
502 static __inline void radeonEltPrimitive( radeonContextPtr rmesa, GLenum prim )
503 {
504 RADEON_NEWPRIM( rmesa );
505 rmesa->swtcl.hw_primitive = hw_prim[prim] | RADEON_CP_VC_CNTL_PRIM_WALK_IND;
506 }
507
508
509
510
511 #define LOCAL_VARS radeonContextPtr rmesa = RADEON_CONTEXT(ctx)
512 #define ELTS_VARS( buf ) GLushort *dest = buf
513 #define INIT( prim ) radeonDmaPrimitive( rmesa, prim )
514 #define ELT_INIT(prim) radeonEltPrimitive( rmesa, prim )
515 #define FLUSH() RADEON_NEWPRIM( rmesa )
516 #define GET_CURRENT_VB_MAX_VERTS() \
517 (((int)rmesa->dma.current.end - (int)rmesa->dma.current.ptr) / (rmesa->swtcl.vertex_size*4))
518 #define GET_SUBSEQUENT_VB_MAX_VERTS() \
519 ((RADEON_BUFFER_SIZE) / (rmesa->swtcl.vertex_size*4))
520
521 #if RADEON_OLD_PACKETS
522 # define GET_CURRENT_VB_MAX_ELTS() \
523 ((RADEON_CMD_BUF_SZ - (rmesa->store.cmd_used + 24)) / 2)
524 #else
525 # define GET_CURRENT_VB_MAX_ELTS() \
526 ((RADEON_CMD_BUF_SZ - (rmesa->store.cmd_used + 16)) / 2)
527 #endif
528 #define GET_SUBSEQUENT_VB_MAX_ELTS() \
529 ((RADEON_CMD_BUF_SZ - 1024) / 2)
530
531
532 static void *radeon_alloc_elts( radeonContextPtr rmesa, int nr )
533 {
534 if (rmesa->dma.flush == radeonFlushElts &&
535 rmesa->store.cmd_used + nr*2 < RADEON_CMD_BUF_SZ) {
536
537 rmesa->store.cmd_used += nr*2;
538
539 return (void *)(rmesa->store.cmd_buf + rmesa->store.cmd_used);
540 }
541 else {
542 if (rmesa->dma.flush) {
543 rmesa->dma.flush( rmesa );
544 }
545
546 radeonEmitVertexAOS( rmesa,
547 rmesa->swtcl.vertex_size,
548 (rmesa->radeonScreen->gart_buffer_offset +
549 rmesa->swtcl.indexed_verts.buf->buf->idx *
550 RADEON_BUFFER_SIZE +
551 rmesa->swtcl.indexed_verts.start));
552
553 return (void *) radeonAllocEltsOpenEnded( rmesa,
554 rmesa->swtcl.vertex_format,
555 rmesa->swtcl.hw_primitive,
556 nr );
557 }
558 }
559
560 #define ALLOC_ELTS(nr) radeon_alloc_elts(rmesa, nr)
561
562 #ifdef MESA_BIG_ENDIAN
563 /* We could do without (most of) this ugliness if dest was always 32 bit word aligned... */
564 #define EMIT_ELT(offset, x) do { \
565 int off = offset + ( ( (GLuint)dest & 0x2 ) >> 1 ); \
566 GLushort *des = (GLushort *)( (GLuint)dest & ~0x2 ); \
567 (des)[ off + 1 - 2 * ( off & 1 ) ] = (GLushort)(x); } while (0)
568 #else
569 #define EMIT_ELT(offset, x) (dest)[offset] = (GLushort) (x)
570 #endif
571 #define EMIT_TWO_ELTS(offset, x, y) *(GLuint *)(dest+offset) = ((y)<<16)|(x);
572 #define INCR_ELTS( nr ) dest += nr
573 #define ELTPTR dest
574 #define RELEASE_ELT_VERTS() \
575 radeonReleaseDmaRegion( rmesa, &rmesa->swtcl.indexed_verts, __FUNCTION__ )
576 #define EMIT_INDEXED_VERTS( ctx, start, count ) \
577 radeon_emit_indexed_verts( ctx, start, count )
578
579
580 #define ALLOC_VERTS( nr ) \
581 radeonAllocDmaLowVerts( rmesa, nr, rmesa->swtcl.vertex_size * 4 )
582 #define EMIT_VERTS( ctx, j, nr, buf ) \
583 radeon_emit_contiguous_verts(ctx, j, (j)+(nr), buf)
584
585 #define TAG(x) radeon_dma_##x
586 #include "tnl_dd/t_dd_dmatmp.h"
587
588
589 /**********************************************************************/
590 /* Render pipeline stage */
591 /**********************************************************************/
592
593
594 static GLboolean radeon_run_render( GLcontext *ctx,
595 struct tnl_pipeline_stage *stage )
596 {
597 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
598 TNLcontext *tnl = TNL_CONTEXT(ctx);
599 struct vertex_buffer *VB = &tnl->vb;
600 tnl_render_func *tab = TAG(render_tab_verts);
601 GLuint i;
602
603 if (rmesa->swtcl.indexed_verts.buf && (!VB->Elts || stage->changed_inputs))
604 RELEASE_ELT_VERTS();
605
606 if (rmesa->swtcl.RenderIndex != 0 ||
607 !radeon_dma_validate_render( ctx, VB ))
608 return GL_TRUE;
609
610 tnl->Driver.Render.Start( ctx );
611
612 if (VB->Elts) {
613 tab = TAG(render_tab_elts);
614 if (!rmesa->swtcl.indexed_verts.buf) {
615 if (VB->Count > GET_SUBSEQUENT_VB_MAX_VERTS())
616 return GL_TRUE;
617 EMIT_INDEXED_VERTS(ctx, 0, VB->Count);
618 }
619 }
620
621 for (i = 0 ; i < VB->PrimitiveCount ; i++)
622 {
623 GLuint prim = VB->Primitive[i].mode;
624 GLuint start = VB->Primitive[i].start;
625 GLuint length = VB->Primitive[i].count;
626
627 if (!length)
628 continue;
629
630 if (RADEON_DEBUG & DEBUG_PRIMS)
631 fprintf(stderr, "radeon_render.c: prim %s %d..%d\n",
632 _mesa_lookup_enum_by_nr(prim & PRIM_MODE_MASK),
633 start, start+length);
634
635 if (length)
636 tab[prim & PRIM_MODE_MASK]( ctx, start, start + length, prim );
637 }
638
639 tnl->Driver.Render.Finish( ctx );
640
641 return GL_FALSE; /* finished the pipe */
642 }
643
644
645
646 static void radeon_check_render( GLcontext *ctx,
647 struct tnl_pipeline_stage *stage )
648 {
649 stage->inputs = TNL_CONTEXT(ctx)->render_inputs;
650 }
651
652
653 static void dtr( struct tnl_pipeline_stage *stage )
654 {
655 (void)stage;
656 }
657
658
659 const struct tnl_pipeline_stage _radeon_render_stage =
660 {
661 "radeon render",
662 (_DD_NEW_SEPARATE_SPECULAR |
663 _NEW_TEXTURE|
664 _NEW_FOG|
665 _NEW_RENDERMODE), /* re-check (new inputs) */
666 0, /* re-run (always runs) */
667 GL_TRUE, /* active */
668 0, 0, /* inputs (set in check_render), outputs */
669 0, 0, /* changed_inputs, private */
670 dtr, /* destructor */
671 radeon_check_render, /* check - initially set to alloc data */
672 radeon_run_render /* run */
673 };
674
675
676 /**************************************************************************/
677
678 /* Radeon texture rectangle expects coords in 0..1 range, not 0..dimension
679 * as in the extension spec. Need to translate here.
680 *
681 * Note that swrast expects 0..dimension, so if a fallback is active,
682 * don't do anything. (Maybe need to configure swrast to match hw)
683 */
684 struct texrect_stage_data {
685 GLvector4f texcoord[MAX_TEXTURE_UNITS];
686 };
687
688 #define TEXRECT_STAGE_DATA(stage) ((struct texrect_stage_data *)stage->privatePtr)
689
690
691 static GLboolean run_texrect_stage( GLcontext *ctx,
692 struct tnl_pipeline_stage *stage )
693 {
694 struct texrect_stage_data *store = TEXRECT_STAGE_DATA(stage);
695 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
696 TNLcontext *tnl = TNL_CONTEXT(ctx);
697 struct vertex_buffer *VB = &tnl->vb;
698 GLuint i;
699
700 if (rmesa->Fallback)
701 return GL_TRUE;
702
703 for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) {
704 if (!(ctx->Texture.Unit[i]._ReallyEnabled & TEXTURE_RECT_BIT))
705 continue;
706
707 if (stage->changed_inputs & VERT_BIT_TEX(i)) {
708 struct gl_texture_object *texObj = ctx->Texture.Unit[i].CurrentRect;
709 struct gl_texture_image *texImage = texObj->Image[0][texObj->BaseLevel];
710 const GLfloat iw = 1.0/texImage->Width;
711 const GLfloat ih = 1.0/texImage->Height;
712 GLfloat *in = (GLfloat *)VB->TexCoordPtr[i]->data;
713 GLint instride = VB->TexCoordPtr[i]->stride;
714 GLfloat (*out)[4] = store->texcoord[i].data;
715 GLint j;
716
717 for (j = 0 ; j < VB->Count ; j++) {
718 out[j][0] = in[0] * iw;
719 out[j][1] = in[1] * ih;
720 in = (GLfloat *)((GLubyte *)in + instride);
721 }
722 }
723
724 VB->TexCoordPtr[i] = &store->texcoord[i];
725 }
726
727 return GL_TRUE;
728 }
729
730
731 /* Called the first time stage->run() is invoked.
732 */
733 static GLboolean alloc_texrect_data( GLcontext *ctx,
734 struct tnl_pipeline_stage *stage )
735 {
736 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
737 struct texrect_stage_data *store;
738 GLuint i;
739
740 stage->privatePtr = CALLOC(sizeof(*store));
741 store = TEXRECT_STAGE_DATA(stage);
742 if (!store)
743 return GL_FALSE;
744
745 for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++)
746 _mesa_vector4f_alloc( &store->texcoord[i], 0, VB->Size, 32 );
747
748 /* Now run the stage.
749 */
750 stage->run = run_texrect_stage;
751 return stage->run( ctx, stage );
752 }
753
754
755 static void check_texrect( GLcontext *ctx,
756 struct tnl_pipeline_stage *stage )
757 {
758 GLuint flags = 0;
759
760 if (ctx->Texture.Unit[0]._ReallyEnabled & TEXTURE_RECT_BIT)
761 flags |= VERT_BIT_TEX0;
762
763 if (ctx->Texture.Unit[1]._ReallyEnabled & TEXTURE_RECT_BIT)
764 flags |= VERT_BIT_TEX1;
765
766 stage->inputs = flags;
767 stage->outputs = flags;
768 stage->active = (flags != 0);
769 }
770
771
772 static void free_texrect_data( struct tnl_pipeline_stage *stage )
773 {
774 struct texrect_stage_data *store = TEXRECT_STAGE_DATA(stage);
775 GLuint i;
776
777 if (store) {
778 for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++)
779 if (store->texcoord[i].data)
780 _mesa_vector4f_free( &store->texcoord[i] );
781 FREE( store );
782 stage->privatePtr = 0;
783 }
784 }
785
786
787 const struct tnl_pipeline_stage _radeon_texrect_stage =
788 {
789 "radeon texrect stage", /* name */
790 _NEW_TEXTURE, /* check_state */
791 _NEW_TEXTURE, /* run_state */
792 GL_TRUE, /* active? */
793 0, /* inputs */
794 0, /* outputs */
795 0, /* changed_inputs */
796 NULL, /* private data */
797 free_texrect_data, /* destructor */
798 check_texrect, /* check */
799 alloc_texrect_data, /* run -- initially set to init */
800 };
801
802
803 /**************************************************************************/
804
805
806 static const GLuint reduced_hw_prim[GL_POLYGON+1] = {
807 RADEON_CP_VC_CNTL_PRIM_TYPE_POINT,
808 RADEON_CP_VC_CNTL_PRIM_TYPE_LINE,
809 RADEON_CP_VC_CNTL_PRIM_TYPE_LINE,
810 RADEON_CP_VC_CNTL_PRIM_TYPE_LINE,
811 RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST,
812 RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST,
813 RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST,
814 RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST,
815 RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST,
816 RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST
817 };
818
819 static void radeonRasterPrimitive( GLcontext *ctx, GLuint hwprim );
820 static void radeonRenderPrimitive( GLcontext *ctx, GLenum prim );
821 static void radeonResetLineStipple( GLcontext *ctx );
822
823
824 /***********************************************************************
825 * Emit primitives as inline vertices *
826 ***********************************************************************/
827
828 #undef LOCAL_VARS
829 #undef ALLOC_VERTS
830 #define CTX_ARG radeonContextPtr rmesa
831 #define CTX_ARG2 rmesa
832 #define GET_VERTEX_DWORDS() rmesa->swtcl.vertex_size
833 #define ALLOC_VERTS( n, size ) radeonAllocDmaLowVerts( rmesa, n, size * 4 )
834 #undef LOCAL_VARS
835 #define LOCAL_VARS \
836 radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \
837 const char *radeonverts = (char *)rmesa->swtcl.verts;
838 #define VERT(x) (radeonVertex *)(radeonverts + (x * vertsize * sizeof(int)))
839 #define VERTEX radeonVertex
840 #undef TAG
841 #define TAG(x) radeon_##x
842 #include "tnl_dd/t_dd_triemit.h"
843
844
845 /***********************************************************************
846 * Macros for t_dd_tritmp.h to draw basic primitives *
847 ***********************************************************************/
848
849 #define QUAD( a, b, c, d ) radeon_quad( rmesa, a, b, c, d )
850 #define TRI( a, b, c ) radeon_triangle( rmesa, a, b, c )
851 #define LINE( a, b ) radeon_line( rmesa, a, b )
852 #define POINT( a ) radeon_point( rmesa, a )
853
854 /***********************************************************************
855 * Build render functions from dd templates *
856 ***********************************************************************/
857
858 #define RADEON_TWOSIDE_BIT 0x01
859 #define RADEON_UNFILLED_BIT 0x02
860 #define RADEON_MAX_TRIFUNC 0x08
861
862
863 static struct {
864 tnl_points_func points;
865 tnl_line_func line;
866 tnl_triangle_func triangle;
867 tnl_quad_func quad;
868 } rast_tab[RADEON_MAX_TRIFUNC];
869
870
871 #define DO_FALLBACK 0
872 #define DO_OFFSET 0
873 #define DO_UNFILLED (IND & RADEON_UNFILLED_BIT)
874 #define DO_TWOSIDE (IND & RADEON_TWOSIDE_BIT)
875 #define DO_FLAT 0
876 #define DO_TRI 1
877 #define DO_QUAD 1
878 #define DO_LINE 1
879 #define DO_POINTS 1
880 #define DO_FULL_QUAD 1
881
882 #define HAVE_RGBA 1
883 #define HAVE_SPEC 1
884 #define HAVE_BACK_COLORS 0
885 #define HAVE_HW_FLATSHADE 1
886 #define TAB rast_tab
887
888 #define DEPTH_SCALE 1.0
889 #define UNFILLED_TRI unfilled_tri
890 #define UNFILLED_QUAD unfilled_quad
891 #define VERT_X(_v) _v->v.x
892 #define VERT_Y(_v) _v->v.y
893 #define VERT_Z(_v) _v->v.z
894 #define AREA_IS_CCW( a ) (a < 0)
895 #define GET_VERTEX(e) (rmesa->swtcl.verts + (e * rmesa->swtcl.vertex_size * sizeof(int)))
896
897 #define VERT_SET_RGBA( v, c ) \
898 do { \
899 radeon_color_t *color = (radeon_color_t *)&((v)->ui[coloroffset]); \
900 UNCLAMPED_FLOAT_TO_UBYTE(color->red, (c)[0]); \
901 UNCLAMPED_FLOAT_TO_UBYTE(color->green, (c)[1]); \
902 UNCLAMPED_FLOAT_TO_UBYTE(color->blue, (c)[2]); \
903 UNCLAMPED_FLOAT_TO_UBYTE(color->alpha, (c)[3]); \
904 } while (0)
905
906 #define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset]
907
908 #define VERT_SET_SPEC( v0, c ) \
909 do { \
910 if (havespec) { \
911 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.red, (c)[0]); \
912 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.green, (c)[1]); \
913 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.blue, (c)[2]); \
914 } \
915 } while (0)
916 #define VERT_COPY_SPEC( v0, v1 ) \
917 do { \
918 if (havespec) { \
919 v0->v.specular.red = v1->v.specular.red; \
920 v0->v.specular.green = v1->v.specular.green; \
921 v0->v.specular.blue = v1->v.specular.blue; \
922 } \
923 } while (0)
924
925 /* These don't need LE32_TO_CPU() as they used to save and restore
926 * colors which are already in the correct format.
927 */
928 #define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->ui[coloroffset]
929 #define VERT_RESTORE_RGBA( idx ) v[idx]->ui[coloroffset] = color[idx]
930 #define VERT_SAVE_SPEC( idx ) if (havespec) spec[idx] = v[idx]->ui[5]
931 #define VERT_RESTORE_SPEC( idx ) if (havespec) v[idx]->ui[5] = spec[idx]
932
933 #undef LOCAL_VARS
934 #undef TAG
935 #undef INIT
936
937 #define LOCAL_VARS(n) \
938 radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \
939 GLuint color[n], spec[n]; \
940 GLuint coloroffset = (rmesa->swtcl.vertex_size == 4 ? 3 : 4); \
941 GLboolean havespec = (rmesa->swtcl.vertex_size > 4); \
942 (void) color; (void) spec; (void) coloroffset; (void) havespec;
943
944 /***********************************************************************
945 * Helpers for rendering unfilled primitives *
946 ***********************************************************************/
947
948 #define RASTERIZE(x) radeonRasterPrimitive( ctx, reduced_hw_prim[x] )
949 #define RENDER_PRIMITIVE rmesa->swtcl.render_primitive
950 #undef TAG
951 #define TAG(x) x
952 #include "tnl_dd/t_dd_unfilled.h"
953 #undef IND
954
955
956 /***********************************************************************
957 * Generate GL render functions *
958 ***********************************************************************/
959
960
961 #define IND (0)
962 #define TAG(x) x
963 #include "tnl_dd/t_dd_tritmp.h"
964
965 #define IND (RADEON_TWOSIDE_BIT)
966 #define TAG(x) x##_twoside
967 #include "tnl_dd/t_dd_tritmp.h"
968
969 #define IND (RADEON_UNFILLED_BIT)
970 #define TAG(x) x##_unfilled
971 #include "tnl_dd/t_dd_tritmp.h"
972
973 #define IND (RADEON_TWOSIDE_BIT|RADEON_UNFILLED_BIT)
974 #define TAG(x) x##_twoside_unfilled
975 #include "tnl_dd/t_dd_tritmp.h"
976
977
978 static void init_rast_tab( void )
979 {
980 init();
981 init_twoside();
982 init_unfilled();
983 init_twoside_unfilled();
984 }
985
986 /**********************************************************************/
987 /* Render unclipped begin/end objects */
988 /**********************************************************************/
989
990 #define VERT(x) (radeonVertex *)(radeonverts + (x * vertsize * sizeof(int)))
991 #define RENDER_POINTS( start, count ) \
992 for ( ; start < count ; start++) \
993 radeon_point( rmesa, VERT(start) )
994 #define RENDER_LINE( v0, v1 ) \
995 radeon_line( rmesa, VERT(v0), VERT(v1) )
996 #define RENDER_TRI( v0, v1, v2 ) \
997 radeon_triangle( rmesa, VERT(v0), VERT(v1), VERT(v2) )
998 #define RENDER_QUAD( v0, v1, v2, v3 ) \
999 radeon_quad( rmesa, VERT(v0), VERT(v1), VERT(v2), VERT(v3) )
1000 #undef INIT
1001 #define INIT(x) do { \
1002 radeonRenderPrimitive( ctx, x ); \
1003 } while (0)
1004 #undef LOCAL_VARS
1005 #define LOCAL_VARS \
1006 radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \
1007 const GLuint vertsize = rmesa->swtcl.vertex_size; \
1008 const char *radeonverts = (char *)rmesa->swtcl.verts; \
1009 const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \
1010 const GLboolean stipple = ctx->Line.StippleFlag; \
1011 (void) elt; (void) stipple;
1012 #define RESET_STIPPLE if ( stipple ) radeonResetLineStipple( ctx );
1013 #define RESET_OCCLUSION
1014 #define PRESERVE_VB_DEFS
1015 #define ELT(x) (x)
1016 #define TAG(x) radeon_##x##_verts
1017 #include "tnl/t_vb_rendertmp.h"
1018 #undef ELT
1019 #undef TAG
1020 #define TAG(x) radeon_##x##_elts
1021 #define ELT(x) elt[x]
1022 #include "tnl/t_vb_rendertmp.h"
1023
1024
1025
1026 /**********************************************************************/
1027 /* Choose render functions */
1028 /**********************************************************************/
1029
1030 void radeonChooseRenderState( GLcontext *ctx )
1031 {
1032 TNLcontext *tnl = TNL_CONTEXT(ctx);
1033 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1034 GLuint index = 0;
1035 GLuint flags = ctx->_TriangleCaps;
1036
1037 if (!rmesa->TclFallback || rmesa->Fallback)
1038 return;
1039
1040 if (flags & DD_TRI_LIGHT_TWOSIDE) index |= RADEON_TWOSIDE_BIT;
1041 if (flags & DD_TRI_UNFILLED) index |= RADEON_UNFILLED_BIT;
1042
1043 if (index != rmesa->swtcl.RenderIndex) {
1044 tnl->Driver.Render.Points = rast_tab[index].points;
1045 tnl->Driver.Render.Line = rast_tab[index].line;
1046 tnl->Driver.Render.ClippedLine = rast_tab[index].line;
1047 tnl->Driver.Render.Triangle = rast_tab[index].triangle;
1048 tnl->Driver.Render.Quad = rast_tab[index].quad;
1049
1050 if (index == 0) {
1051 tnl->Driver.Render.PrimTabVerts = radeon_render_tab_verts;
1052 tnl->Driver.Render.PrimTabElts = radeon_render_tab_elts;
1053 tnl->Driver.Render.ClippedPolygon = radeon_fast_clipped_poly;
1054 } else {
1055 tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
1056 tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
1057 tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon;
1058 }
1059
1060 rmesa->swtcl.RenderIndex = index;
1061 }
1062 }
1063
1064
1065 /**********************************************************************/
1066 /* High level hooks for t_vb_render.c */
1067 /**********************************************************************/
1068
1069
1070 static void radeonRasterPrimitive( GLcontext *ctx, GLuint hwprim )
1071 {
1072 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1073
1074 if (rmesa->swtcl.hw_primitive != hwprim) {
1075 RADEON_NEWPRIM( rmesa );
1076 rmesa->swtcl.hw_primitive = hwprim;
1077 }
1078 }
1079
1080 static void radeonRenderPrimitive( GLcontext *ctx, GLenum prim )
1081 {
1082 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1083 rmesa->swtcl.render_primitive = prim;
1084 if (prim < GL_TRIANGLES || !(ctx->_TriangleCaps & DD_TRI_UNFILLED))
1085 radeonRasterPrimitive( ctx, reduced_hw_prim[prim] );
1086 }
1087
1088 static void radeonRenderFinish( GLcontext *ctx )
1089 {
1090 }
1091
1092 static void radeonResetLineStipple( GLcontext *ctx )
1093 {
1094 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1095 RADEON_STATECHANGE( rmesa, lin );
1096 }
1097
1098
1099 /**********************************************************************/
1100 /* Transition to/from hardware rasterization. */
1101 /**********************************************************************/
1102
1103 static const char * const fallbackStrings[] = {
1104 "Texture mode",
1105 "glDrawBuffer(GL_FRONT_AND_BACK)",
1106 "glEnable(GL_STENCIL) without hw stencil buffer",
1107 "glRenderMode(selection or feedback)",
1108 "glBlendEquation",
1109 "glBlendFunc",
1110 "RADEON_NO_RAST",
1111 "Mixing GL_CLAMP_TO_BORDER and GL_CLAMP (or GL_MIRROR_CLAMP_ATI)"
1112 };
1113
1114
1115 static const char *getFallbackString(GLuint bit)
1116 {
1117 int i = 0;
1118 while (bit > 1) {
1119 i++;
1120 bit >>= 1;
1121 }
1122 return fallbackStrings[i];
1123 }
1124
1125
1126 void radeonFallback( GLcontext *ctx, GLuint bit, GLboolean mode )
1127 {
1128 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1129 TNLcontext *tnl = TNL_CONTEXT(ctx);
1130 GLuint oldfallback = rmesa->Fallback;
1131
1132 if (mode) {
1133 rmesa->Fallback |= bit;
1134 if (oldfallback == 0) {
1135 RADEON_FIREVERTICES( rmesa );
1136 TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_RASTER, GL_TRUE );
1137 _swsetup_Wakeup( ctx );
1138 _tnl_need_projected_coords( ctx, GL_TRUE );
1139 rmesa->swtcl.RenderIndex = ~0;
1140 if (RADEON_DEBUG & DEBUG_FALLBACKS) {
1141 fprintf(stderr, "Radeon begin rasterization fallback: 0x%x %s\n",
1142 bit, getFallbackString(bit));
1143 }
1144 }
1145 }
1146 else {
1147 rmesa->Fallback &= ~bit;
1148 if (oldfallback == bit) {
1149 _swrast_flush( ctx );
1150 tnl->Driver.Render.Start = radeonRenderStart;
1151 tnl->Driver.Render.PrimitiveNotify = radeonRenderPrimitive;
1152 tnl->Driver.Render.Finish = radeonRenderFinish;
1153 tnl->Driver.Render.BuildVertices = radeonBuildVertices;
1154 tnl->Driver.Render.ResetLineStipple = radeonResetLineStipple;
1155 TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_RASTER, GL_FALSE );
1156 if (rmesa->TclFallback) {
1157 /* These are already done if rmesa->TclFallback goes to
1158 * zero above. But not if it doesn't (RADEON_NO_TCL for
1159 * example?)
1160 */
1161 radeonChooseVertexState( ctx );
1162 radeonChooseRenderState( ctx );
1163 }
1164 if (RADEON_DEBUG & DEBUG_FALLBACKS) {
1165 fprintf(stderr, "Radeon end rasterization fallback: 0x%x %s\n",
1166 bit, getFallbackString(bit));
1167 }
1168 }
1169 }
1170 }
1171
1172
1173 void radeonFlushVertices( GLcontext *ctx, GLuint flags )
1174 {
1175 _tnl_FlushVertices( ctx, flags );
1176
1177 if (flags & FLUSH_STORED_VERTICES)
1178 RADEON_NEWPRIM( RADEON_CONTEXT( ctx ) );
1179 }
1180
1181 /**********************************************************************/
1182 /* Initialization. */
1183 /**********************************************************************/
1184
1185 void radeonInitSwtcl( GLcontext *ctx )
1186 {
1187 TNLcontext *tnl = TNL_CONTEXT(ctx);
1188 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1189 GLuint size = TNL_CONTEXT(ctx)->vb.Size;
1190 static int firsttime = 1;
1191
1192 if (firsttime) {
1193 init_rast_tab();
1194 init_setup_tab();
1195 firsttime = 0;
1196 }
1197
1198 tnl->Driver.Render.Start = radeonRenderStart;
1199 tnl->Driver.Render.Finish = radeonRenderFinish;
1200 tnl->Driver.Render.PrimitiveNotify = radeonRenderPrimitive;
1201 tnl->Driver.Render.ResetLineStipple = radeonResetLineStipple;
1202 tnl->Driver.Render.BuildVertices = radeonBuildVertices;
1203
1204 rmesa->swtcl.verts = (GLubyte *)ALIGN_MALLOC( size * 16 * 4, 32 );
1205 rmesa->swtcl.RenderIndex = ~0;
1206 rmesa->swtcl.render_primitive = GL_TRIANGLES;
1207 rmesa->swtcl.hw_primitive = 0;
1208 }
1209
1210
1211 void radeonDestroySwtcl( GLcontext *ctx )
1212 {
1213 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1214
1215 if (rmesa->swtcl.indexed_verts.buf)
1216 radeonReleaseDmaRegion( rmesa, &rmesa->swtcl.indexed_verts,
1217 __FUNCTION__ );
1218
1219 if (rmesa->swtcl.verts) {
1220 ALIGN_FREE(rmesa->swtcl.verts);
1221 rmesa->swtcl.verts = 0;
1222 }
1223
1224 }