61d80c9ac288f3bfa30c31da49e4d307775bb32f
[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 interp_func interp;
74 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 radeonEmitVertexAOS( rmesa,
384 rmesa->swtcl.vertex_size,
385 current_offset);
386
387 radeonEmitVbufPrim( rmesa,
388 rmesa->swtcl.vertex_format,
389 rmesa->swtcl.hw_primitive,
390 rmesa->swtcl.numverts);
391 }
392
393 rmesa->swtcl.numverts = 0;
394 current->start = current->ptr;
395 }
396 }
397
398
399 /* Alloc space in the current dma region.
400 */
401 static __inline void *radeonAllocDmaLowVerts( radeonContextPtr rmesa,
402 int nverts, int vsize )
403 {
404 GLuint bytes = vsize * nverts;
405
406 if ( rmesa->dma.current.ptr + bytes > rmesa->dma.current.end )
407 radeonRefillCurrentDmaRegion( rmesa );
408
409 if (!rmesa->dma.flush) {
410 rmesa->glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
411 rmesa->dma.flush = flush_last_swtcl_prim;
412 }
413
414 assert( vsize == rmesa->swtcl.vertex_size * 4 );
415 assert( rmesa->dma.flush == flush_last_swtcl_prim );
416 assert (rmesa->dma.current.start +
417 rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 ==
418 rmesa->dma.current.ptr);
419
420
421 {
422 GLubyte *head = (GLubyte *)(rmesa->dma.current.address + rmesa->dma.current.ptr);
423 rmesa->dma.current.ptr += bytes;
424 rmesa->swtcl.numverts += nverts;
425 return head;
426 }
427
428 }
429
430
431
432
433 static void *radeon_emit_contiguous_verts( GLcontext *ctx,
434 GLuint start,
435 GLuint count,
436 void *dest)
437 {
438 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
439 GLuint stride = rmesa->swtcl.vertex_size * 4;
440 setup_tab[rmesa->swtcl.SetupIndex].emit( ctx, start, count, dest, stride );
441 return (void *)((char *)dest + stride * (count - start));
442 }
443
444
445
446 void radeon_emit_indexed_verts( GLcontext *ctx, GLuint start, GLuint count )
447 {
448 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
449
450 radeonAllocDmaRegionVerts( rmesa,
451 &rmesa->swtcl.indexed_verts,
452 count - start,
453 rmesa->swtcl.vertex_size * 4,
454 64);
455
456 setup_tab[rmesa->swtcl.SetupIndex].emit(
457 ctx, start, count,
458 rmesa->swtcl.indexed_verts.address + rmesa->swtcl.indexed_verts.start,
459 rmesa->swtcl.vertex_size * 4 );
460 }
461
462
463 /*
464 * Render unclipped vertex buffers by emitting vertices directly to
465 * dma buffers. Use strip/fan hardware primitives where possible.
466 * Try to simulate missing primitives with indexed vertices.
467 */
468 #define HAVE_POINTS 1
469 #define HAVE_LINES 1
470 #define HAVE_LINE_STRIPS 1
471 #define HAVE_TRIANGLES 1
472 #define HAVE_TRI_STRIPS 1
473 #define HAVE_TRI_STRIP_1 0
474 #define HAVE_TRI_FANS 1
475 #define HAVE_QUADS 0
476 #define HAVE_QUAD_STRIPS 0
477 #define HAVE_POLYGONS 0
478 #define HAVE_ELTS 1
479
480 static const GLuint hw_prim[GL_POLYGON+1] = {
481 RADEON_CP_VC_CNTL_PRIM_TYPE_POINT,
482 RADEON_CP_VC_CNTL_PRIM_TYPE_LINE,
483 0,
484 RADEON_CP_VC_CNTL_PRIM_TYPE_LINE_STRIP,
485 RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST,
486 RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_STRIP,
487 RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN,
488 0,
489 0,
490 0
491 };
492
493 static __inline void radeonDmaPrimitive( radeonContextPtr rmesa, GLenum prim )
494 {
495 RADEON_NEWPRIM( rmesa );
496 rmesa->swtcl.hw_primitive = hw_prim[prim];
497 assert(rmesa->dma.current.ptr == rmesa->dma.current.start);
498 }
499
500 static __inline void radeonEltPrimitive( radeonContextPtr rmesa, GLenum prim )
501 {
502 RADEON_NEWPRIM( rmesa );
503 rmesa->swtcl.hw_primitive = hw_prim[prim] | RADEON_CP_VC_CNTL_PRIM_WALK_IND;
504 }
505
506
507
508
509 #define LOCAL_VARS radeonContextPtr rmesa = RADEON_CONTEXT(ctx)
510 #define ELTS_VARS( buf ) GLushort *dest = buf
511 #define INIT( prim ) radeonDmaPrimitive( rmesa, prim )
512 #define ELT_INIT(prim) radeonEltPrimitive( rmesa, prim )
513 #define FLUSH() RADEON_NEWPRIM( rmesa )
514 #define GET_CURRENT_VB_MAX_VERTS() \
515 (((int)rmesa->dma.current.end - (int)rmesa->dma.current.ptr) / (rmesa->swtcl.vertex_size*4))
516 #define GET_SUBSEQUENT_VB_MAX_VERTS() \
517 ((RADEON_BUFFER_SIZE) / (rmesa->swtcl.vertex_size*4))
518
519 #if RADEON_OLD_PACKETS
520 # define GET_CURRENT_VB_MAX_ELTS() \
521 ((RADEON_CMD_BUF_SZ - (rmesa->store.cmd_used + 24)) / 2)
522 #else
523 # define GET_CURRENT_VB_MAX_ELTS() \
524 ((RADEON_CMD_BUF_SZ - (rmesa->store.cmd_used + 16)) / 2)
525 #endif
526 #define GET_SUBSEQUENT_VB_MAX_ELTS() \
527 ((RADEON_CMD_BUF_SZ - 1024) / 2)
528
529
530 static void *radeon_alloc_elts( radeonContextPtr rmesa, int nr )
531 {
532 if (rmesa->dma.flush == radeonFlushElts &&
533 rmesa->store.cmd_used + nr*2 < RADEON_CMD_BUF_SZ) {
534
535 rmesa->store.cmd_used += nr*2;
536
537 return (void *)(rmesa->store.cmd_buf + rmesa->store.cmd_used);
538 }
539 else {
540 if (rmesa->dma.flush) {
541 rmesa->dma.flush( rmesa );
542 }
543
544 radeonEmitVertexAOS( rmesa,
545 rmesa->swtcl.vertex_size,
546 (rmesa->radeonScreen->gart_buffer_offset +
547 rmesa->swtcl.indexed_verts.buf->buf->idx *
548 RADEON_BUFFER_SIZE +
549 rmesa->swtcl.indexed_verts.start));
550
551 return (void *) radeonAllocEltsOpenEnded( rmesa,
552 rmesa->swtcl.vertex_format,
553 rmesa->swtcl.hw_primitive,
554 nr );
555 }
556 }
557
558 #define ALLOC_ELTS(nr) radeon_alloc_elts(rmesa, nr)
559
560 #ifdef MESA_BIG_ENDIAN
561 /* We could do without (most of) this ugliness if dest was always 32 bit word aligned... */
562 #define EMIT_ELT(offset, x) do { \
563 int off = offset + ( ( (GLuint)dest & 0x2 ) >> 1 ); \
564 GLushort *des = (GLushort *)( (GLuint)dest & ~0x2 ); \
565 (des)[ off + 1 - 2 * ( off & 1 ) ] = (GLushort)(x); } while (0)
566 #else
567 #define EMIT_ELT(offset, x) (dest)[offset] = (GLushort) (x)
568 #endif
569 #define EMIT_TWO_ELTS(offset, x, y) *(GLuint *)(dest+offset) = ((y)<<16)|(x);
570 #define INCR_ELTS( nr ) dest += nr
571 #define ELTPTR dest
572 #define RELEASE_ELT_VERTS() \
573 radeonReleaseDmaRegion( rmesa, &rmesa->swtcl.indexed_verts, __FUNCTION__ )
574 #define EMIT_INDEXED_VERTS( ctx, start, count ) \
575 radeon_emit_indexed_verts( ctx, start, count )
576
577
578 #define ALLOC_VERTS( nr ) \
579 radeonAllocDmaLowVerts( rmesa, nr, rmesa->swtcl.vertex_size * 4 )
580 #define EMIT_VERTS( ctx, j, nr, buf ) \
581 radeon_emit_contiguous_verts(ctx, j, (j)+(nr), buf)
582
583 #define TAG(x) radeon_dma_##x
584 #include "tnl_dd/t_dd_dmatmp.h"
585
586
587 /**********************************************************************/
588 /* Render pipeline stage */
589 /**********************************************************************/
590
591
592 static GLboolean radeon_run_render( GLcontext *ctx,
593 struct tnl_pipeline_stage *stage )
594 {
595 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
596 TNLcontext *tnl = TNL_CONTEXT(ctx);
597 struct vertex_buffer *VB = &tnl->vb;
598 render_func *tab = TAG(render_tab_verts);
599 GLuint i;
600
601 if (rmesa->swtcl.indexed_verts.buf && (!VB->Elts || stage->changed_inputs))
602 RELEASE_ELT_VERTS();
603
604 if (rmesa->swtcl.RenderIndex != 0 ||
605 !radeon_dma_validate_render( ctx, VB ))
606 return GL_TRUE;
607
608 tnl->Driver.Render.Start( ctx );
609
610 if (VB->Elts) {
611 tab = TAG(render_tab_elts);
612 if (!rmesa->swtcl.indexed_verts.buf) {
613 if (VB->Count > GET_SUBSEQUENT_VB_MAX_VERTS())
614 return GL_TRUE;
615 EMIT_INDEXED_VERTS(ctx, 0, VB->Count);
616 }
617 }
618
619 for (i = 0 ; i < VB->PrimitiveCount ; i++)
620 {
621 GLuint prim = VB->Primitive[i].mode;
622 GLuint start = VB->Primitive[i].start;
623 GLuint length = VB->Primitive[i].count;
624
625 if (!length)
626 continue;
627
628 if (RADEON_DEBUG & DEBUG_PRIMS)
629 fprintf(stderr, "radeon_render.c: prim %s %d..%d\n",
630 _mesa_lookup_enum_by_nr(prim & PRIM_MODE_MASK),
631 start, start+length);
632
633 if (length)
634 tab[prim & PRIM_MODE_MASK]( ctx, start, start + length, prim );
635 }
636
637 tnl->Driver.Render.Finish( ctx );
638
639 return GL_FALSE; /* finished the pipe */
640 }
641
642
643
644 static void radeon_check_render( GLcontext *ctx,
645 struct tnl_pipeline_stage *stage )
646 {
647 GLuint inputs = VERT_BIT_POS | VERT_BIT_COLOR0;
648
649 if (ctx->RenderMode == GL_RENDER) {
650 if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
651 inputs |= VERT_BIT_COLOR1;
652
653 if (ctx->Texture.Unit[0]._ReallyEnabled)
654 inputs |= VERT_BIT_TEX0;
655
656 if (ctx->Texture.Unit[1]._ReallyEnabled)
657 inputs |= VERT_BIT_TEX1;
658
659 if (ctx->Fog.Enabled)
660 inputs |= VERT_BIT_FOG;
661 }
662
663 stage->inputs = inputs;
664 }
665
666
667 static void dtr( struct tnl_pipeline_stage *stage )
668 {
669 (void)stage;
670 }
671
672
673 const struct tnl_pipeline_stage _radeon_render_stage =
674 {
675 "radeon render",
676 (_DD_NEW_SEPARATE_SPECULAR |
677 _NEW_TEXTURE|
678 _NEW_FOG|
679 _NEW_RENDERMODE), /* re-check (new inputs) */
680 0, /* re-run (always runs) */
681 GL_TRUE, /* active */
682 0, 0, /* inputs (set in check_render), outputs */
683 0, 0, /* changed_inputs, private */
684 dtr, /* destructor */
685 radeon_check_render, /* check - initially set to alloc data */
686 radeon_run_render /* run */
687 };
688
689
690 /**************************************************************************/
691
692 /* Radeon texture rectangle expects coords in 0..1 range, not 0..dimension
693 * as in the extension spec. Need to translate here.
694 *
695 * Note that swrast expects 0..dimension, so if a fallback is active,
696 * don't do anything. (Maybe need to configure swrast to match hw)
697 */
698 struct texrect_stage_data {
699 GLvector4f texcoord[MAX_TEXTURE_UNITS];
700 };
701
702 #define TEXRECT_STAGE_DATA(stage) ((struct texrect_stage_data *)stage->privatePtr)
703
704
705 static GLboolean run_texrect_stage( GLcontext *ctx,
706 struct tnl_pipeline_stage *stage )
707 {
708 struct texrect_stage_data *store = TEXRECT_STAGE_DATA(stage);
709 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
710 TNLcontext *tnl = TNL_CONTEXT(ctx);
711 struct vertex_buffer *VB = &tnl->vb;
712 GLuint i;
713
714 if (rmesa->Fallback)
715 return GL_TRUE;
716
717 for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) {
718 if (!(ctx->Texture.Unit[i]._ReallyEnabled & TEXTURE_RECT_BIT))
719 continue;
720
721 if (stage->changed_inputs & VERT_BIT_TEX(i)) {
722 struct gl_texture_object *texObj = ctx->Texture.Unit[i].CurrentRect;
723 struct gl_texture_image *texImage = texObj->Image[texObj->BaseLevel];
724 const GLfloat iw = 1.0/texImage->Width;
725 const GLfloat ih = 1.0/texImage->Height;
726 GLfloat *in = (GLfloat *)VB->TexCoordPtr[i]->data;
727 GLint instride = VB->TexCoordPtr[i]->stride;
728 GLfloat (*out)[4] = store->texcoord[i].data;
729 GLint j;
730
731 for (j = 0 ; j < VB->Count ; j++) {
732 out[j][0] = in[0] * iw;
733 out[j][1] = in[1] * ih;
734 in = (GLfloat *)((GLubyte *)in + instride);
735 }
736 }
737
738 VB->TexCoordPtr[i] = &store->texcoord[i];
739 }
740
741 return GL_TRUE;
742 }
743
744
745 /* Called the first time stage->run() is invoked.
746 */
747 static GLboolean alloc_texrect_data( GLcontext *ctx,
748 struct tnl_pipeline_stage *stage )
749 {
750 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
751 struct texrect_stage_data *store;
752 GLuint i;
753
754 stage->privatePtr = CALLOC(sizeof(*store));
755 store = TEXRECT_STAGE_DATA(stage);
756 if (!store)
757 return GL_FALSE;
758
759 for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++)
760 _mesa_vector4f_alloc( &store->texcoord[i], 0, VB->Size, 32 );
761
762 /* Now run the stage.
763 */
764 stage->run = run_texrect_stage;
765 return stage->run( ctx, stage );
766 }
767
768
769 static void check_texrect( GLcontext *ctx,
770 struct tnl_pipeline_stage *stage )
771 {
772 GLuint flags = 0;
773
774 if (ctx->Texture.Unit[0]._ReallyEnabled & TEXTURE_RECT_BIT)
775 flags |= VERT_BIT_TEX0;
776
777 if (ctx->Texture.Unit[1]._ReallyEnabled & TEXTURE_RECT_BIT)
778 flags |= VERT_BIT_TEX1;
779
780 stage->inputs = flags;
781 stage->outputs = flags;
782 stage->active = (flags != 0);
783 }
784
785
786 static void free_texrect_data( struct tnl_pipeline_stage *stage )
787 {
788 struct texrect_stage_data *store = TEXRECT_STAGE_DATA(stage);
789 GLuint i;
790
791 if (store) {
792 for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++)
793 if (store->texcoord[i].data)
794 _mesa_vector4f_free( &store->texcoord[i] );
795 FREE( store );
796 stage->privatePtr = 0;
797 }
798 }
799
800
801 const struct tnl_pipeline_stage _radeon_texrect_stage =
802 {
803 "radeon texrect stage", /* name */
804 _NEW_TEXTURE, /* check_state */
805 _NEW_TEXTURE, /* run_state */
806 GL_TRUE, /* active? */
807 0, /* inputs */
808 0, /* outputs */
809 0, /* changed_inputs */
810 NULL, /* private data */
811 free_texrect_data, /* destructor */
812 check_texrect, /* check */
813 alloc_texrect_data, /* run -- initially set to init */
814 };
815
816
817 /**************************************************************************/
818
819
820 static const GLuint reduced_hw_prim[GL_POLYGON+1] = {
821 RADEON_CP_VC_CNTL_PRIM_TYPE_POINT,
822 RADEON_CP_VC_CNTL_PRIM_TYPE_LINE,
823 RADEON_CP_VC_CNTL_PRIM_TYPE_LINE,
824 RADEON_CP_VC_CNTL_PRIM_TYPE_LINE,
825 RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST,
826 RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST,
827 RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST,
828 RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST,
829 RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST,
830 RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST
831 };
832
833 static void radeonRasterPrimitive( GLcontext *ctx, GLuint hwprim );
834 static void radeonRenderPrimitive( GLcontext *ctx, GLenum prim );
835 static void radeonResetLineStipple( GLcontext *ctx );
836
837
838 /***********************************************************************
839 * Emit primitives as inline vertices *
840 ***********************************************************************/
841
842 #undef LOCAL_VARS
843 #undef ALLOC_VERTS
844 #define CTX_ARG radeonContextPtr rmesa
845 #define CTX_ARG2 rmesa
846 #define GET_VERTEX_DWORDS() rmesa->swtcl.vertex_size
847 #define ALLOC_VERTS( n, size ) radeonAllocDmaLowVerts( rmesa, n, size * 4 )
848 #undef LOCAL_VARS
849 #define LOCAL_VARS \
850 radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \
851 const char *radeonverts = (char *)rmesa->swtcl.verts;
852 #define VERT(x) (radeonVertex *)(radeonverts + (x * vertsize * sizeof(int)))
853 #define VERTEX radeonVertex
854 #undef TAG
855 #define TAG(x) radeon_##x
856 #include "tnl_dd/t_dd_triemit.h"
857
858
859 /***********************************************************************
860 * Macros for t_dd_tritmp.h to draw basic primitives *
861 ***********************************************************************/
862
863 #define QUAD( a, b, c, d ) radeon_quad( rmesa, a, b, c, d )
864 #define TRI( a, b, c ) radeon_triangle( rmesa, a, b, c )
865 #define LINE( a, b ) radeon_line( rmesa, a, b )
866 #define POINT( a ) radeon_point( rmesa, a )
867
868 /***********************************************************************
869 * Build render functions from dd templates *
870 ***********************************************************************/
871
872 #define RADEON_TWOSIDE_BIT 0x01
873 #define RADEON_UNFILLED_BIT 0x02
874 #define RADEON_MAX_TRIFUNC 0x08
875
876
877 static struct {
878 points_func points;
879 line_func line;
880 triangle_func triangle;
881 quad_func quad;
882 } rast_tab[RADEON_MAX_TRIFUNC];
883
884
885 #define DO_FALLBACK 0
886 #define DO_OFFSET 0
887 #define DO_UNFILLED (IND & RADEON_UNFILLED_BIT)
888 #define DO_TWOSIDE (IND & RADEON_TWOSIDE_BIT)
889 #define DO_FLAT 0
890 #define DO_TRI 1
891 #define DO_QUAD 1
892 #define DO_LINE 1
893 #define DO_POINTS 1
894 #define DO_FULL_QUAD 1
895
896 #define HAVE_RGBA 1
897 #define HAVE_SPEC 1
898 #define HAVE_INDEX 0
899 #define HAVE_BACK_COLORS 0
900 #define HAVE_HW_FLATSHADE 1
901 #define TAB rast_tab
902
903 #define DEPTH_SCALE 1.0
904 #define UNFILLED_TRI unfilled_tri
905 #define UNFILLED_QUAD unfilled_quad
906 #define VERT_X(_v) _v->v.x
907 #define VERT_Y(_v) _v->v.y
908 #define VERT_Z(_v) _v->v.z
909 #define AREA_IS_CCW( a ) (a < 0)
910 #define GET_VERTEX(e) (rmesa->swtcl.verts + (e * rmesa->swtcl.vertex_size * sizeof(int)))
911
912 #define VERT_SET_RGBA( v, c ) \
913 do { \
914 radeon_color_t *color = (radeon_color_t *)&((v)->ui[coloroffset]); \
915 UNCLAMPED_FLOAT_TO_UBYTE(color->red, (c)[0]); \
916 UNCLAMPED_FLOAT_TO_UBYTE(color->green, (c)[1]); \
917 UNCLAMPED_FLOAT_TO_UBYTE(color->blue, (c)[2]); \
918 UNCLAMPED_FLOAT_TO_UBYTE(color->alpha, (c)[3]); \
919 } while (0)
920
921 #define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset]
922
923 #define VERT_SET_SPEC( v0, c ) \
924 do { \
925 if (havespec) { \
926 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.red, (c)[0]); \
927 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.green, (c)[1]); \
928 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.blue, (c)[2]); \
929 } \
930 } while (0)
931 #define VERT_COPY_SPEC( v0, v1 ) \
932 do { \
933 if (havespec) { \
934 v0->v.specular.red = v1->v.specular.red; \
935 v0->v.specular.green = v1->v.specular.green; \
936 v0->v.specular.blue = v1->v.specular.blue; \
937 } \
938 } while (0)
939
940 /* These don't need LE32_TO_CPU() as they used to save and restore
941 * colors which are already in the correct format.
942 */
943 #define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->ui[coloroffset]
944 #define VERT_RESTORE_RGBA( idx ) v[idx]->ui[coloroffset] = color[idx]
945 #define VERT_SAVE_SPEC( idx ) if (havespec) spec[idx] = v[idx]->ui[5]
946 #define VERT_RESTORE_SPEC( idx ) if (havespec) v[idx]->ui[5] = spec[idx]
947
948 #undef LOCAL_VARS
949 #undef TAG
950 #undef INIT
951
952 #define LOCAL_VARS(n) \
953 radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \
954 GLuint color[n], spec[n]; \
955 GLuint coloroffset = (rmesa->swtcl.vertex_size == 4 ? 3 : 4); \
956 GLboolean havespec = (rmesa->swtcl.vertex_size > 4); \
957 (void) color; (void) spec; (void) coloroffset; (void) havespec;
958
959 /***********************************************************************
960 * Helpers for rendering unfilled primitives *
961 ***********************************************************************/
962
963 #define RASTERIZE(x) radeonRasterPrimitive( ctx, reduced_hw_prim[x] )
964 #define RENDER_PRIMITIVE rmesa->swtcl.render_primitive
965 #undef TAG
966 #define TAG(x) x
967 #include "tnl_dd/t_dd_unfilled.h"
968 #undef IND
969
970
971 /***********************************************************************
972 * Generate GL render functions *
973 ***********************************************************************/
974
975
976 #define IND (0)
977 #define TAG(x) x
978 #include "tnl_dd/t_dd_tritmp.h"
979
980 #define IND (RADEON_TWOSIDE_BIT)
981 #define TAG(x) x##_twoside
982 #include "tnl_dd/t_dd_tritmp.h"
983
984 #define IND (RADEON_UNFILLED_BIT)
985 #define TAG(x) x##_unfilled
986 #include "tnl_dd/t_dd_tritmp.h"
987
988 #define IND (RADEON_TWOSIDE_BIT|RADEON_UNFILLED_BIT)
989 #define TAG(x) x##_twoside_unfilled
990 #include "tnl_dd/t_dd_tritmp.h"
991
992
993 static void init_rast_tab( void )
994 {
995 init();
996 init_twoside();
997 init_unfilled();
998 init_twoside_unfilled();
999 }
1000
1001 /**********************************************************************/
1002 /* Render unclipped begin/end objects */
1003 /**********************************************************************/
1004
1005 #define VERT(x) (radeonVertex *)(radeonverts + (x * vertsize * sizeof(int)))
1006 #define RENDER_POINTS( start, count ) \
1007 for ( ; start < count ; start++) \
1008 radeon_point( rmesa, VERT(start) )
1009 #define RENDER_LINE( v0, v1 ) \
1010 radeon_line( rmesa, VERT(v0), VERT(v1) )
1011 #define RENDER_TRI( v0, v1, v2 ) \
1012 radeon_triangle( rmesa, VERT(v0), VERT(v1), VERT(v2) )
1013 #define RENDER_QUAD( v0, v1, v2, v3 ) \
1014 radeon_quad( rmesa, VERT(v0), VERT(v1), VERT(v2), VERT(v3) )
1015 #undef INIT
1016 #define INIT(x) do { \
1017 radeonRenderPrimitive( ctx, x ); \
1018 } while (0)
1019 #undef LOCAL_VARS
1020 #define LOCAL_VARS \
1021 radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \
1022 const GLuint vertsize = rmesa->swtcl.vertex_size; \
1023 const char *radeonverts = (char *)rmesa->swtcl.verts; \
1024 const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \
1025 const GLboolean stipple = ctx->Line.StippleFlag; \
1026 (void) elt; (void) stipple;
1027 #define RESET_STIPPLE if ( stipple ) radeonResetLineStipple( ctx );
1028 #define RESET_OCCLUSION
1029 #define PRESERVE_VB_DEFS
1030 #define ELT(x) (x)
1031 #define TAG(x) radeon_##x##_verts
1032 #include "tnl/t_vb_rendertmp.h"
1033 #undef ELT
1034 #undef TAG
1035 #define TAG(x) radeon_##x##_elts
1036 #define ELT(x) elt[x]
1037 #include "tnl/t_vb_rendertmp.h"
1038
1039
1040
1041 /**********************************************************************/
1042 /* Choose render functions */
1043 /**********************************************************************/
1044
1045 void radeonChooseRenderState( GLcontext *ctx )
1046 {
1047 TNLcontext *tnl = TNL_CONTEXT(ctx);
1048 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1049 GLuint index = 0;
1050 GLuint flags = ctx->_TriangleCaps;
1051
1052 if (!rmesa->TclFallback || rmesa->Fallback)
1053 return;
1054
1055 if (flags & DD_TRI_LIGHT_TWOSIDE) index |= RADEON_TWOSIDE_BIT;
1056 if (flags & DD_TRI_UNFILLED) index |= RADEON_UNFILLED_BIT;
1057
1058 if (index != rmesa->swtcl.RenderIndex) {
1059 tnl->Driver.Render.Points = rast_tab[index].points;
1060 tnl->Driver.Render.Line = rast_tab[index].line;
1061 tnl->Driver.Render.ClippedLine = rast_tab[index].line;
1062 tnl->Driver.Render.Triangle = rast_tab[index].triangle;
1063 tnl->Driver.Render.Quad = rast_tab[index].quad;
1064
1065 if (index == 0) {
1066 tnl->Driver.Render.PrimTabVerts = radeon_render_tab_verts;
1067 tnl->Driver.Render.PrimTabElts = radeon_render_tab_elts;
1068 tnl->Driver.Render.ClippedPolygon = radeon_fast_clipped_poly;
1069 } else {
1070 tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
1071 tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
1072 tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon;
1073 }
1074
1075 rmesa->swtcl.RenderIndex = index;
1076 }
1077 }
1078
1079
1080 /**********************************************************************/
1081 /* High level hooks for t_vb_render.c */
1082 /**********************************************************************/
1083
1084
1085 static void radeonRasterPrimitive( GLcontext *ctx, GLuint hwprim )
1086 {
1087 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1088
1089 if (rmesa->swtcl.hw_primitive != hwprim) {
1090 RADEON_NEWPRIM( rmesa );
1091 rmesa->swtcl.hw_primitive = hwprim;
1092 }
1093 }
1094
1095 static void radeonRenderPrimitive( GLcontext *ctx, GLenum prim )
1096 {
1097 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1098 rmesa->swtcl.render_primitive = prim;
1099 if (prim < GL_TRIANGLES || !(ctx->_TriangleCaps & DD_TRI_UNFILLED))
1100 radeonRasterPrimitive( ctx, reduced_hw_prim[prim] );
1101 }
1102
1103 static void radeonRenderFinish( GLcontext *ctx )
1104 {
1105 }
1106
1107 static void radeonResetLineStipple( GLcontext *ctx )
1108 {
1109 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1110 RADEON_STATECHANGE( rmesa, lin );
1111 }
1112
1113
1114 /**********************************************************************/
1115 /* Transition to/from hardware rasterization. */
1116 /**********************************************************************/
1117
1118 static const char * const fallbackStrings[] = {
1119 "Texture mode",
1120 "glDrawBuffer(GL_FRONT_AND_BACK)",
1121 "glEnable(GL_STENCIL) without hw stencil buffer",
1122 "glRenderMode(selection or feedback)",
1123 "glBlendEquation",
1124 "glBlendFunc",
1125 "RADEON_NO_RAST",
1126 "Mixing GL_CLAMP_TO_BORDER and GL_CLAMP (or GL_MIRROR_CLAMP_ATI)"
1127 };
1128
1129
1130 static const char *getFallbackString(GLuint bit)
1131 {
1132 int i = 0;
1133 while (bit > 1) {
1134 i++;
1135 bit >>= 1;
1136 }
1137 return fallbackStrings[i];
1138 }
1139
1140
1141 void radeonFallback( GLcontext *ctx, GLuint bit, GLboolean mode )
1142 {
1143 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1144 TNLcontext *tnl = TNL_CONTEXT(ctx);
1145 GLuint oldfallback = rmesa->Fallback;
1146
1147 if (mode) {
1148 rmesa->Fallback |= bit;
1149 if (oldfallback == 0) {
1150 RADEON_FIREVERTICES( rmesa );
1151 TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_RASTER, GL_TRUE );
1152 _swsetup_Wakeup( ctx );
1153 _tnl_need_projected_coords( ctx, GL_TRUE );
1154 rmesa->swtcl.RenderIndex = ~0;
1155 if (RADEON_DEBUG & DEBUG_FALLBACKS) {
1156 fprintf(stderr, "Radeon begin rasterization fallback: 0x%x %s\n",
1157 bit, getFallbackString(bit));
1158 }
1159 }
1160 }
1161 else {
1162 rmesa->Fallback &= ~bit;
1163 if (oldfallback == bit) {
1164 _swrast_flush( ctx );
1165 tnl->Driver.Render.Start = radeonRenderStart;
1166 tnl->Driver.Render.PrimitiveNotify = radeonRenderPrimitive;
1167 tnl->Driver.Render.Finish = radeonRenderFinish;
1168 tnl->Driver.Render.BuildVertices = radeonBuildVertices;
1169 tnl->Driver.Render.ResetLineStipple = radeonResetLineStipple;
1170 TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_RASTER, GL_FALSE );
1171 if (rmesa->TclFallback) {
1172 /* These are already done if rmesa->TclFallback goes to
1173 * zero above. But not if it doesn't (RADEON_NO_TCL for
1174 * example?)
1175 */
1176 radeonChooseVertexState( ctx );
1177 radeonChooseRenderState( ctx );
1178 }
1179 if (RADEON_DEBUG & DEBUG_FALLBACKS) {
1180 fprintf(stderr, "Radeon end rasterization fallback: 0x%x %s\n",
1181 bit, getFallbackString(bit));
1182 }
1183 }
1184 }
1185 }
1186
1187
1188 void radeonFlushVertices( GLcontext *ctx, GLuint flags )
1189 {
1190 _tnl_FlushVertices( ctx, flags );
1191
1192 if (flags & FLUSH_STORED_VERTICES)
1193 RADEON_NEWPRIM( RADEON_CONTEXT( ctx ) );
1194 }
1195
1196 /**********************************************************************/
1197 /* Initialization. */
1198 /**********************************************************************/
1199
1200 void radeonInitSwtcl( GLcontext *ctx )
1201 {
1202 TNLcontext *tnl = TNL_CONTEXT(ctx);
1203 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1204 GLuint size = TNL_CONTEXT(ctx)->vb.Size;
1205 static int firsttime = 1;
1206
1207 if (firsttime) {
1208 init_rast_tab();
1209 init_setup_tab();
1210 firsttime = 0;
1211 }
1212
1213 tnl->Driver.Render.Start = radeonRenderStart;
1214 tnl->Driver.Render.Finish = radeonRenderFinish;
1215 tnl->Driver.Render.PrimitiveNotify = radeonRenderPrimitive;
1216 tnl->Driver.Render.ResetLineStipple = radeonResetLineStipple;
1217 tnl->Driver.Render.BuildVertices = radeonBuildVertices;
1218
1219 rmesa->swtcl.verts = (GLubyte *)ALIGN_MALLOC( size * 16 * 4, 32 );
1220 rmesa->swtcl.RenderIndex = ~0;
1221 rmesa->swtcl.render_primitive = GL_TRIANGLES;
1222 rmesa->swtcl.hw_primitive = 0;
1223 }
1224
1225
1226 void radeonDestroySwtcl( GLcontext *ctx )
1227 {
1228 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1229
1230 if (rmesa->swtcl.indexed_verts.buf)
1231 radeonReleaseDmaRegion( rmesa, &rmesa->swtcl.indexed_verts,
1232 __FUNCTION__ );
1233
1234 if (rmesa->swtcl.verts) {
1235 ALIGN_FREE(rmesa->swtcl.verts);
1236 rmesa->swtcl.verts = 0;
1237 }
1238
1239 }