1 /* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_vb.c,v 1.16 2003/03/26 20:43:49 tsi Exp $ */
2 /**************************************************************************
4 Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
5 VA Linux Systems Inc., Fremont, California.
9 Permission is hereby granted, free of charge, to any person obtaining a
10 copy of this software and associated documentation files (the "Software"),
11 to deal in the Software without restriction, including without limitation
12 on the rights to use, copy, modify, merge, publish, distribute, sub
13 license, and/or sell copies of the Software, and to permit persons to whom
14 the Software is furnished to do so, subject to the following conditions:
16 The above copyright notice and this permission notice (including the next
17 paragraph) shall be included in all copies or substantial portions of the
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
23 ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
24 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
25 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
26 USE OR OTHER DEALINGS IN THE SOFTWARE.
28 **************************************************************************/
32 * Keith Whitwell <keith@tungstengraphics.com>
42 #include "swrast_setup/swrast_setup.h"
43 #include "tnl/t_context.h"
45 #include "r128_context.h"
47 #include "r128_ioctl.h"
48 #include "r128_tris.h"
49 #include "r128_state.h"
52 #define R128_TEX1_BIT 0x1
53 #define R128_TEX0_BIT 0x2
54 #define R128_RGBA_BIT 0x4
55 #define R128_SPEC_BIT 0x8
56 #define R128_FOG_BIT 0x10
57 #define R128_XYZW_BIT 0x20
58 #define R128_PTEX_BIT 0x40
59 #define R128_MAX_SETUP 0x80
62 void (*emit
)( GLcontext
*, GLuint
, GLuint
, void *, GLuint
);
65 GLboolean (*check_tex_sizes
)( GLcontext
*ctx
);
67 GLuint vertex_stride_shift
;
69 } setup_tab
[R128_MAX_SETUP
];
71 #define TINY_VERTEX_FORMAT (R128_CCE_VC_FRMT_DIFFUSE_ARGB)
73 #define NOTEX_VERTEX_FORMAT (R128_CCE_VC_FRMT_RHW | \
74 R128_CCE_VC_FRMT_DIFFUSE_ARGB |\
75 R128_CCE_VC_FRMT_SPEC_FRGB)
77 #define TEX0_VERTEX_FORMAT (R128_CCE_VC_FRMT_RHW | \
78 R128_CCE_VC_FRMT_DIFFUSE_ARGB |\
79 R128_CCE_VC_FRMT_SPEC_FRGB | \
82 #define TEX1_VERTEX_FORMAT (R128_CCE_VC_FRMT_RHW | \
83 R128_CCE_VC_FRMT_DIFFUSE_ARGB |\
84 R128_CCE_VC_FRMT_SPEC_FRGB | \
85 R128_CCE_VC_FRMT_S_T | \
86 R128_CCE_VC_FRMT_S2_T2)
89 #define PROJ_TEX1_VERTEX_FORMAT 0
90 #define TEX2_VERTEX_FORMAT 0
91 #define TEX3_VERTEX_FORMAT 0
92 #define PROJ_TEX3_VERTEX_FORMAT 0
94 #define DO_XYZW (IND & R128_XYZW_BIT)
95 #define DO_RGBA (IND & R128_RGBA_BIT)
96 #define DO_SPEC (IND & R128_SPEC_BIT)
97 #define DO_FOG (IND & R128_FOG_BIT)
98 #define DO_TEX0 (IND & R128_TEX0_BIT)
99 #define DO_TEX1 (IND & R128_TEX1_BIT)
102 #define DO_PTEX (IND & R128_PTEX_BIT)
104 #define VERTEX r128Vertex
105 #define VERTEX_COLOR r128_color_t
106 #define LOCALVARS r128ContextPtr rmesa = R128_CONTEXT(ctx);
107 #define GET_VIEWPORT_MAT() rmesa->hw_viewport
108 #define GET_TEXSOURCE(n) rmesa->tmu_source[n]
109 #define GET_VERTEX_FORMAT() rmesa->vertex_format
110 #define GET_VERTEX_STORE() rmesa->verts
111 #define GET_VERTEX_STRIDE_SHIFT() rmesa->vertex_stride_shift
112 #define INVALIDATE_STORED_VERTICES()
113 #define GET_UBYTE_COLOR_STORE() &rmesa->UbyteColor
114 #define GET_UBYTE_SPEC_COLOR_STORE() &rmesa->UbyteSecondaryColor
116 #define HAVE_HW_VIEWPORT 0
117 #define HAVE_HW_DIVIDE 0
118 #define HAVE_RGBA_COLOR 0
119 #define HAVE_TINY_VERTICES 1
120 #define HAVE_NOTEX_VERTICES 1
121 #define HAVE_TEX0_VERTICES 1
122 #define HAVE_TEX1_VERTICES 1
123 #define HAVE_TEX2_VERTICES 0
124 #define HAVE_TEX3_VERTICES 0
125 #define HAVE_PTEX_VERTICES 0 /* r128 rhw2 not supported by template */
127 #define UNVIEWPORT_VARS GLfloat h = R128_CONTEXT(ctx)->driDrawable->h
128 #define UNVIEWPORT_X(x) x - SUBPIXEL_X
129 #define UNVIEWPORT_Y(y) - y + h + SUBPIXEL_Y
130 #define UNVIEWPORT_Z(z) z / rmesa->depth_scale
132 #define PTEX_FALLBACK() FALLBACK(R128_CONTEXT(ctx), R128_FALLBACK_TEXTURE, 1)
134 #define IMPORT_FLOAT_COLORS r128_import_float_colors
135 #define IMPORT_FLOAT_SPEC_COLORS r128_import_float_spec_colors
137 #define INTERP_VERTEX setup_tab[rmesa->SetupIndex].interp
138 #define COPY_PV_VERTEX setup_tab[rmesa->SetupIndex].copy_pv
140 /***********************************************************************
141 * Generate pv-copying and translation functions *
142 ***********************************************************************/
144 #define TAG(x) r128_##x
145 #include "tnl_dd/t_dd_vb.c"
147 /***********************************************************************
148 * Generate vertex emit and interp functions *
149 ***********************************************************************/
152 #define IND (R128_XYZW_BIT|R128_RGBA_BIT)
153 #define TAG(x) x##_wg
154 #include "tnl_dd/t_dd_vbtmp.h"
156 #define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_SPEC_BIT)
157 #define TAG(x) x##_wgs
158 #include "tnl_dd/t_dd_vbtmp.h"
160 #define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_TEX0_BIT)
161 #define TAG(x) x##_wgt0
162 #include "tnl_dd/t_dd_vbtmp.h"
164 #define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_TEX0_BIT|R128_TEX1_BIT)
165 #define TAG(x) x##_wgt0t1
166 #include "tnl_dd/t_dd_vbtmp.h"
168 #define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_TEX0_BIT|R128_PTEX_BIT)
169 #define TAG(x) x##_wgpt0
170 #include "tnl_dd/t_dd_vbtmp.h"
172 #define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX0_BIT)
173 #define TAG(x) x##_wgst0
174 #include "tnl_dd/t_dd_vbtmp.h"
176 #define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX0_BIT|\
178 #define TAG(x) x##_wgst0t1
179 #include "tnl_dd/t_dd_vbtmp.h"
181 #define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX0_BIT|\
183 #define TAG(x) x##_wgspt0
184 #include "tnl_dd/t_dd_vbtmp.h"
186 #define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_FOG_BIT)
187 #define TAG(x) x##_wgf
188 #include "tnl_dd/t_dd_vbtmp.h"
190 #define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT)
191 #define TAG(x) x##_wgfs
192 #include "tnl_dd/t_dd_vbtmp.h"
194 #define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_TEX0_BIT)
195 #define TAG(x) x##_wgft0
196 #include "tnl_dd/t_dd_vbtmp.h"
198 #define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_TEX0_BIT|\
200 #define TAG(x) x##_wgft0t1
201 #include "tnl_dd/t_dd_vbtmp.h"
203 #define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_TEX0_BIT|\
205 #define TAG(x) x##_wgfpt0
206 #include "tnl_dd/t_dd_vbtmp.h"
208 #define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|\
210 #define TAG(x) x##_wgfst0
211 #include "tnl_dd/t_dd_vbtmp.h"
213 #define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|\
214 R128_TEX0_BIT|R128_TEX1_BIT)
215 #define TAG(x) x##_wgfst0t1
216 #include "tnl_dd/t_dd_vbtmp.h"
218 #define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|\
219 R128_TEX0_BIT|R128_PTEX_BIT)
220 #define TAG(x) x##_wgfspt0
221 #include "tnl_dd/t_dd_vbtmp.h"
223 #define IND (R128_TEX0_BIT)
224 #define TAG(x) x##_t0
225 #include "tnl_dd/t_dd_vbtmp.h"
227 #define IND (R128_TEX0_BIT|R128_TEX1_BIT)
228 #define TAG(x) x##_t0t1
229 #include "tnl_dd/t_dd_vbtmp.h"
231 #define IND (R128_FOG_BIT)
233 #include "tnl_dd/t_dd_vbtmp.h"
235 #define IND (R128_FOG_BIT|R128_TEX0_BIT)
236 #define TAG(x) x##_ft0
237 #include "tnl_dd/t_dd_vbtmp.h"
239 #define IND (R128_FOG_BIT|R128_TEX0_BIT|R128_TEX1_BIT)
240 #define TAG(x) x##_ft0t1
241 #include "tnl_dd/t_dd_vbtmp.h"
243 #define IND (R128_RGBA_BIT)
245 #include "tnl_dd/t_dd_vbtmp.h"
247 #define IND (R128_RGBA_BIT|R128_SPEC_BIT)
248 #define TAG(x) x##_gs
249 #include "tnl_dd/t_dd_vbtmp.h"
251 #define IND (R128_RGBA_BIT|R128_TEX0_BIT)
252 #define TAG(x) x##_gt0
253 #include "tnl_dd/t_dd_vbtmp.h"
255 #define IND (R128_RGBA_BIT|R128_TEX0_BIT|R128_TEX1_BIT)
256 #define TAG(x) x##_gt0t1
257 #include "tnl_dd/t_dd_vbtmp.h"
259 #define IND (R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX0_BIT)
260 #define TAG(x) x##_gst0
261 #include "tnl_dd/t_dd_vbtmp.h"
263 #define IND (R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX0_BIT|R128_TEX1_BIT)
264 #define TAG(x) x##_gst0t1
265 #include "tnl_dd/t_dd_vbtmp.h"
267 #define IND (R128_RGBA_BIT|R128_FOG_BIT)
268 #define TAG(x) x##_gf
269 #include "tnl_dd/t_dd_vbtmp.h"
271 #define IND (R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT)
272 #define TAG(x) x##_gfs
273 #include "tnl_dd/t_dd_vbtmp.h"
275 #define IND (R128_RGBA_BIT|R128_FOG_BIT|R128_TEX0_BIT)
276 #define TAG(x) x##_gft0
277 #include "tnl_dd/t_dd_vbtmp.h"
279 #define IND (R128_RGBA_BIT|R128_FOG_BIT|R128_TEX0_BIT|R128_TEX1_BIT)
280 #define TAG(x) x##_gft0t1
281 #include "tnl_dd/t_dd_vbtmp.h"
283 #define IND (R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|R128_TEX0_BIT)
284 #define TAG(x) x##_gfst0
285 #include "tnl_dd/t_dd_vbtmp.h"
287 #define IND (R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|R128_TEX0_BIT|\
289 #define TAG(x) x##_gfst0t1
290 #include "tnl_dd/t_dd_vbtmp.h"
293 static void init_setup_tab( void )
332 void r128PrintSetupFlags(char *msg
, GLuint flags
)
334 fprintf(stderr
, "%s(%x): %s%s%s%s%s%s\n",
337 (flags
& R128_XYZW_BIT
) ? " xyzw," : "",
338 (flags
& R128_RGBA_BIT
) ? " rgba," : "",
339 (flags
& R128_SPEC_BIT
) ? " spec," : "",
340 (flags
& R128_FOG_BIT
) ? " fog," : "",
341 (flags
& R128_TEX0_BIT
) ? " tex-0," : "",
342 (flags
& R128_TEX1_BIT
) ? " tex-1," : "");
347 void r128CheckTexSizes( GLcontext
*ctx
)
349 r128ContextPtr rmesa
= R128_CONTEXT( ctx
);
351 if (!setup_tab
[rmesa
->SetupIndex
].check_tex_sizes(ctx
)) {
352 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
354 /* Invalidate stored verts
356 rmesa
->SetupNewInputs
= ~0;
357 rmesa
->SetupIndex
|= R128_PTEX_BIT
;
359 if (!rmesa
->Fallback
&&
360 !(ctx
->_TriangleCaps
& (DD_TRI_LIGHT_TWOSIDE
|DD_TRI_UNFILLED
))) {
361 tnl
->Driver
.Render
.Interp
= setup_tab
[rmesa
->SetupIndex
].interp
;
362 tnl
->Driver
.Render
.CopyPV
= setup_tab
[rmesa
->SetupIndex
].copy_pv
;
364 if (rmesa
->Fallback
) {
365 tnl
->Driver
.Render
.Start(ctx
);
370 void r128BuildVertices( GLcontext
*ctx
,
375 r128ContextPtr rmesa
= R128_CONTEXT( ctx
);
376 GLubyte
*v
= ((GLubyte
*)rmesa
->verts
+ (start
<<rmesa
->vertex_stride_shift
));
377 GLuint stride
= 1<<rmesa
->vertex_stride_shift
;
379 newinputs
|= rmesa
->SetupNewInputs
;
380 rmesa
->SetupNewInputs
= 0;
385 if (newinputs
& VERT_BIT_POS
) {
386 setup_tab
[rmesa
->SetupIndex
].emit( ctx
, start
, count
, v
, stride
);
390 if (newinputs
& VERT_BIT_COLOR0
)
391 ind
|= R128_RGBA_BIT
;
393 if (newinputs
& VERT_BIT_COLOR1
)
394 ind
|= R128_SPEC_BIT
;
396 if (newinputs
& VERT_BIT_TEX0
)
397 ind
|= R128_TEX0_BIT
;
399 if (newinputs
& VERT_BIT_TEX1
)
400 ind
|= R128_TEX1_BIT
;
402 if (newinputs
& VERT_BIT_FOG
)
405 if (rmesa
->SetupIndex
& R128_PTEX_BIT
)
408 ind
&= rmesa
->SetupIndex
;
411 setup_tab
[ind
].emit( ctx
, start
, count
, v
, stride
);
416 void r128ChooseVertexState( GLcontext
*ctx
)
418 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
419 r128ContextPtr rmesa
= R128_CONTEXT( ctx
);
420 GLuint ind
= R128_XYZW_BIT
|R128_RGBA_BIT
;
422 if (ctx
->_TriangleCaps
& DD_SEPARATE_SPECULAR
)
423 ind
|= R128_SPEC_BIT
;
425 if (ctx
->Fog
.Enabled
)
428 if (ctx
->Texture
._EnabledUnits
) {
429 ind
|= R128_TEX0_BIT
;
430 if (ctx
->Texture
.Unit
[0]._ReallyEnabled
&&
431 ctx
->Texture
.Unit
[1]._ReallyEnabled
)
432 ind
|= R128_TEX1_BIT
;
435 rmesa
->SetupIndex
= ind
;
437 if (ctx
->_TriangleCaps
& (DD_TRI_LIGHT_TWOSIDE
|DD_TRI_UNFILLED
)) {
438 tnl
->Driver
.Render
.Interp
= r128_interp_extras
;
439 tnl
->Driver
.Render
.CopyPV
= r128_copy_pv_extras
;
441 tnl
->Driver
.Render
.Interp
= setup_tab
[ind
].interp
;
442 tnl
->Driver
.Render
.CopyPV
= setup_tab
[ind
].copy_pv
;
445 if (setup_tab
[ind
].vertex_format
!= rmesa
->vertex_format
) {
447 rmesa
->vertex_format
= setup_tab
[ind
].vertex_format
;
448 rmesa
->vertex_size
= setup_tab
[ind
].vertex_size
;
449 rmesa
->vertex_stride_shift
= setup_tab
[ind
].vertex_stride_shift
;
455 void r128_emit_contiguous_verts( GLcontext
*ctx
,
459 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
460 GLuint vertex_size
= rmesa
->vertex_size
* 4;
461 GLuint
*dest
= r128AllocDmaLow( rmesa
, (count
-start
) * vertex_size
);
462 setup_tab
[rmesa
->SetupIndex
].emit( ctx
, start
, count
, dest
, vertex_size
);
467 void r128_emit_indexed_verts( GLcontext
*ctx
, GLuint start
, GLuint count
)
469 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
470 GLuint vertex_size
= rmesa
->vertex_size
* 4;
471 GLuint bufsz
= (count
-start
) * vertex_size
;
474 rmesa
->vertex_low
= (rmesa
->vertex_low
+ 63) & ~63; /* alignment */
475 rmesa
->vertex_last_prim
= rmesa
->vertex_low
;
477 dest
= r128AllocDmaLow( rmesa
, bufsz
, __FUNCTION__
);
478 setup_tab
[rmesa
->SetupIndex
].emit( ctx
, start
, count
, dest
, vertex_size
);
480 rmesa
->retained_buffer
= rmesa
->vertex_buffer
;
481 rmesa
->vb_offset
= (rmesa
->vertex_buffer
->idx
* R128_BUFFER_SIZE
+
482 rmesa
->vertex_low
- bufsz
);
484 rmesa
->vertex_low
= (rmesa
->vertex_low
+ 0x7) & ~0x7; /* alignment */
485 rmesa
->vertex_last_prim
= rmesa
->vertex_low
;
490 void r128InitVB( GLcontext
*ctx
)
492 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
493 GLuint size
= TNL_CONTEXT(ctx
)->vb
.Size
;
495 rmesa
->verts
= (GLubyte
*)ALIGN_MALLOC(size
* 4 * 16, 32);
498 static int firsttime
= 1;
507 void r128FreeVB( GLcontext
*ctx
)
509 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
511 ALIGN_FREE(rmesa
->verts
);
516 if (rmesa
->UbyteSecondaryColor
.Ptr
) {
517 ALIGN_FREE(rmesa
->UbyteSecondaryColor
.Ptr
);
518 rmesa
->UbyteSecondaryColor
.Ptr
= 0;
521 if (rmesa
->UbyteColor
.Ptr
) {
522 ALIGN_FREE(rmesa
->UbyteColor
.Ptr
);
523 rmesa
->UbyteColor
.Ptr
= 0;