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