a66879fe75da3d3d1f3a7c3b7e91e8f620257b39
[mesa.git] / src / mesa / drivers / dri / r200 / r200_swtcl.c
1 /* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_swtcl.c,v 1.5 2003/05/06 23:52:08 daenzer Exp $ */
2 /*
3 Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
4
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.
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 "image.h"
41 #include "imports.h"
42 #include "macros.h"
43
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"
48 #include "tnl/tnl.h"
49 #include "tnl/t_context.h"
50 #include "tnl/t_pipeline.h"
51 #include "tnl/t_vtx_api.h"
52
53 #include "r200_context.h"
54 #include "r200_ioctl.h"
55 #include "r200_state.h"
56 #include "r200_swtcl.h"
57 #include "r200_tcl.h"
58
59 /***********************************************************************
60 * Build render functions from dd templates *
61 ***********************************************************************/
62
63
64 #define R200_XYZW_BIT 0x01
65 #define R200_RGBA_BIT 0x02
66 #define R200_SPEC_BIT 0x04
67 #define R200_TEX0_BIT 0x08
68 #define R200_TEX1_BIT 0x10
69 #define R200_PTEX_BIT 0x20
70 #define R200_MAX_SETUP 0x40
71
72 static void flush_last_swtcl_prim( r200ContextPtr rmesa );
73
74 static struct {
75 void (*emit)( GLcontext *, GLuint, GLuint, void *, GLuint );
76 interp_func interp;
77 copy_pv_func copy_pv;
78 GLboolean (*check_tex_sizes)( GLcontext *ctx );
79 GLuint vertex_size;
80 GLuint vertex_format;
81 } setup_tab[R200_MAX_SETUP];
82
83
84 static int se_vtx_fmt_0[] = {
85 0,
86
87 (R200_VTX_XY |
88 R200_VTX_Z0 |
89 (R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT)),
90
91 (R200_VTX_XY |
92 R200_VTX_Z0 |
93 R200_VTX_W0 |
94 (R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT) |
95 (R200_VTX_PK_RGBA << R200_VTX_COLOR_1_SHIFT)),
96
97 (R200_VTX_XY |
98 R200_VTX_Z0 |
99 R200_VTX_W0 |
100 (R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT) |
101 (R200_VTX_PK_RGBA << R200_VTX_COLOR_1_SHIFT)),
102
103 (R200_VTX_XY |
104 R200_VTX_Z0 |
105 R200_VTX_W0 |
106 (R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT) |
107 (R200_VTX_PK_RGBA << R200_VTX_COLOR_1_SHIFT)),
108
109 (R200_VTX_XY |
110 R200_VTX_Z0 |
111 R200_VTX_W0 |
112 (R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT) |
113 (R200_VTX_PK_RGBA << R200_VTX_COLOR_1_SHIFT))
114 };
115
116 static int se_vtx_fmt_1[] = {
117 0,
118 0,
119 0,
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)),
125 };
126
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
135
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)
142 #define DO_TEX2 0
143 #define DO_TEX3 0
144 #define DO_PTEX (IND & R200_PTEX_BIT)
145
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_SIZE() R200_CONTEXT(ctx)->swtcl.vertex_size * sizeof(GLuint)
153
154 #define HAVE_HW_VIEWPORT 1
155 #define HAVE_HW_DIVIDE (IND & ~(R200_XYZW_BIT|R200_RGBA_BIT))
156 #define HAVE_TINY_VERTICES 1
157 #define HAVE_RGBA_COLOR 1
158 #define HAVE_NOTEX_VERTICES 1
159 #define HAVE_TEX0_VERTICES 1
160 #define HAVE_TEX1_VERTICES 1
161 #define HAVE_TEX2_VERTICES 0
162 #define HAVE_TEX3_VERTICES 0
163 #define HAVE_PTEX_VERTICES 1
164
165 #define CHECK_HW_DIVIDE (!(ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE| \
166 DD_TRI_UNFILLED)))
167
168 #define INTERP_VERTEX setup_tab[R200_CONTEXT(ctx)->swtcl.SetupIndex].interp
169 #define COPY_PV_VERTEX setup_tab[R200_CONTEXT(ctx)->swtcl.SetupIndex].copy_pv
170
171
172 /***********************************************************************
173 * Generate pv-copying and translation functions *
174 ***********************************************************************/
175
176 #define TAG(x) r200_##x
177 #define IND ~0
178 #include "tnl_dd/t_dd_vb.c"
179 #undef IND
180
181
182 /***********************************************************************
183 * Generate vertex emit and interp functions *
184 ***********************************************************************/
185
186 #define IND (R200_XYZW_BIT|R200_RGBA_BIT)
187 #define TAG(x) x##_wg
188 #include "tnl_dd/t_dd_vbtmp.h"
189
190 #define IND (R200_XYZW_BIT|R200_RGBA_BIT|R200_TEX0_BIT)
191 #define TAG(x) x##_wgt0
192 #include "tnl_dd/t_dd_vbtmp.h"
193
194 #define IND (R200_XYZW_BIT|R200_RGBA_BIT|R200_TEX0_BIT|R200_PTEX_BIT)
195 #define TAG(x) x##_wgpt0
196 #include "tnl_dd/t_dd_vbtmp.h"
197
198 #define IND (R200_XYZW_BIT|R200_RGBA_BIT|R200_TEX0_BIT|R200_TEX1_BIT)
199 #define TAG(x) x##_wgt0t1
200 #include "tnl_dd/t_dd_vbtmp.h"
201
202 #define IND (R200_XYZW_BIT|R200_RGBA_BIT|R200_TEX0_BIT|R200_TEX1_BIT|\
203 R200_PTEX_BIT)
204 #define TAG(x) x##_wgpt0t1
205 #include "tnl_dd/t_dd_vbtmp.h"
206
207 #define IND (R200_XYZW_BIT|R200_RGBA_BIT|R200_SPEC_BIT)
208 #define TAG(x) x##_wgfs
209 #include "tnl_dd/t_dd_vbtmp.h"
210
211 #define IND (R200_XYZW_BIT|R200_RGBA_BIT|R200_SPEC_BIT|\
212 R200_TEX0_BIT)
213 #define TAG(x) x##_wgfst0
214 #include "tnl_dd/t_dd_vbtmp.h"
215
216 #define IND (R200_XYZW_BIT|R200_RGBA_BIT|R200_SPEC_BIT|\
217 R200_TEX0_BIT|R200_PTEX_BIT)
218 #define TAG(x) x##_wgfspt0
219 #include "tnl_dd/t_dd_vbtmp.h"
220
221 #define IND (R200_XYZW_BIT|R200_RGBA_BIT|R200_SPEC_BIT|\
222 R200_TEX0_BIT|R200_TEX1_BIT)
223 #define TAG(x) x##_wgfst0t1
224 #include "tnl_dd/t_dd_vbtmp.h"
225
226 #define IND (R200_XYZW_BIT|R200_RGBA_BIT|R200_SPEC_BIT|\
227 R200_TEX0_BIT|R200_TEX1_BIT|R200_PTEX_BIT)
228 #define TAG(x) x##_wgfspt0t1
229 #include "tnl_dd/t_dd_vbtmp.h"
230
231
232 /***********************************************************************
233 * Initialization
234 ***********************************************************************/
235
236 static void init_setup_tab( void )
237 {
238 init_wg();
239 init_wgt0();
240 init_wgpt0();
241 init_wgt0t1();
242 init_wgpt0t1();
243 init_wgfs();
244 init_wgfst0();
245 init_wgfspt0();
246 init_wgfst0t1();
247 init_wgfspt0t1();
248 }
249
250
251
252 void r200PrintSetupFlags(char *msg, GLuint flags )
253 {
254 fprintf(stderr, "%s(%x): %s%s%s%s%s%s\n",
255 msg,
256 (int)flags,
257 (flags & R200_XYZW_BIT) ? " xyzw," : "",
258 (flags & R200_RGBA_BIT) ? " rgba," : "",
259 (flags & R200_SPEC_BIT) ? " spec/fog," : "",
260 (flags & R200_TEX0_BIT) ? " tex-0," : "",
261 (flags & R200_TEX1_BIT) ? " tex-1," : "",
262 (flags & R200_PTEX_BIT) ? " proj-tex," : "");
263 }
264
265
266
267 static void r200SetVertexFormat( GLcontext *ctx, GLuint ind )
268 {
269 r200ContextPtr rmesa = R200_CONTEXT( ctx );
270 TNLcontext *tnl = TNL_CONTEXT(ctx);
271
272 rmesa->swtcl.SetupIndex = ind;
273
274 if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED)) {
275 tnl->Driver.Render.Interp = r200_interp_extras;
276 tnl->Driver.Render.CopyPV = r200_copy_pv_extras;
277 }
278 else {
279 tnl->Driver.Render.Interp = setup_tab[ind].interp;
280 tnl->Driver.Render.CopyPV = setup_tab[ind].copy_pv;
281 }
282
283 if (setup_tab[ind].vertex_format != rmesa->swtcl.vertex_format) {
284 int i;
285 R200_NEWPRIM(rmesa);
286 i = rmesa->swtcl.vertex_format = setup_tab[ind].vertex_format;
287 rmesa->swtcl.vertex_size = setup_tab[ind].vertex_size;
288
289 R200_STATECHANGE( rmesa, vtx );
290 rmesa->hw.vtx.cmd[VTX_VTXFMT_0] = se_vtx_fmt_0[i];
291 rmesa->hw.vtx.cmd[VTX_VTXFMT_1] = se_vtx_fmt_1[i];
292 }
293
294 {
295 GLuint vte = rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL];
296 GLuint vap = rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL];
297 GLuint needproj;
298
299 /* HW perspective divide is a win, but tiny vertex formats are a
300 * bigger one.
301 */
302 if (setup_tab[ind].vertex_format == TINY_VERTEX_FORMAT ||
303 (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) {
304 needproj = GL_TRUE;
305 vte |= R200_VTX_XY_FMT | R200_VTX_Z_FMT;
306 vte &= ~R200_VTX_W0_FMT;
307 vap |= R200_VAP_FORCE_W_TO_ONE;
308 }
309 else {
310 needproj = GL_FALSE;
311 vte &= ~(R200_VTX_XY_FMT | R200_VTX_Z_FMT);
312 vte |= R200_VTX_W0_FMT;
313 vap &= ~R200_VAP_FORCE_W_TO_ONE;
314 }
315
316 _tnl_need_projected_coords( ctx, needproj );
317 if (vte != rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL]) {
318 R200_STATECHANGE( rmesa, vte );
319 rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] = vte;
320 }
321 if (vap != rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL]) {
322 R200_STATECHANGE( rmesa, vap );
323 rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] = vap;
324 }
325 }
326 }
327
328 static void r200RenderStart( GLcontext *ctx )
329 {
330 r200ContextPtr rmesa = R200_CONTEXT( ctx );
331
332 if (!setup_tab[rmesa->swtcl.SetupIndex].check_tex_sizes(ctx)) {
333 r200SetVertexFormat( ctx, rmesa->swtcl.SetupIndex | R200_PTEX_BIT);
334 }
335
336 if (rmesa->dma.flush != 0 &&
337 rmesa->dma.flush != flush_last_swtcl_prim)
338 rmesa->dma.flush( rmesa );
339 }
340
341
342 void r200BuildVertices( GLcontext *ctx, GLuint start, GLuint count,
343 GLuint newinputs )
344 {
345 r200ContextPtr rmesa = R200_CONTEXT( ctx );
346 GLuint stride = rmesa->swtcl.vertex_size * sizeof(int);
347 GLubyte *v = ((GLubyte *)rmesa->swtcl.verts + (start * stride));
348
349 newinputs |= rmesa->swtcl.SetupNewInputs;
350 rmesa->swtcl.SetupNewInputs = 0;
351
352 if (!newinputs)
353 return;
354
355 setup_tab[rmesa->swtcl.SetupIndex].emit( ctx, start, count, v, stride );
356 }
357
358
359 void r200ChooseVertexState( GLcontext *ctx )
360 {
361 r200ContextPtr rmesa = R200_CONTEXT( ctx );
362 GLuint ind = (R200_XYZW_BIT | R200_RGBA_BIT);
363
364 if (!rmesa->TclFallback || rmesa->Fallback)
365 return;
366
367 if (ctx->Fog.Enabled || (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR))
368 ind |= R200_SPEC_BIT;
369
370 if (ctx->Texture._EnabledUnits & 0x2) /* unit 1 enabled */
371 ind |= R200_TEX0_BIT|R200_TEX1_BIT;
372 else if (ctx->Texture._EnabledUnits & 0x1) /* unit 1 enabled */
373 ind |= R200_TEX0_BIT;
374
375 r200SetVertexFormat( ctx, ind );
376 }
377
378
379 /* Flush vertices in the current dma region.
380 */
381 static void flush_last_swtcl_prim( r200ContextPtr rmesa )
382 {
383 if (R200_DEBUG & DEBUG_IOCTL)
384 fprintf(stderr, "%s\n", __FUNCTION__);
385
386 rmesa->dma.flush = 0;
387
388 if (rmesa->dma.current.buf) {
389 struct r200_dma_region *current = &rmesa->dma.current;
390 GLuint current_offset = (rmesa->r200Screen->gart_buffer_offset +
391 current->buf->buf->idx * RADEON_BUFFER_SIZE +
392 current->start);
393
394 assert (!(rmesa->swtcl.hw_primitive & R200_VF_PRIM_WALK_IND));
395
396 assert (current->start +
397 rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 ==
398 current->ptr);
399
400 if (rmesa->dma.current.start != rmesa->dma.current.ptr) {
401 r200EmitVertexAOS( rmesa,
402 rmesa->swtcl.vertex_size,
403 current_offset);
404
405 r200EmitVbufPrim( rmesa,
406 rmesa->swtcl.hw_primitive,
407 rmesa->swtcl.numverts);
408 }
409
410 rmesa->swtcl.numverts = 0;
411 current->start = current->ptr;
412 }
413 }
414
415
416 /* Alloc space in the current dma region.
417 */
418 static __inline void *r200AllocDmaLowVerts( r200ContextPtr rmesa,
419 int nverts, int vsize )
420 {
421 GLuint bytes = vsize * nverts;
422
423 if ( rmesa->dma.current.ptr + bytes > rmesa->dma.current.end )
424 r200RefillCurrentDmaRegion( rmesa );
425
426 if (!rmesa->dma.flush) {
427 rmesa->glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
428 rmesa->dma.flush = flush_last_swtcl_prim;
429 }
430
431 ASSERT( vsize == rmesa->swtcl.vertex_size * 4 );
432 ASSERT( rmesa->dma.flush == flush_last_swtcl_prim );
433 ASSERT( rmesa->dma.current.start +
434 rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 ==
435 rmesa->dma.current.ptr );
436
437
438 {
439 GLubyte *head = (GLubyte *) (rmesa->dma.current.address + rmesa->dma.current.ptr);
440 rmesa->dma.current.ptr += bytes;
441 rmesa->swtcl.numverts += nverts;
442 return head;
443 }
444
445 }
446
447
448
449
450 static void *r200_emit_contiguous_verts( GLcontext *ctx,
451 GLuint start,
452 GLuint count,
453 void *dest)
454 {
455 r200ContextPtr rmesa = R200_CONTEXT(ctx);
456 GLuint stride = rmesa->swtcl.vertex_size * 4;
457 setup_tab[rmesa->swtcl.SetupIndex].emit( ctx, start, count, dest, stride );
458 return (void *)((char *)dest + stride * (count - start));
459 }
460
461
462
463 void r200_emit_indexed_verts( GLcontext *ctx, GLuint start, GLuint count )
464 {
465 r200ContextPtr rmesa = R200_CONTEXT(ctx);
466
467 r200AllocDmaRegionVerts( rmesa,
468 &rmesa->swtcl.indexed_verts,
469 count - start,
470 rmesa->swtcl.vertex_size * 4,
471 64);
472
473 setup_tab[rmesa->swtcl.SetupIndex].emit(
474 ctx, start, count,
475 rmesa->swtcl.indexed_verts.address + rmesa->swtcl.indexed_verts.start,
476 rmesa->swtcl.vertex_size * 4 );
477 }
478
479
480 /*
481 * Render unclipped vertex buffers by emitting vertices directly to
482 * dma buffers. Use strip/fan hardware primitives where possible.
483 * Try to simulate missing primitives with indexed vertices.
484 */
485 #define HAVE_POINTS 1
486 #define HAVE_LINES 1
487 #define HAVE_LINE_STRIPS 1
488 #define HAVE_TRIANGLES 1
489 #define HAVE_TRI_STRIPS 1
490 #define HAVE_TRI_STRIP_1 0
491 #define HAVE_TRI_FANS 1
492 #define HAVE_QUADS 1
493 #define HAVE_QUAD_STRIPS 1
494 #define HAVE_POLYGONS 1
495 #define HAVE_ELTS 1
496
497 static const GLuint hw_prim[GL_POLYGON+1] = {
498 R200_VF_PRIM_POINTS,
499 R200_VF_PRIM_LINES,
500 0,
501 R200_VF_PRIM_LINE_STRIP,
502 R200_VF_PRIM_TRIANGLES,
503 R200_VF_PRIM_TRIANGLE_STRIP,
504 R200_VF_PRIM_TRIANGLE_FAN,
505 R200_VF_PRIM_QUADS,
506 R200_VF_PRIM_QUAD_STRIP,
507 R200_VF_PRIM_POLYGON
508 };
509
510 static __inline void r200DmaPrimitive( r200ContextPtr rmesa, GLenum prim )
511 {
512 R200_NEWPRIM( rmesa );
513 rmesa->swtcl.hw_primitive = hw_prim[prim];
514 assert(rmesa->dma.current.ptr == rmesa->dma.current.start);
515 }
516
517 static __inline void r200EltPrimitive( r200ContextPtr rmesa, GLenum prim )
518 {
519 R200_NEWPRIM( rmesa );
520 rmesa->swtcl.hw_primitive = hw_prim[prim] | R200_VF_PRIM_WALK_IND;
521 }
522
523
524
525
526 #define LOCAL_VARS r200ContextPtr rmesa = R200_CONTEXT(ctx)
527 #define ELTS_VARS(buf) GLushort *dest = buf
528 #define INIT( prim ) r200DmaPrimitive( rmesa, prim )
529 #define ELT_INIT(prim) r200EltPrimitive( rmesa, prim )
530 #define FLUSH() R200_NEWPRIM( rmesa )
531 #define GET_CURRENT_VB_MAX_VERTS() \
532 (((int)rmesa->dma.current.end - (int)rmesa->dma.current.ptr) / (rmesa->swtcl.vertex_size*4))
533 #define GET_SUBSEQUENT_VB_MAX_VERTS() \
534 ((RADEON_BUFFER_SIZE) / (rmesa->swtcl.vertex_size*4))
535
536 #define GET_CURRENT_VB_MAX_ELTS() \
537 ((R200_CMD_BUF_SZ - (rmesa->store.cmd_used + 16)) / 2)
538 #define GET_SUBSEQUENT_VB_MAX_ELTS() \
539 ((R200_CMD_BUF_SZ - 1024) / 2)
540
541 static void *r200_alloc_elts( r200ContextPtr rmesa, int nr )
542 {
543 if (rmesa->dma.flush == r200FlushElts &&
544 rmesa->store.cmd_used + nr*2 < R200_CMD_BUF_SZ) {
545
546 rmesa->store.cmd_used += nr*2;
547
548 return (void *)(rmesa->store.cmd_buf + rmesa->store.cmd_used);
549 }
550 else {
551 if (rmesa->dma.flush) {
552 rmesa->dma.flush( rmesa );
553 }
554
555 r200EmitVertexAOS( rmesa,
556 rmesa->swtcl.vertex_size,
557 (rmesa->r200Screen->gart_buffer_offset +
558 rmesa->swtcl.indexed_verts.buf->buf->idx *
559 RADEON_BUFFER_SIZE +
560 rmesa->swtcl.indexed_verts.start));
561
562 return (void *) r200AllocEltsOpenEnded( rmesa,
563 rmesa->swtcl.hw_primitive,
564 nr );
565 }
566 }
567
568 #define ALLOC_ELTS(nr) r200_alloc_elts(rmesa, nr)
569
570
571
572 #ifdef MESA_BIG_ENDIAN
573 /* We could do without (most of) this ugliness if dest was always 32 bit word aligned... */
574 #define EMIT_ELT(offset, x) do { \
575 int off = offset + ( ( (GLuint)dest & 0x2 ) >> 1 ); \
576 GLushort *des = (GLushort *)( (GLuint)dest & ~0x2 ); \
577 (des)[ off + 1 - 2 * ( off & 1 ) ] = (GLushort)(x); } while (0)
578 #else
579 #define EMIT_ELT(offset, x) (dest)[offset] = (GLushort) (x)
580 #endif
581 #define EMIT_TWO_ELTS(offset, x, y) *(GLuint *)(dest+offset) = ((y)<<16)|(x);
582 #define INCR_ELTS( nr ) dest += nr
583 #define ELTPTR dest
584 #define RELEASE_ELT_VERTS() \
585 r200ReleaseDmaRegion( rmesa, &rmesa->swtcl.indexed_verts, __FUNCTION__ )
586
587 #define EMIT_INDEXED_VERTS( ctx, start, count ) \
588 r200_emit_indexed_verts( ctx, start, count )
589
590
591 #define ALLOC_VERTS( nr ) \
592 r200AllocDmaLowVerts( rmesa, nr, rmesa->swtcl.vertex_size * 4 )
593 #define EMIT_VERTS( ctx, j, nr, buf ) \
594 r200_emit_contiguous_verts(ctx, j, (j)+(nr), buf)
595
596
597
598 #define TAG(x) r200_dma_##x
599 #include "tnl_dd/t_dd_dmatmp.h"
600
601
602 /**********************************************************************/
603 /* Render pipeline stage */
604 /**********************************************************************/
605
606
607
608 static GLboolean r200_run_render( GLcontext *ctx,
609 struct tnl_pipeline_stage *stage )
610 {
611 r200ContextPtr rmesa = R200_CONTEXT(ctx);
612 TNLcontext *tnl = TNL_CONTEXT(ctx);
613 struct vertex_buffer *VB = &tnl->vb;
614 GLuint i;
615 render_func *tab = TAG(render_tab_verts);
616
617 if (rmesa->swtcl.indexed_verts.buf && (!VB->Elts || stage->changed_inputs))
618 RELEASE_ELT_VERTS();
619
620
621
622 if ((R200_DEBUG & DEBUG_VERTS) ||
623 rmesa->swtcl.RenderIndex != 0 ||
624 !r200_dma_validate_render( ctx, VB ))
625 return GL_TRUE;
626
627 if (VB->Elts) {
628 tab = TAG(render_tab_elts);
629 if (!rmesa->swtcl.indexed_verts.buf) {
630 if (VB->Count > GET_SUBSEQUENT_VB_MAX_VERTS())
631 return GL_TRUE;
632 EMIT_INDEXED_VERTS(ctx, 0, VB->Count);
633 }
634 }
635
636 tnl->Driver.Render.Start( ctx );
637
638 for (i = 0 ; i < VB->PrimitiveCount ; i++)
639 {
640 GLuint prim = VB->Primitive[i].mode;
641 GLuint start = VB->Primitive[i].start;
642 GLuint length = VB->Primitive[i].count;
643
644 if (!length)
645 continue;
646
647 if (R200_DEBUG & DEBUG_PRIMS)
648 fprintf(stderr, "r200_render.c: prim %s %d..%d\n",
649 _mesa_lookup_enum_by_nr(prim & PRIM_MODE_MASK),
650 start, start+length);
651
652 tab[prim & PRIM_MODE_MASK]( ctx, start, start + length, prim );
653 }
654
655 tnl->Driver.Render.Finish( ctx );
656
657 return GL_FALSE; /* finished the pipe */
658 }
659
660
661
662 static void r200_check_render( GLcontext *ctx,
663 struct tnl_pipeline_stage *stage )
664 {
665 stage->inputs = TNL_CONTEXT(ctx)->render_inputs;
666 }
667
668
669 static void dtr( struct tnl_pipeline_stage *stage )
670 {
671 (void)stage;
672 }
673
674
675 const struct tnl_pipeline_stage _r200_render_stage =
676 {
677 "r200 render",
678 (_DD_NEW_SEPARATE_SPECULAR |
679 _NEW_TEXTURE|
680 _NEW_FOG|
681 _NEW_RENDERMODE), /* re-check (new inputs) */
682 0, /* re-run (always runs) */
683 GL_TRUE, /* active */
684 0, 0, /* inputs (set in check_render), outputs */
685 0, 0, /* changed_inputs, private */
686 dtr, /* destructor */
687 r200_check_render, /* check - initially set to alloc data */
688 r200_run_render /* run */
689 };
690
691
692
693 /**************************************************************************/
694
695
696 static const GLuint reduced_hw_prim[GL_POLYGON+1] = {
697 R200_VF_PRIM_POINTS,
698 R200_VF_PRIM_LINES,
699 R200_VF_PRIM_LINES,
700 R200_VF_PRIM_LINES,
701 R200_VF_PRIM_TRIANGLES,
702 R200_VF_PRIM_TRIANGLES,
703 R200_VF_PRIM_TRIANGLES,
704 R200_VF_PRIM_TRIANGLES,
705 R200_VF_PRIM_TRIANGLES,
706 R200_VF_PRIM_TRIANGLES
707 };
708
709 static void r200RasterPrimitive( GLcontext *ctx, GLuint hwprim );
710 static void r200RenderPrimitive( GLcontext *ctx, GLenum prim );
711 static void r200ResetLineStipple( GLcontext *ctx );
712
713 #undef HAVE_QUADS
714 #define HAVE_QUADS 0
715
716 #undef HAVE_QUAD_STRIPS
717 #define HAVE_QUAD_STRIPS 0
718
719 /***********************************************************************
720 * Emit primitives as inline vertices *
721 ***********************************************************************/
722
723 #undef LOCAL_VARS
724 #undef ALLOC_VERTS
725 #define CTX_ARG r200ContextPtr rmesa
726 #define CTX_ARG2 rmesa
727 #define GET_VERTEX_DWORDS() rmesa->swtcl.vertex_size
728 #define ALLOC_VERTS( n, size ) r200AllocDmaLowVerts( rmesa, n, size * 4 )
729 #define LOCAL_VARS \
730 r200ContextPtr rmesa = R200_CONTEXT(ctx); \
731 const char *r200verts = (char *)rmesa->swtcl.verts;
732 #define VERT(x) (r200Vertex *)(r200verts + ((x) * vertsize * sizeof(int)))
733 #define VERTEX r200Vertex
734 #define DO_DEBUG_VERTS (1 && (R200_DEBUG & DEBUG_VERTS))
735 #define PRINT_VERTEX(v) r200_print_vertex(rmesa->glCtx, v)
736 #undef TAG
737 #define TAG(x) r200_##x
738 #include "tnl_dd/t_dd_triemit.h"
739
740
741 /***********************************************************************
742 * Macros for t_dd_tritmp.h to draw basic primitives *
743 ***********************************************************************/
744
745 #define QUAD( a, b, c, d ) r200_quad( rmesa, a, b, c, d )
746 #define TRI( a, b, c ) r200_triangle( rmesa, a, b, c )
747 #define LINE( a, b ) r200_line( rmesa, a, b )
748 #define POINT( a ) r200_point( rmesa, a )
749
750 /***********************************************************************
751 * Build render functions from dd templates *
752 ***********************************************************************/
753
754 #define R200_TWOSIDE_BIT 0x01
755 #define R200_UNFILLED_BIT 0x02
756 #define R200_MAX_TRIFUNC 0x04
757
758
759 static struct {
760 points_func points;
761 line_func line;
762 triangle_func triangle;
763 quad_func quad;
764 } rast_tab[R200_MAX_TRIFUNC];
765
766
767 #define DO_FALLBACK 0
768 #define DO_UNFILLED (IND & R200_UNFILLED_BIT)
769 #define DO_TWOSIDE (IND & R200_TWOSIDE_BIT)
770 #define DO_FLAT 0
771 #define DO_OFFSET 0
772 #define DO_TRI 1
773 #define DO_QUAD 1
774 #define DO_LINE 1
775 #define DO_POINTS 1
776 #define DO_FULL_QUAD 1
777
778 #define HAVE_RGBA 1
779 #define HAVE_SPEC 1
780 #define HAVE_INDEX 0
781 #define HAVE_BACK_COLORS 0
782 #define HAVE_HW_FLATSHADE 1
783 #define TAB rast_tab
784
785 #define DEPTH_SCALE 1.0
786 #define UNFILLED_TRI unfilled_tri
787 #define UNFILLED_QUAD unfilled_quad
788 #define VERT_X(_v) _v->v.x
789 #define VERT_Y(_v) _v->v.y
790 #define VERT_Z(_v) _v->v.z
791 #define AREA_IS_CCW( a ) (a < 0)
792 #define GET_VERTEX(e) (rmesa->swtcl.verts + (e*rmesa->swtcl.vertex_size*sizeof(int)))
793
794 #define VERT_SET_RGBA( v, c ) \
795 do { \
796 r200_color_t *color = (r200_color_t *)&((v)->ui[coloroffset]); \
797 UNCLAMPED_FLOAT_TO_UBYTE(color->red, (c)[0]); \
798 UNCLAMPED_FLOAT_TO_UBYTE(color->green, (c)[1]); \
799 UNCLAMPED_FLOAT_TO_UBYTE(color->blue, (c)[2]); \
800 UNCLAMPED_FLOAT_TO_UBYTE(color->alpha, (c)[3]); \
801 } while (0)
802
803 #define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset]
804
805 #define VERT_SET_SPEC( v0, c ) \
806 do { \
807 if (havespec) { \
808 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.red, (c)[0]); \
809 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.green, (c)[1]); \
810 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.blue, (c)[2]); \
811 } \
812 } while (0)
813 #define VERT_COPY_SPEC( v0, v1 ) \
814 do { \
815 if (havespec) { \
816 v0->v.specular.red = v1->v.specular.red; \
817 v0->v.specular.green = v1->v.specular.green; \
818 v0->v.specular.blue = v1->v.specular.blue; \
819 } \
820 } while (0)
821
822 /* These don't need LE32_TO_CPU() as they used to save and restore
823 * colors which are already in the correct format.
824 */
825 #define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->ui[coloroffset]
826 #define VERT_RESTORE_RGBA( idx ) v[idx]->ui[coloroffset] = color[idx]
827 #define VERT_SAVE_SPEC( idx ) if (havespec) spec[idx] = v[idx]->ui[5]
828 #define VERT_RESTORE_SPEC( idx ) if (havespec) v[idx]->ui[5] = spec[idx]
829
830 #undef LOCAL_VARS
831 #undef TAG
832 #undef INIT
833
834 #define LOCAL_VARS(n) \
835 r200ContextPtr rmesa = R200_CONTEXT(ctx); \
836 GLuint color[n], spec[n]; \
837 GLuint coloroffset = (rmesa->swtcl.vertex_size == 4 ? 3 : 4); \
838 GLboolean havespec = (rmesa->swtcl.vertex_size > 4); \
839 (void) color; (void) spec; (void) coloroffset; (void) havespec;
840
841 /***********************************************************************
842 * Helpers for rendering unfilled primitives *
843 ***********************************************************************/
844
845 #define RASTERIZE(x) r200RasterPrimitive( ctx, reduced_hw_prim[x] )
846 #define RENDER_PRIMITIVE rmesa->swtcl.render_primitive
847 #undef TAG
848 #define TAG(x) x
849 #include "tnl_dd/t_dd_unfilled.h"
850 #undef IND
851
852
853 /***********************************************************************
854 * Generate GL render functions *
855 ***********************************************************************/
856
857
858 #define IND (0)
859 #define TAG(x) x
860 #include "tnl_dd/t_dd_tritmp.h"
861
862 #define IND (R200_TWOSIDE_BIT)
863 #define TAG(x) x##_twoside
864 #include "tnl_dd/t_dd_tritmp.h"
865
866 #define IND (R200_UNFILLED_BIT)
867 #define TAG(x) x##_unfilled
868 #include "tnl_dd/t_dd_tritmp.h"
869
870 #define IND (R200_TWOSIDE_BIT|R200_UNFILLED_BIT)
871 #define TAG(x) x##_twoside_unfilled
872 #include "tnl_dd/t_dd_tritmp.h"
873
874
875 static void init_rast_tab( void )
876 {
877 init();
878 init_twoside();
879 init_unfilled();
880 init_twoside_unfilled();
881 }
882
883 /**********************************************************************/
884 /* Render unclipped begin/end objects */
885 /**********************************************************************/
886
887 #define RENDER_POINTS( start, count ) \
888 for ( ; start < count ; start++) \
889 r200_point( rmesa, VERT(start) )
890 #define RENDER_LINE( v0, v1 ) \
891 r200_line( rmesa, VERT(v0), VERT(v1) )
892 #define RENDER_TRI( v0, v1, v2 ) \
893 r200_triangle( rmesa, VERT(v0), VERT(v1), VERT(v2) )
894 #define RENDER_QUAD( v0, v1, v2, v3 ) \
895 r200_quad( rmesa, VERT(v0), VERT(v1), VERT(v2), VERT(v3) )
896 #define INIT(x) do { \
897 r200RenderPrimitive( ctx, x ); \
898 } while (0)
899 #undef LOCAL_VARS
900 #define LOCAL_VARS \
901 r200ContextPtr rmesa = R200_CONTEXT(ctx); \
902 const GLuint vertsize = rmesa->swtcl.vertex_size; \
903 const char *r200verts = (char *)rmesa->swtcl.verts; \
904 const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \
905 const GLboolean stipple = ctx->Line.StippleFlag; \
906 (void) elt; (void) stipple;
907 #define RESET_STIPPLE if ( stipple ) r200ResetLineStipple( ctx );
908 #define RESET_OCCLUSION
909 #define PRESERVE_VB_DEFS
910 #define ELT(x) (x)
911 #define TAG(x) r200_##x##_verts
912 #include "tnl/t_vb_rendertmp.h"
913 #undef ELT
914 #undef TAG
915 #define TAG(x) r200_##x##_elts
916 #define ELT(x) elt[x]
917 #include "tnl/t_vb_rendertmp.h"
918
919
920
921 /**********************************************************************/
922 /* Choose render functions */
923 /**********************************************************************/
924
925 void r200ChooseRenderState( GLcontext *ctx )
926 {
927 TNLcontext *tnl = TNL_CONTEXT(ctx);
928 r200ContextPtr rmesa = R200_CONTEXT(ctx);
929 GLuint index = 0;
930 GLuint flags = ctx->_TriangleCaps;
931
932 if (!rmesa->TclFallback || rmesa->Fallback)
933 return;
934
935 if (flags & DD_TRI_LIGHT_TWOSIDE) index |= R200_TWOSIDE_BIT;
936 if (flags & DD_TRI_UNFILLED) index |= R200_UNFILLED_BIT;
937
938 if (index != rmesa->swtcl.RenderIndex) {
939 tnl->Driver.Render.Points = rast_tab[index].points;
940 tnl->Driver.Render.Line = rast_tab[index].line;
941 tnl->Driver.Render.ClippedLine = rast_tab[index].line;
942 tnl->Driver.Render.Triangle = rast_tab[index].triangle;
943 tnl->Driver.Render.Quad = rast_tab[index].quad;
944
945 if (index == 0) {
946 tnl->Driver.Render.PrimTabVerts = r200_render_tab_verts;
947 tnl->Driver.Render.PrimTabElts = r200_render_tab_elts;
948 tnl->Driver.Render.ClippedPolygon = r200_fast_clipped_poly;
949 } else {
950 tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
951 tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
952 tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon;
953 }
954
955 rmesa->swtcl.RenderIndex = index;
956 }
957 }
958
959
960 /**********************************************************************/
961 /* High level hooks for t_vb_render.c */
962 /**********************************************************************/
963
964
965 static void r200RasterPrimitive( GLcontext *ctx, GLuint hwprim )
966 {
967 r200ContextPtr rmesa = R200_CONTEXT(ctx);
968
969 if (rmesa->swtcl.hw_primitive != hwprim) {
970 R200_NEWPRIM( rmesa );
971 rmesa->swtcl.hw_primitive = hwprim;
972 }
973 }
974
975 static void r200RenderPrimitive( GLcontext *ctx, GLenum prim )
976 {
977 r200ContextPtr rmesa = R200_CONTEXT(ctx);
978 rmesa->swtcl.render_primitive = prim;
979 if (prim < GL_TRIANGLES || !(ctx->_TriangleCaps & DD_TRI_UNFILLED))
980 r200RasterPrimitive( ctx, reduced_hw_prim[prim] );
981 }
982
983 static void r200RenderFinish( GLcontext *ctx )
984 {
985 }
986
987 static void r200ResetLineStipple( GLcontext *ctx )
988 {
989 r200ContextPtr rmesa = R200_CONTEXT(ctx);
990 R200_STATECHANGE( rmesa, lin );
991 }
992
993
994 /**********************************************************************/
995 /* Transition to/from hardware rasterization. */
996 /**********************************************************************/
997
998 static const char * const fallbackStrings[] = {
999 "Texture mode",
1000 "glDrawBuffer(GL_FRONT_AND_BACK)",
1001 "glEnable(GL_STENCIL) without hw stencil buffer",
1002 "glRenderMode(selection or feedback)",
1003 "glBlendEquation",
1004 "glBlendFunc(mode != ADD)",
1005 "R200_NO_RAST",
1006 "Mixing GL_CLAMP_TO_BORDER and GL_CLAMP (or GL_MIRROR_CLAMP_ATI)"
1007 };
1008
1009
1010 static const char *getFallbackString(GLuint bit)
1011 {
1012 int i = 0;
1013 while (bit > 1) {
1014 i++;
1015 bit >>= 1;
1016 }
1017 return fallbackStrings[i];
1018 }
1019
1020
1021 void r200Fallback( GLcontext *ctx, GLuint bit, GLboolean mode )
1022 {
1023 r200ContextPtr rmesa = R200_CONTEXT(ctx);
1024 TNLcontext *tnl = TNL_CONTEXT(ctx);
1025 GLuint oldfallback = rmesa->Fallback;
1026
1027 if (mode) {
1028 rmesa->Fallback |= bit;
1029 if (oldfallback == 0) {
1030 R200_FIREVERTICES( rmesa );
1031 TCL_FALLBACK( ctx, R200_TCL_FALLBACK_RASTER, GL_TRUE );
1032 _swsetup_Wakeup( ctx );
1033 _tnl_need_projected_coords( ctx, GL_TRUE );
1034 rmesa->swtcl.RenderIndex = ~0;
1035 if (R200_DEBUG & DEBUG_FALLBACKS) {
1036 fprintf(stderr, "R200 begin rasterization fallback: 0x%x %s\n",
1037 bit, getFallbackString(bit));
1038 }
1039 }
1040 }
1041 else {
1042 rmesa->Fallback &= ~bit;
1043 if (oldfallback == bit) {
1044 _swrast_flush( ctx );
1045 tnl->Driver.Render.Start = r200RenderStart;
1046 tnl->Driver.Render.PrimitiveNotify = r200RenderPrimitive;
1047 tnl->Driver.Render.Finish = r200RenderFinish;
1048 tnl->Driver.Render.BuildVertices = r200BuildVertices;
1049 tnl->Driver.Render.ResetLineStipple = r200ResetLineStipple;
1050 TCL_FALLBACK( ctx, R200_TCL_FALLBACK_RASTER, GL_FALSE );
1051 if (rmesa->TclFallback) {
1052 /* These are already done if rmesa->TclFallback goes to
1053 * zero above. But not if it doesn't (R200_NO_TCL for
1054 * example?)
1055 */
1056 r200ChooseVertexState( ctx );
1057 r200ChooseRenderState( ctx );
1058 }
1059 if (R200_DEBUG & DEBUG_FALLBACKS) {
1060 fprintf(stderr, "R200 end rasterization fallback: 0x%x %s\n",
1061 bit, getFallbackString(bit));
1062 }
1063 }
1064 }
1065 }
1066
1067
1068
1069
1070 /* Cope with depth operations by drawing individual pixels as points???
1071 */
1072 void
1073 r200PointsBitmap( GLcontext *ctx, GLint px, GLint py,
1074 GLsizei width, GLsizei height,
1075 const struct gl_pixelstore_attrib *unpack,
1076 const GLubyte *bitmap )
1077 {
1078 r200ContextPtr rmesa = R200_CONTEXT(ctx);
1079 const GLfloat *rc = ctx->Current.RasterColor;
1080 GLint row, col;
1081 r200Vertex vert;
1082 GLuint orig_vte;
1083 GLuint h;
1084
1085
1086 /* Turn off tcl.
1087 */
1088 TCL_FALLBACK( ctx, R200_TCL_FALLBACK_BITMAP, 1 );
1089
1090 /* Choose tiny vertex format
1091 */
1092 r200SetVertexFormat( ctx, R200_XYZW_BIT | R200_RGBA_BIT );
1093
1094 /* Ready for point primitives:
1095 */
1096 r200RenderPrimitive( ctx, GL_POINTS );
1097
1098 /* Turn off the hw viewport transformation:
1099 */
1100 R200_STATECHANGE( rmesa, vte );
1101 orig_vte = rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL];
1102 rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] &= ~(R200_VPORT_X_SCALE_ENA |
1103 R200_VPORT_Y_SCALE_ENA |
1104 R200_VPORT_Z_SCALE_ENA |
1105 R200_VPORT_X_OFFSET_ENA |
1106 R200_VPORT_Y_OFFSET_ENA |
1107 R200_VPORT_Z_OFFSET_ENA);
1108
1109 /* Turn off other stuff: Stipple?, texture?, blending?, etc.
1110 */
1111
1112
1113 /* Populate the vertex
1114 *
1115 * Incorporate FOG into RGBA
1116 */
1117 if (ctx->Fog.Enabled) {
1118 const GLfloat *fc = ctx->Fog.Color;
1119 GLfloat color[4];
1120 GLfloat f;
1121
1122 if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT)
1123 f = _swrast_z_to_fogfactor(ctx, ctx->Current.Attrib[VERT_ATTRIB_FOG][0]);
1124 else
1125 f = _swrast_z_to_fogfactor(ctx, ctx->Current.RasterDistance);
1126
1127 color[0] = f * rc[0] + (1.F - f) * fc[0];
1128 color[1] = f * rc[1] + (1.F - f) * fc[1];
1129 color[2] = f * rc[2] + (1.F - f) * fc[2];
1130 color[3] = rc[3];
1131
1132 UNCLAMPED_FLOAT_TO_CHAN(vert.tv.color.red, color[0]);
1133 UNCLAMPED_FLOAT_TO_CHAN(vert.tv.color.green, color[1]);
1134 UNCLAMPED_FLOAT_TO_CHAN(vert.tv.color.blue, color[2]);
1135 UNCLAMPED_FLOAT_TO_CHAN(vert.tv.color.alpha, color[3]);
1136 }
1137 else {
1138 UNCLAMPED_FLOAT_TO_CHAN(vert.tv.color.red, rc[0]);
1139 UNCLAMPED_FLOAT_TO_CHAN(vert.tv.color.green, rc[1]);
1140 UNCLAMPED_FLOAT_TO_CHAN(vert.tv.color.blue, rc[2]);
1141 UNCLAMPED_FLOAT_TO_CHAN(vert.tv.color.alpha, rc[3]);
1142 }
1143
1144
1145 vert.tv.z = ctx->Current.RasterPos[2];
1146
1147
1148 /* Update window height
1149 */
1150 LOCK_HARDWARE( rmesa );
1151 UNLOCK_HARDWARE( rmesa );
1152 h = rmesa->dri.drawable->h + rmesa->dri.drawable->y;
1153 px += rmesa->dri.drawable->x;
1154
1155 /* Clipping handled by existing mechansims in r200_ioctl.c?
1156 */
1157 for (row=0; row<height; row++) {
1158 const GLubyte *src = (const GLubyte *)
1159 _mesa_image_address( unpack, bitmap, width, height,
1160 GL_COLOR_INDEX, GL_BITMAP, 0, row, 0 );
1161
1162 if (unpack->LsbFirst) {
1163 /* Lsb first */
1164 GLubyte mask = 1U << (unpack->SkipPixels & 0x7);
1165 for (col=0; col<width; col++) {
1166 if (*src & mask) {
1167 vert.tv.x = px+col;
1168 vert.tv.y = h - (py+row) - 1;
1169 r200_point( rmesa, &vert );
1170 }
1171 src += (mask >> 7);
1172 mask = ((mask << 1) & 0xff) | (mask >> 7);
1173 }
1174
1175 /* get ready for next row */
1176 if (mask != 1)
1177 src++;
1178 }
1179 else {
1180 /* Msb first */
1181 GLubyte mask = 128U >> (unpack->SkipPixels & 0x7);
1182 for (col=0; col<width; col++) {
1183 if (*src & mask) {
1184 vert.tv.x = px+col;
1185 vert.tv.y = h - (py+row) - 1;
1186 r200_point( rmesa, &vert );
1187 }
1188 src += mask & 1;
1189 mask = ((mask << 7) & 0xff) | (mask >> 1);
1190 }
1191 /* get ready for next row */
1192 if (mask != 128)
1193 src++;
1194 }
1195 }
1196
1197 /* Fire outstanding vertices, restore state
1198 */
1199 R200_STATECHANGE( rmesa, vte );
1200 rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] = orig_vte;
1201
1202 /* Unfallback
1203 */
1204 TCL_FALLBACK( ctx, R200_TCL_FALLBACK_BITMAP, 0 );
1205
1206 /* Need to restore vertexformat?
1207 */
1208 if (rmesa->TclFallback)
1209 r200ChooseVertexState( ctx );
1210 }
1211
1212
1213 void r200FlushVertices( GLcontext *ctx, GLuint flags )
1214 {
1215 _tnl_FlushVertices( ctx, flags );
1216
1217 if (flags & FLUSH_STORED_VERTICES)
1218 R200_NEWPRIM( R200_CONTEXT( ctx ) );
1219 }
1220
1221 /**********************************************************************/
1222 /* Initialization. */
1223 /**********************************************************************/
1224
1225 void r200InitSwtcl( GLcontext *ctx )
1226 {
1227 TNLcontext *tnl = TNL_CONTEXT(ctx);
1228 r200ContextPtr rmesa = R200_CONTEXT(ctx);
1229 GLuint size = tnl->vb.Size;
1230 static int firsttime = 1;
1231
1232 if (firsttime) {
1233 init_rast_tab();
1234 init_setup_tab();
1235 firsttime = 0;
1236 }
1237
1238 tnl->Driver.Render.Start = r200RenderStart;
1239 tnl->Driver.Render.Finish = r200RenderFinish;
1240 tnl->Driver.Render.PrimitiveNotify = r200RenderPrimitive;
1241 tnl->Driver.Render.ResetLineStipple = r200ResetLineStipple;
1242 tnl->Driver.Render.BuildVertices = r200BuildVertices;
1243
1244 rmesa->swtcl.verts = (GLubyte *)ALIGN_MALLOC( size * 16 * 4, 32 );
1245 rmesa->swtcl.RenderIndex = ~0;
1246 rmesa->swtcl.render_primitive = GL_TRIANGLES;
1247 rmesa->swtcl.hw_primitive = 0;
1248 }
1249
1250
1251 void r200DestroySwtcl( GLcontext *ctx )
1252 {
1253 r200ContextPtr rmesa = R200_CONTEXT(ctx);
1254
1255 if (rmesa->swtcl.indexed_verts.buf)
1256 r200ReleaseDmaRegion( rmesa, &rmesa->swtcl.indexed_verts, __FUNCTION__ );
1257
1258 if (rmesa->swtcl.verts) {
1259 ALIGN_FREE(rmesa->swtcl.verts);
1260 rmesa->swtcl.verts = 0;
1261 }
1262 }