Import vtx-0-2-branch
[mesa.git] / src / mesa / drivers / dri / r128 / r128_vb.c
1 /* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_vb.c,v 1.16 2003/03/26 20:43:49 tsi Exp $ */
2 /**************************************************************************
3
4 Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
5 VA Linux Systems Inc., Fremont, California.
6
7 All Rights Reserved.
8
9 Permission is hereby granted, free of charge, to any person obtaining 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:
15
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
18 Software.
19
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.
27
28 **************************************************************************/
29
30 /*
31 * Authors:
32 * Keith Whitwell <keith@tungstengraphics.com>
33 *
34 */
35
36 #include "glheader.h"
37 #include "mtypes.h"
38 #include "imports.h"
39 #include "macros.h"
40 #include "colormac.h"
41
42 #include "swrast_setup/swrast_setup.h"
43 #include "tnl/t_context.h"
44
45 #include "r128_context.h"
46 #include "r128_vb.h"
47 #include "r128_ioctl.h"
48 #include "r128_tris.h"
49 #include "r128_state.h"
50
51
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
60
61 static struct {
62 void (*emit)( GLcontext *, GLuint, GLuint, void *, GLuint );
63 interp_func interp;
64 copy_pv_func copy_pv;
65 GLboolean (*check_tex_sizes)( GLcontext *ctx );
66 GLuint vertex_size;
67 GLuint vertex_stride_shift;
68 GLuint vertex_format;
69 } setup_tab[R128_MAX_SETUP];
70
71 #define TINY_VERTEX_FORMAT (R128_CCE_VC_FRMT_DIFFUSE_ARGB)
72
73 #define NOTEX_VERTEX_FORMAT (R128_CCE_VC_FRMT_RHW | \
74 R128_CCE_VC_FRMT_DIFFUSE_ARGB |\
75 R128_CCE_VC_FRMT_SPEC_FRGB)
76
77 #define TEX0_VERTEX_FORMAT (R128_CCE_VC_FRMT_RHW | \
78 R128_CCE_VC_FRMT_DIFFUSE_ARGB |\
79 R128_CCE_VC_FRMT_SPEC_FRGB | \
80 R128_CCE_VC_FRMT_S_T)
81
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)
87
88
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
93
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)
100 #define DO_TEX2 0
101 #define DO_TEX3 0
102 #define DO_PTEX (IND & R128_PTEX_BIT)
103
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
115
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 */
126
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
131
132 #define PTEX_FALLBACK() FALLBACK(R128_CONTEXT(ctx), R128_FALLBACK_TEXTURE, 1)
133
134 #define IMPORT_FLOAT_COLORS r128_import_float_colors
135 #define IMPORT_FLOAT_SPEC_COLORS r128_import_float_spec_colors
136
137 #define INTERP_VERTEX setup_tab[rmesa->SetupIndex].interp
138 #define COPY_PV_VERTEX setup_tab[rmesa->SetupIndex].copy_pv
139
140 /***********************************************************************
141 * Generate pv-copying and translation functions *
142 ***********************************************************************/
143
144 #define TAG(x) r128_##x
145 #include "tnl_dd/t_dd_vb.c"
146
147 /***********************************************************************
148 * Generate vertex emit and interp functions *
149 ***********************************************************************/
150
151
152 #define IND (R128_XYZW_BIT|R128_RGBA_BIT)
153 #define TAG(x) x##_wg
154 #include "tnl_dd/t_dd_vbtmp.h"
155
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"
159
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"
163
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"
167
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"
171
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"
175
176 #define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX0_BIT|\
177 R128_TEX1_BIT)
178 #define TAG(x) x##_wgst0t1
179 #include "tnl_dd/t_dd_vbtmp.h"
180
181 #define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX0_BIT|\
182 R128_PTEX_BIT)
183 #define TAG(x) x##_wgspt0
184 #include "tnl_dd/t_dd_vbtmp.h"
185
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"
189
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"
193
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"
197
198 #define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_TEX0_BIT|\
199 R128_TEX1_BIT)
200 #define TAG(x) x##_wgft0t1
201 #include "tnl_dd/t_dd_vbtmp.h"
202
203 #define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_TEX0_BIT|\
204 R128_PTEX_BIT)
205 #define TAG(x) x##_wgfpt0
206 #include "tnl_dd/t_dd_vbtmp.h"
207
208 #define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|\
209 R128_TEX0_BIT)
210 #define TAG(x) x##_wgfst0
211 #include "tnl_dd/t_dd_vbtmp.h"
212
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"
217
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"
222
223 #define IND (R128_TEX0_BIT)
224 #define TAG(x) x##_t0
225 #include "tnl_dd/t_dd_vbtmp.h"
226
227 #define IND (R128_TEX0_BIT|R128_TEX1_BIT)
228 #define TAG(x) x##_t0t1
229 #include "tnl_dd/t_dd_vbtmp.h"
230
231 #define IND (R128_FOG_BIT)
232 #define TAG(x) x##_f
233 #include "tnl_dd/t_dd_vbtmp.h"
234
235 #define IND (R128_FOG_BIT|R128_TEX0_BIT)
236 #define TAG(x) x##_ft0
237 #include "tnl_dd/t_dd_vbtmp.h"
238
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"
242
243 #define IND (R128_RGBA_BIT)
244 #define TAG(x) x##_g
245 #include "tnl_dd/t_dd_vbtmp.h"
246
247 #define IND (R128_RGBA_BIT|R128_SPEC_BIT)
248 #define TAG(x) x##_gs
249 #include "tnl_dd/t_dd_vbtmp.h"
250
251 #define IND (R128_RGBA_BIT|R128_TEX0_BIT)
252 #define TAG(x) x##_gt0
253 #include "tnl_dd/t_dd_vbtmp.h"
254
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"
258
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"
262
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"
266
267 #define IND (R128_RGBA_BIT|R128_FOG_BIT)
268 #define TAG(x) x##_gf
269 #include "tnl_dd/t_dd_vbtmp.h"
270
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"
274
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"
278
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"
282
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"
286
287 #define IND (R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|R128_TEX0_BIT|\
288 R128_TEX1_BIT)
289 #define TAG(x) x##_gfst0t1
290 #include "tnl_dd/t_dd_vbtmp.h"
291
292
293 static void init_setup_tab( void )
294 {
295 init_wg();
296 init_wgs();
297 init_wgt0();
298 init_wgt0t1();
299 init_wgpt0();
300 init_wgst0();
301 init_wgst0t1();
302 init_wgspt0();
303 init_wgf();
304 init_wgfs();
305 init_wgft0();
306 init_wgft0t1();
307 init_wgfpt0();
308 init_wgfst0();
309 init_wgfst0t1();
310 init_wgfspt0();
311 init_t0();
312 init_t0t1();
313 init_f();
314 init_ft0();
315 init_ft0t1();
316 init_g();
317 init_gs();
318 init_gt0();
319 init_gt0t1();
320 init_gst0();
321 init_gst0t1();
322 init_gf();
323 init_gfs();
324 init_gft0();
325 init_gft0t1();
326 init_gfst0();
327 init_gfst0t1();
328 }
329
330
331
332 void r128PrintSetupFlags(char *msg, GLuint flags )
333 {
334 fprintf(stderr, "%s(%x): %s%s%s%s%s%s\n",
335 msg,
336 (int)flags,
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," : "");
343 }
344
345
346
347 void r128CheckTexSizes( GLcontext *ctx )
348 {
349 r128ContextPtr rmesa = R128_CONTEXT( ctx );
350
351 if (!setup_tab[rmesa->SetupIndex].check_tex_sizes(ctx)) {
352 TNLcontext *tnl = TNL_CONTEXT(ctx);
353
354 /* Invalidate stored verts
355 */
356 rmesa->SetupNewInputs = ~0;
357 rmesa->SetupIndex |= R128_PTEX_BIT;
358
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;
363 }
364 if (rmesa->Fallback) {
365 tnl->Driver.Render.Start(ctx);
366 }
367 }
368 }
369
370 void r128BuildVertices( GLcontext *ctx,
371 GLuint start,
372 GLuint count,
373 GLuint newinputs )
374 {
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;
378
379 newinputs |= rmesa->SetupNewInputs;
380 rmesa->SetupNewInputs = 0;
381
382 if (!newinputs)
383 return;
384
385 if (newinputs & VERT_BIT_POS) {
386 setup_tab[rmesa->SetupIndex].emit( ctx, start, count, v, stride );
387 } else {
388 GLuint ind = 0;
389
390 if (newinputs & VERT_BIT_COLOR0)
391 ind |= R128_RGBA_BIT;
392
393 if (newinputs & VERT_BIT_COLOR1)
394 ind |= R128_SPEC_BIT;
395
396 if (newinputs & VERT_BIT_TEX0)
397 ind |= R128_TEX0_BIT;
398
399 if (newinputs & VERT_BIT_TEX1)
400 ind |= R128_TEX1_BIT;
401
402 if (newinputs & VERT_BIT_FOG)
403 ind |= R128_FOG_BIT;
404
405 if (rmesa->SetupIndex & R128_PTEX_BIT)
406 ind = ~0;
407
408 ind &= rmesa->SetupIndex;
409
410 if (ind) {
411 setup_tab[ind].emit( ctx, start, count, v, stride );
412 }
413 }
414 }
415
416 void r128ChooseVertexState( GLcontext *ctx )
417 {
418 TNLcontext *tnl = TNL_CONTEXT(ctx);
419 r128ContextPtr rmesa = R128_CONTEXT( ctx );
420 GLuint ind = R128_XYZW_BIT|R128_RGBA_BIT;
421
422 if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
423 ind |= R128_SPEC_BIT;
424
425 if (ctx->Fog.Enabled)
426 ind |= R128_FOG_BIT;
427
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;
433 }
434
435 rmesa->SetupIndex = ind;
436
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;
440 } else {
441 tnl->Driver.Render.Interp = setup_tab[ind].interp;
442 tnl->Driver.Render.CopyPV = setup_tab[ind].copy_pv;
443 }
444
445 if (setup_tab[ind].vertex_format != rmesa->vertex_format) {
446 FLUSH_BATCH(rmesa);
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;
450 }
451 }
452
453
454
455 void r128_emit_contiguous_verts( GLcontext *ctx,
456 GLuint start,
457 GLuint count )
458 {
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 );
463 }
464
465
466 #if 0
467 void r128_emit_indexed_verts( GLcontext *ctx, GLuint start, GLuint count )
468 {
469 r128ContextPtr rmesa = R128_CONTEXT(ctx);
470 GLuint vertex_size = rmesa->vertex_size * 4;
471 GLuint bufsz = (count-start) * vertex_size;
472 CARD32 *dest;
473
474 rmesa->vertex_low = (rmesa->vertex_low + 63) & ~63; /* alignment */
475 rmesa->vertex_last_prim = rmesa->vertex_low;
476
477 dest = r128AllocDmaLow( rmesa, bufsz, __FUNCTION__);
478 setup_tab[rmesa->SetupIndex].emit( ctx, start, count, dest, vertex_size );
479
480 rmesa->retained_buffer = rmesa->vertex_buffer;
481 rmesa->vb_offset = (rmesa->vertex_buffer->idx * R128_BUFFER_SIZE +
482 rmesa->vertex_low - bufsz);
483
484 rmesa->vertex_low = (rmesa->vertex_low + 0x7) & ~0x7; /* alignment */
485 rmesa->vertex_last_prim = rmesa->vertex_low;
486 }
487 #endif
488
489
490 void r128InitVB( GLcontext *ctx )
491 {
492 r128ContextPtr rmesa = R128_CONTEXT(ctx);
493 GLuint size = TNL_CONTEXT(ctx)->vb.Size;
494
495 rmesa->verts = (GLubyte *)ALIGN_MALLOC(size * 4 * 16, 32);
496
497 {
498 static int firsttime = 1;
499 if (firsttime) {
500 init_setup_tab();
501 firsttime = 0;
502 }
503 }
504 }
505
506
507 void r128FreeVB( GLcontext *ctx )
508 {
509 r128ContextPtr rmesa = R128_CONTEXT(ctx);
510 if (rmesa->verts) {
511 ALIGN_FREE(rmesa->verts);
512 rmesa->verts = 0;
513 }
514
515
516 if (rmesa->UbyteSecondaryColor.Ptr) {
517 ALIGN_FREE(rmesa->UbyteSecondaryColor.Ptr);
518 rmesa->UbyteSecondaryColor.Ptr = 0;
519 }
520
521 if (rmesa->UbyteColor.Ptr) {
522 ALIGN_FREE(rmesa->UbyteColor.Ptr);
523 rmesa->UbyteColor.Ptr = 0;
524 }
525 }