Import vtx-0-2-branch
[mesa.git] / src / mesa / drivers / dri / i810 / i810vb.c
1 /*
2 * GLX Hardware Device Driver for Intel i810
3 * Copyright (C) 1999 Keith Whitwell
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included
13 * in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
21 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 *
23 *
24 */
25 /* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810vb.c,v 1.13 2003/03/26 20:43:48 tsi Exp $ */
26
27
28 #include "glheader.h"
29 #include "mtypes.h"
30 #include "imports.h"
31 #include "macros.h"
32 #include "colormac.h"
33
34 #include "swrast_setup/swrast_setup.h"
35 #include "tnl/t_context.h"
36
37 #include "i810screen.h"
38 #include "i810_dri.h"
39
40 #include "i810context.h"
41 #include "i810vb.h"
42 #include "i810ioctl.h"
43 #include "i810tris.h"
44 #include "i810state.h"
45
46
47 #define I810_TEX1_BIT 0x1
48 #define I810_TEX0_BIT 0x2
49 #define I810_RGBA_BIT 0x4
50 #define I810_SPEC_BIT 0x8
51 #define I810_FOG_BIT 0x10
52 #define I810_XYZW_BIT 0x20
53 #define I810_PTEX_BIT 0x40
54 #define I810_MAX_SETUP 0x80
55
56 static struct {
57 void (*emit)( GLcontext *, GLuint, GLuint, void *, GLuint );
58 interp_func interp;
59 copy_pv_func copy_pv;
60 GLboolean (*check_tex_sizes)( GLcontext *ctx );
61 GLuint vertex_size;
62 GLuint vertex_stride_shift;
63 GLuint vertex_format;
64 } setup_tab[I810_MAX_SETUP];
65
66 #define TINY_VERTEX_FORMAT (GFX_OP_VERTEX_FMT | \
67 VF_TEXCOORD_COUNT_0 | \
68 VF_RGBA_ENABLE | \
69 VF_XYZ)
70
71 #define NOTEX_VERTEX_FORMAT (GFX_OP_VERTEX_FMT | \
72 VF_TEXCOORD_COUNT_0 | \
73 VF_SPEC_FOG_ENABLE | \
74 VF_RGBA_ENABLE | \
75 VF_XYZW)
76
77 #define TEX0_VERTEX_FORMAT (GFX_OP_VERTEX_FMT | \
78 VF_TEXCOORD_COUNT_1 | \
79 VF_SPEC_FOG_ENABLE | \
80 VF_RGBA_ENABLE | \
81 VF_XYZW)
82
83 #define TEX1_VERTEX_FORMAT (GFX_OP_VERTEX_FMT | \
84 VF_TEXCOORD_COUNT_2 | \
85 VF_SPEC_FOG_ENABLE | \
86 VF_RGBA_ENABLE | \
87 VF_XYZW)
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 & I810_XYZW_BIT)
95 #define DO_RGBA (IND & I810_RGBA_BIT)
96 #define DO_SPEC (IND & I810_SPEC_BIT)
97 #define DO_FOG (IND & I810_FOG_BIT)
98 #define DO_TEX0 (IND & I810_TEX0_BIT)
99 #define DO_TEX1 (IND & I810_TEX1_BIT)
100 #define DO_TEX2 0
101 #define DO_TEX3 0
102 #define DO_PTEX (IND & I810_PTEX_BIT)
103
104 #define VERTEX i810Vertex
105 #define VERTEX_COLOR i810_color_t
106 #define GET_VIEWPORT_MAT() I810_CONTEXT(ctx)->ViewportMatrix.m
107 #define GET_TEXSOURCE(n) n
108 #define GET_VERTEX_FORMAT() I810_CONTEXT(ctx)->Setup[I810_CTXREG_VF]
109 #define GET_VERTEX_STORE() I810_CONTEXT(ctx)->verts
110 #define GET_VERTEX_STRIDE_SHIFT() I810_CONTEXT(ctx)->vertex_stride_shift
111 #define GET_UBYTE_COLOR_STORE() &I810_CONTEXT(ctx)->UbyteColor
112 #define GET_UBYTE_SPEC_COLOR_STORE() &I810_CONTEXT(ctx)->UbyteSecondaryColor
113 #define INVALIDATE_STORED_VERTICES()
114
115 #define HAVE_HW_VIEWPORT 0
116 #define HAVE_HW_DIVIDE 0
117 #define HAVE_RGBA_COLOR 0
118 #define HAVE_TINY_VERTICES 1
119 #define HAVE_NOTEX_VERTICES 1
120 #define HAVE_TEX0_VERTICES 1
121 #define HAVE_TEX1_VERTICES 1
122 #define HAVE_TEX2_VERTICES 0
123 #define HAVE_TEX3_VERTICES 0
124 #define HAVE_PTEX_VERTICES 0
125
126 #define UNVIEWPORT_VARS GLfloat h = I810_CONTEXT(ctx)->driDrawable->h
127 #define UNVIEWPORT_X(x) x - SUBPIXEL_X
128 #define UNVIEWPORT_Y(y) - y + h + SUBPIXEL_Y
129 #define UNVIEWPORT_Z(z) z * (float)0xffff
130
131 #define PTEX_FALLBACK() FALLBACK(I810_CONTEXT(ctx), I810_FALLBACK_TEXTURE, 1)
132
133 #define IMPORT_FLOAT_COLORS i810_import_float_colors
134 #define IMPORT_FLOAT_SPEC_COLORS i810_import_float_spec_colors
135
136 #define INTERP_VERTEX setup_tab[I810_CONTEXT(ctx)->SetupIndex].interp
137 #define COPY_PV_VERTEX setup_tab[I810_CONTEXT(ctx)->SetupIndex].copy_pv
138
139
140 /***********************************************************************
141 * Generate pv-copying and translation functions *
142 ***********************************************************************/
143
144 #define TAG(x) i810_##x
145 #include "tnl_dd/t_dd_vb.c"
146
147 /***********************************************************************
148 * Generate vertex emit and interp functions *
149 ***********************************************************************/
150
151
152 #define IND (I810_XYZW_BIT|I810_RGBA_BIT)
153 #define TAG(x) x##_wg
154 #include "tnl_dd/t_dd_vbtmp.h"
155
156 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_SPEC_BIT)
157 #define TAG(x) x##_wgs
158 #include "tnl_dd/t_dd_vbtmp.h"
159
160 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_TEX0_BIT)
161 #define TAG(x) x##_wgt0
162 #include "tnl_dd/t_dd_vbtmp.h"
163
164 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_TEX0_BIT|I810_TEX1_BIT)
165 #define TAG(x) x##_wgt0t1
166 #include "tnl_dd/t_dd_vbtmp.h"
167
168 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_TEX0_BIT|I810_PTEX_BIT)
169 #define TAG(x) x##_wgpt0
170 #include "tnl_dd/t_dd_vbtmp.h"
171
172 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT)
173 #define TAG(x) x##_wgst0
174 #include "tnl_dd/t_dd_vbtmp.h"
175
176 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT|\
177 I810_TEX1_BIT)
178 #define TAG(x) x##_wgst0t1
179 #include "tnl_dd/t_dd_vbtmp.h"
180
181 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT|\
182 I810_PTEX_BIT)
183 #define TAG(x) x##_wgspt0
184 #include "tnl_dd/t_dd_vbtmp.h"
185
186 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT)
187 #define TAG(x) x##_wgf
188 #include "tnl_dd/t_dd_vbtmp.h"
189
190 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT)
191 #define TAG(x) x##_wgfs
192 #include "tnl_dd/t_dd_vbtmp.h"
193
194 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT)
195 #define TAG(x) x##_wgft0
196 #include "tnl_dd/t_dd_vbtmp.h"
197
198 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT|\
199 I810_TEX1_BIT)
200 #define TAG(x) x##_wgft0t1
201 #include "tnl_dd/t_dd_vbtmp.h"
202
203 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT|\
204 I810_PTEX_BIT)
205 #define TAG(x) x##_wgfpt0
206 #include "tnl_dd/t_dd_vbtmp.h"
207
208 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT|\
209 I810_TEX0_BIT)
210 #define TAG(x) x##_wgfst0
211 #include "tnl_dd/t_dd_vbtmp.h"
212
213 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT|\
214 I810_TEX0_BIT|I810_TEX1_BIT)
215 #define TAG(x) x##_wgfst0t1
216 #include "tnl_dd/t_dd_vbtmp.h"
217
218 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT|\
219 I810_TEX0_BIT|I810_PTEX_BIT)
220 #define TAG(x) x##_wgfspt0
221 #include "tnl_dd/t_dd_vbtmp.h"
222
223 #define IND (I810_TEX0_BIT)
224 #define TAG(x) x##_t0
225 #include "tnl_dd/t_dd_vbtmp.h"
226
227 #define IND (I810_TEX0_BIT|I810_TEX1_BIT)
228 #define TAG(x) x##_t0t1
229 #include "tnl_dd/t_dd_vbtmp.h"
230
231 #define IND (I810_FOG_BIT)
232 #define TAG(x) x##_f
233 #include "tnl_dd/t_dd_vbtmp.h"
234
235 #define IND (I810_FOG_BIT|I810_TEX0_BIT)
236 #define TAG(x) x##_ft0
237 #include "tnl_dd/t_dd_vbtmp.h"
238
239 #define IND (I810_FOG_BIT|I810_TEX0_BIT|I810_TEX1_BIT)
240 #define TAG(x) x##_ft0t1
241 #include "tnl_dd/t_dd_vbtmp.h"
242
243 #define IND (I810_RGBA_BIT)
244 #define TAG(x) x##_g
245 #include "tnl_dd/t_dd_vbtmp.h"
246
247 #define IND (I810_RGBA_BIT|I810_SPEC_BIT)
248 #define TAG(x) x##_gs
249 #include "tnl_dd/t_dd_vbtmp.h"
250
251 #define IND (I810_RGBA_BIT|I810_TEX0_BIT)
252 #define TAG(x) x##_gt0
253 #include "tnl_dd/t_dd_vbtmp.h"
254
255 #define IND (I810_RGBA_BIT|I810_TEX0_BIT|I810_TEX1_BIT)
256 #define TAG(x) x##_gt0t1
257 #include "tnl_dd/t_dd_vbtmp.h"
258
259 #define IND (I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT)
260 #define TAG(x) x##_gst0
261 #include "tnl_dd/t_dd_vbtmp.h"
262
263 #define IND (I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT|I810_TEX1_BIT)
264 #define TAG(x) x##_gst0t1
265 #include "tnl_dd/t_dd_vbtmp.h"
266
267 #define IND (I810_RGBA_BIT|I810_FOG_BIT)
268 #define TAG(x) x##_gf
269 #include "tnl_dd/t_dd_vbtmp.h"
270
271 #define IND (I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT)
272 #define TAG(x) x##_gfs
273 #include "tnl_dd/t_dd_vbtmp.h"
274
275 #define IND (I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT)
276 #define TAG(x) x##_gft0
277 #include "tnl_dd/t_dd_vbtmp.h"
278
279 #define IND (I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT|I810_TEX1_BIT)
280 #define TAG(x) x##_gft0t1
281 #include "tnl_dd/t_dd_vbtmp.h"
282
283 #define IND (I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT|I810_TEX0_BIT)
284 #define TAG(x) x##_gfst0
285 #include "tnl_dd/t_dd_vbtmp.h"
286
287 #define IND (I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT|I810_TEX0_BIT|\
288 I810_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 i810PrintSetupFlags(char *msg, GLuint flags )
333 {
334 fprintf(stderr, "%s(%x): %s%s%s%s%s%s\n",
335 msg,
336 (int)flags,
337 (flags & I810_XYZW_BIT) ? " xyzw," : "",
338 (flags & I810_RGBA_BIT) ? " rgba," : "",
339 (flags & I810_SPEC_BIT) ? " spec," : "",
340 (flags & I810_FOG_BIT) ? " fog," : "",
341 (flags & I810_TEX0_BIT) ? " tex-0," : "",
342 (flags & I810_TEX1_BIT) ? " tex-1," : "");
343 }
344
345
346
347 void i810CheckTexSizes( GLcontext *ctx )
348 {
349 TNLcontext *tnl = TNL_CONTEXT(ctx);
350 i810ContextPtr imesa = I810_CONTEXT( ctx );
351
352 if (!setup_tab[imesa->SetupIndex].check_tex_sizes(ctx)) {
353 /* Invalidate stored verts
354 */
355 imesa->SetupNewInputs = ~0;
356 imesa->SetupIndex |= I810_PTEX_BIT;
357
358 if (!imesa->Fallback &&
359 !(ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) {
360 tnl->Driver.Render.Interp = setup_tab[imesa->SetupIndex].interp;
361 tnl->Driver.Render.CopyPV = setup_tab[imesa->SetupIndex].copy_pv;
362 }
363 if (imesa->Fallback) {
364 tnl->Driver.Render.Start(ctx);
365 }
366 }
367 }
368
369 void i810BuildVertices( GLcontext *ctx,
370 GLuint start,
371 GLuint count,
372 GLuint newinputs )
373 {
374 i810ContextPtr imesa = I810_CONTEXT( ctx );
375 GLubyte *v = ((GLubyte *)imesa->verts + (start<<imesa->vertex_stride_shift));
376 GLuint stride = 1<<imesa->vertex_stride_shift;
377
378 if (0) fprintf(stderr, "%s\n", __FUNCTION__);
379
380 newinputs |= imesa->SetupNewInputs;
381 imesa->SetupNewInputs = 0;
382
383 if (!newinputs)
384 return;
385
386 if (newinputs & VERT_BIT_POS) {
387 setup_tab[imesa->SetupIndex].emit( ctx, start, count, v, stride );
388 } else {
389 GLuint ind = 0;
390
391 if (newinputs & VERT_BIT_COLOR0)
392 ind |= I810_RGBA_BIT;
393
394 if (newinputs & VERT_BIT_COLOR1)
395 ind |= I810_SPEC_BIT;
396
397 if (newinputs & VERT_BIT_TEX0)
398 ind |= I810_TEX0_BIT;
399
400 if (newinputs & VERT_BIT_TEX1)
401 ind |= I810_TEX1_BIT;
402
403 if (newinputs & VERT_BIT_FOG)
404 ind |= I810_FOG_BIT;
405
406 if (imesa->SetupIndex & I810_PTEX_BIT)
407 ind = ~0;
408
409 ind &= imesa->SetupIndex;
410
411 if (ind) {
412 setup_tab[ind].emit( ctx, start, count, v, stride );
413 }
414 }
415 }
416
417 void i810ChooseVertexState( GLcontext *ctx )
418 {
419 TNLcontext *tnl = TNL_CONTEXT(ctx);
420 i810ContextPtr imesa = I810_CONTEXT( ctx );
421 GLuint ind = I810_XYZW_BIT|I810_RGBA_BIT;
422
423 if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
424 ind |= I810_SPEC_BIT;
425
426 if (ctx->Fog.Enabled)
427 ind |= I810_FOG_BIT;
428
429 if (ctx->Texture._EnabledUnits & 0x2)
430 /* unit 1 enabled */
431 ind |= I810_TEX1_BIT|I810_TEX0_BIT;
432 else if (ctx->Texture._EnabledUnits & 0x1)
433 /* unit 0 enabled */
434 ind |= I810_TEX0_BIT;
435
436 imesa->SetupIndex = ind;
437
438 if (I810_DEBUG & (DEBUG_VERTS|DEBUG_STATE))
439 i810PrintSetupFlags( __FUNCTION__, ind );
440
441 if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED)) {
442 tnl->Driver.Render.Interp = i810_interp_extras;
443 tnl->Driver.Render.CopyPV = i810_copy_pv_extras;
444 } else {
445 tnl->Driver.Render.Interp = setup_tab[ind].interp;
446 tnl->Driver.Render.CopyPV = setup_tab[ind].copy_pv;
447 }
448
449 if (setup_tab[ind].vertex_format != imesa->Setup[I810_CTXREG_VF]) {
450 I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
451 imesa->Setup[I810_CTXREG_VF] = setup_tab[ind].vertex_format;
452 imesa->vertex_size = setup_tab[ind].vertex_size;
453 imesa->vertex_stride_shift = setup_tab[ind].vertex_stride_shift;
454 }
455 }
456
457
458
459 void i810_emit_contiguous_verts( GLcontext *ctx,
460 GLuint start,
461 GLuint count )
462 {
463 i810ContextPtr imesa = I810_CONTEXT(ctx);
464 GLuint vertex_size = imesa->vertex_size * 4;
465 GLuint *dest = i810AllocDmaLow( imesa, (count-start) * vertex_size);
466 setup_tab[imesa->SetupIndex].emit( ctx, start, count, dest, vertex_size );
467 }
468
469
470
471 void i810InitVB( GLcontext *ctx )
472 {
473 i810ContextPtr imesa = I810_CONTEXT(ctx);
474 GLuint size = TNL_CONTEXT(ctx)->vb.Size;
475
476 imesa->verts = (GLubyte *)ALIGN_MALLOC(size * 4 * 16, 32);
477
478 {
479 static int firsttime = 1;
480 if (firsttime) {
481 init_setup_tab();
482 firsttime = 0;
483 }
484 }
485 }
486
487
488 void i810FreeVB( GLcontext *ctx )
489 {
490 i810ContextPtr imesa = I810_CONTEXT(ctx);
491 if (imesa->verts) {
492 ALIGN_FREE(imesa->verts);
493 imesa->verts = 0;
494 }
495
496 if (imesa->UbyteSecondaryColor.Ptr) {
497 ALIGN_FREE(imesa->UbyteSecondaryColor.Ptr);
498 imesa->UbyteSecondaryColor.Ptr = 0;
499 }
500
501 if (imesa->UbyteColor.Ptr) {
502 ALIGN_FREE(imesa->UbyteColor.Ptr);
503 imesa->UbyteColor.Ptr = 0;
504 }
505 }