Merge branch 'master' into gallium-0.2
[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
26
27 #include "main/glheader.h"
28 #include "main/mtypes.h"
29 #include "main/imports.h"
30 #include "main/macros.h"
31 #include "main/colormac.h"
32
33 #include "swrast_setup/swrast_setup.h"
34 #include "tnl/t_context.h"
35
36 #include "i810screen.h"
37 #include "i810_dri.h"
38 #include "i810context.h"
39 #include "i810vb.h"
40 #include "i810ioctl.h"
41 #include "i810tris.h"
42 #include "i810state.h"
43
44
45 #define I810_TEX1_BIT 0x1
46 #define I810_TEX0_BIT 0x2
47 #define I810_RGBA_BIT 0x4
48 #define I810_SPEC_BIT 0x8
49 #define I810_FOG_BIT 0x10
50 #define I810_XYZW_BIT 0x20
51 #define I810_PTEX_BIT 0x40
52 #define I810_MAX_SETUP 0x80
53
54 static struct {
55 void (*emit)( GLcontext *, GLuint, GLuint, void *, GLuint );
56 tnl_interp_func interp;
57 tnl_copy_pv_func copy_pv;
58 GLboolean (*check_tex_sizes)( GLcontext *ctx );
59 GLuint vertex_size;
60 GLuint vertex_format;
61 } setup_tab[I810_MAX_SETUP];
62
63 #define TINY_VERTEX_FORMAT (GFX_OP_VERTEX_FMT | \
64 VF_TEXCOORD_COUNT_0 | \
65 VF_RGBA_ENABLE | \
66 VF_XYZ)
67
68 #define NOTEX_VERTEX_FORMAT (GFX_OP_VERTEX_FMT | \
69 VF_TEXCOORD_COUNT_0 | \
70 VF_SPEC_FOG_ENABLE | \
71 VF_RGBA_ENABLE | \
72 VF_XYZW)
73
74 #define TEX0_VERTEX_FORMAT (GFX_OP_VERTEX_FMT | \
75 VF_TEXCOORD_COUNT_1 | \
76 VF_SPEC_FOG_ENABLE | \
77 VF_RGBA_ENABLE | \
78 VF_XYZW)
79
80 #define TEX1_VERTEX_FORMAT (GFX_OP_VERTEX_FMT | \
81 VF_TEXCOORD_COUNT_2 | \
82 VF_SPEC_FOG_ENABLE | \
83 VF_RGBA_ENABLE | \
84 VF_XYZW)
85
86 #define PROJ_TEX1_VERTEX_FORMAT 0
87 #define TEX2_VERTEX_FORMAT 0
88 #define TEX3_VERTEX_FORMAT 0
89 #define PROJ_TEX3_VERTEX_FORMAT 0
90
91 #define DO_XYZW (IND & I810_XYZW_BIT)
92 #define DO_RGBA (IND & I810_RGBA_BIT)
93 #define DO_SPEC (IND & I810_SPEC_BIT)
94 #define DO_FOG (IND & I810_FOG_BIT)
95 #define DO_TEX0 (IND & I810_TEX0_BIT)
96 #define DO_TEX1 (IND & I810_TEX1_BIT)
97 #define DO_TEX2 0
98 #define DO_TEX3 0
99 #define DO_PTEX (IND & I810_PTEX_BIT)
100
101 #define VERTEX i810Vertex
102 #define VERTEX_COLOR i810_color_t
103 #define GET_VIEWPORT_MAT() I810_CONTEXT(ctx)->ViewportMatrix.m
104 #define GET_TEXSOURCE(n) n
105 #define GET_VERTEX_FORMAT() I810_CONTEXT(ctx)->Setup[I810_CTXREG_VF]
106 #define GET_VERTEX_STORE() I810_CONTEXT(ctx)->verts
107 #define GET_VERTEX_SIZE() I810_CONTEXT(ctx)->vertex_size * sizeof(GLuint)
108 #define INVALIDATE_STORED_VERTICES()
109
110 #define HAVE_HW_VIEWPORT 0
111 #define HAVE_HW_DIVIDE 0
112 #define HAVE_RGBA_COLOR 0
113 #define HAVE_TINY_VERTICES 1
114 #define HAVE_NOTEX_VERTICES 1
115 #define HAVE_TEX0_VERTICES 1
116 #define HAVE_TEX1_VERTICES 1
117 #define HAVE_TEX2_VERTICES 0
118 #define HAVE_TEX3_VERTICES 0
119 #define HAVE_PTEX_VERTICES 0
120
121 #define UNVIEWPORT_VARS GLfloat h = I810_CONTEXT(ctx)->driDrawable->h
122 #define UNVIEWPORT_X(x) x - SUBPIXEL_X
123 #define UNVIEWPORT_Y(y) - y + h + SUBPIXEL_Y
124 #define UNVIEWPORT_Z(z) z * (float)0xffff
125
126 #define PTEX_FALLBACK() FALLBACK(I810_CONTEXT(ctx), I810_FALLBACK_TEXTURE, 1)
127
128 #define INTERP_VERTEX setup_tab[I810_CONTEXT(ctx)->SetupIndex].interp
129 #define COPY_PV_VERTEX setup_tab[I810_CONTEXT(ctx)->SetupIndex].copy_pv
130
131
132 /***********************************************************************
133 * Generate pv-copying and translation functions *
134 ***********************************************************************/
135
136 #define TAG(x) i810_##x
137 #include "tnl_dd/t_dd_vb.c"
138
139 /***********************************************************************
140 * Generate vertex emit and interp functions *
141 ***********************************************************************/
142
143
144 #define IND (I810_XYZW_BIT|I810_RGBA_BIT)
145 #define TAG(x) x##_wg
146 #include "tnl_dd/t_dd_vbtmp.h"
147
148 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_SPEC_BIT)
149 #define TAG(x) x##_wgs
150 #include "tnl_dd/t_dd_vbtmp.h"
151
152 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_TEX0_BIT)
153 #define TAG(x) x##_wgt0
154 #include "tnl_dd/t_dd_vbtmp.h"
155
156 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_TEX0_BIT|I810_TEX1_BIT)
157 #define TAG(x) x##_wgt0t1
158 #include "tnl_dd/t_dd_vbtmp.h"
159
160 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_TEX0_BIT|I810_PTEX_BIT)
161 #define TAG(x) x##_wgpt0
162 #include "tnl_dd/t_dd_vbtmp.h"
163
164 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT)
165 #define TAG(x) x##_wgst0
166 #include "tnl_dd/t_dd_vbtmp.h"
167
168 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT|\
169 I810_TEX1_BIT)
170 #define TAG(x) x##_wgst0t1
171 #include "tnl_dd/t_dd_vbtmp.h"
172
173 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT|\
174 I810_PTEX_BIT)
175 #define TAG(x) x##_wgspt0
176 #include "tnl_dd/t_dd_vbtmp.h"
177
178 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT)
179 #define TAG(x) x##_wgf
180 #include "tnl_dd/t_dd_vbtmp.h"
181
182 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT)
183 #define TAG(x) x##_wgfs
184 #include "tnl_dd/t_dd_vbtmp.h"
185
186 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT)
187 #define TAG(x) x##_wgft0
188 #include "tnl_dd/t_dd_vbtmp.h"
189
190 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT|\
191 I810_TEX1_BIT)
192 #define TAG(x) x##_wgft0t1
193 #include "tnl_dd/t_dd_vbtmp.h"
194
195 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT|\
196 I810_PTEX_BIT)
197 #define TAG(x) x##_wgfpt0
198 #include "tnl_dd/t_dd_vbtmp.h"
199
200 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT|\
201 I810_TEX0_BIT)
202 #define TAG(x) x##_wgfst0
203 #include "tnl_dd/t_dd_vbtmp.h"
204
205 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT|\
206 I810_TEX0_BIT|I810_TEX1_BIT)
207 #define TAG(x) x##_wgfst0t1
208 #include "tnl_dd/t_dd_vbtmp.h"
209
210 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT|\
211 I810_TEX0_BIT|I810_PTEX_BIT)
212 #define TAG(x) x##_wgfspt0
213 #include "tnl_dd/t_dd_vbtmp.h"
214
215 #define IND (I810_TEX0_BIT)
216 #define TAG(x) x##_t0
217 #include "tnl_dd/t_dd_vbtmp.h"
218
219 #define IND (I810_TEX0_BIT|I810_TEX1_BIT)
220 #define TAG(x) x##_t0t1
221 #include "tnl_dd/t_dd_vbtmp.h"
222
223 #define IND (I810_FOG_BIT)
224 #define TAG(x) x##_f
225 #include "tnl_dd/t_dd_vbtmp.h"
226
227 #define IND (I810_FOG_BIT|I810_TEX0_BIT)
228 #define TAG(x) x##_ft0
229 #include "tnl_dd/t_dd_vbtmp.h"
230
231 #define IND (I810_FOG_BIT|I810_TEX0_BIT|I810_TEX1_BIT)
232 #define TAG(x) x##_ft0t1
233 #include "tnl_dd/t_dd_vbtmp.h"
234
235 #define IND (I810_RGBA_BIT)
236 #define TAG(x) x##_g
237 #include "tnl_dd/t_dd_vbtmp.h"
238
239 #define IND (I810_RGBA_BIT|I810_SPEC_BIT)
240 #define TAG(x) x##_gs
241 #include "tnl_dd/t_dd_vbtmp.h"
242
243 #define IND (I810_RGBA_BIT|I810_TEX0_BIT)
244 #define TAG(x) x##_gt0
245 #include "tnl_dd/t_dd_vbtmp.h"
246
247 #define IND (I810_RGBA_BIT|I810_TEX0_BIT|I810_TEX1_BIT)
248 #define TAG(x) x##_gt0t1
249 #include "tnl_dd/t_dd_vbtmp.h"
250
251 #define IND (I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT)
252 #define TAG(x) x##_gst0
253 #include "tnl_dd/t_dd_vbtmp.h"
254
255 #define IND (I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT|I810_TEX1_BIT)
256 #define TAG(x) x##_gst0t1
257 #include "tnl_dd/t_dd_vbtmp.h"
258
259 #define IND (I810_RGBA_BIT|I810_FOG_BIT)
260 #define TAG(x) x##_gf
261 #include "tnl_dd/t_dd_vbtmp.h"
262
263 #define IND (I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT)
264 #define TAG(x) x##_gfs
265 #include "tnl_dd/t_dd_vbtmp.h"
266
267 #define IND (I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT)
268 #define TAG(x) x##_gft0
269 #include "tnl_dd/t_dd_vbtmp.h"
270
271 #define IND (I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT|I810_TEX1_BIT)
272 #define TAG(x) x##_gft0t1
273 #include "tnl_dd/t_dd_vbtmp.h"
274
275 #define IND (I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT|I810_TEX0_BIT)
276 #define TAG(x) x##_gfst0
277 #include "tnl_dd/t_dd_vbtmp.h"
278
279 #define IND (I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT|I810_TEX0_BIT|\
280 I810_TEX1_BIT)
281 #define TAG(x) x##_gfst0t1
282 #include "tnl_dd/t_dd_vbtmp.h"
283
284
285 static void init_setup_tab( void )
286 {
287 init_wg();
288 init_wgs();
289 init_wgt0();
290 init_wgt0t1();
291 init_wgpt0();
292 init_wgst0();
293 init_wgst0t1();
294 init_wgspt0();
295 init_wgf();
296 init_wgfs();
297 init_wgft0();
298 init_wgft0t1();
299 init_wgfpt0();
300 init_wgfst0();
301 init_wgfst0t1();
302 init_wgfspt0();
303 init_t0();
304 init_t0t1();
305 init_f();
306 init_ft0();
307 init_ft0t1();
308 init_g();
309 init_gs();
310 init_gt0();
311 init_gt0t1();
312 init_gst0();
313 init_gst0t1();
314 init_gf();
315 init_gfs();
316 init_gft0();
317 init_gft0t1();
318 init_gfst0();
319 init_gfst0t1();
320 }
321
322
323
324 static void i810PrintSetupFlags(const char *msg, GLuint flags )
325 {
326 fprintf(stderr, "%s(%x): %s%s%s%s%s%s\n",
327 msg,
328 (int)flags,
329 (flags & I810_XYZW_BIT) ? " xyzw," : "",
330 (flags & I810_RGBA_BIT) ? " rgba," : "",
331 (flags & I810_SPEC_BIT) ? " spec," : "",
332 (flags & I810_FOG_BIT) ? " fog," : "",
333 (flags & I810_TEX0_BIT) ? " tex-0," : "",
334 (flags & I810_TEX1_BIT) ? " tex-1," : "");
335 }
336
337
338
339 void i810CheckTexSizes( GLcontext *ctx )
340 {
341 TNLcontext *tnl = TNL_CONTEXT(ctx);
342 i810ContextPtr imesa = I810_CONTEXT( ctx );
343
344 if (!setup_tab[imesa->SetupIndex].check_tex_sizes(ctx)) {
345 /* Invalidate stored verts
346 */
347 imesa->SetupNewInputs = ~0;
348 imesa->SetupIndex |= I810_PTEX_BIT;
349
350 if (!imesa->Fallback &&
351 !(ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) {
352 tnl->Driver.Render.Interp = setup_tab[imesa->SetupIndex].interp;
353 tnl->Driver.Render.CopyPV = setup_tab[imesa->SetupIndex].copy_pv;
354 }
355 if (imesa->Fallback) {
356 tnl->Driver.Render.Start(ctx);
357 }
358 }
359 }
360
361 void i810BuildVertices( GLcontext *ctx,
362 GLuint start,
363 GLuint count,
364 GLuint newinputs )
365 {
366 i810ContextPtr imesa = I810_CONTEXT( ctx );
367 GLuint stride = imesa->vertex_size * sizeof(int);
368 GLubyte *v = ((GLubyte *)imesa->verts + (start * stride));
369
370 if (0) fprintf(stderr, "%s\n", __FUNCTION__);
371
372 newinputs |= imesa->SetupNewInputs;
373 imesa->SetupNewInputs = 0;
374
375 if (!newinputs)
376 return;
377
378 if (newinputs & VERT_BIT_POS) {
379 setup_tab[imesa->SetupIndex].emit( ctx, start, count, v, stride );
380 } else {
381 GLuint ind = 0;
382
383 if (newinputs & VERT_BIT_COLOR0)
384 ind |= I810_RGBA_BIT;
385
386 if (newinputs & VERT_BIT_COLOR1)
387 ind |= I810_SPEC_BIT;
388
389 if (newinputs & VERT_BIT_TEX0)
390 ind |= I810_TEX0_BIT;
391
392 if (newinputs & VERT_BIT_TEX1)
393 ind |= I810_TEX1_BIT;
394
395 if (newinputs & VERT_BIT_FOG)
396 ind |= I810_FOG_BIT;
397
398 if (imesa->SetupIndex & I810_PTEX_BIT)
399 ind = ~0;
400
401 ind &= imesa->SetupIndex;
402
403 if (ind) {
404 setup_tab[ind].emit( ctx, start, count, v, stride );
405 }
406 }
407 }
408
409 void i810ChooseVertexState( GLcontext *ctx )
410 {
411 TNLcontext *tnl = TNL_CONTEXT(ctx);
412 i810ContextPtr imesa = I810_CONTEXT( ctx );
413 GLuint ind = I810_XYZW_BIT|I810_RGBA_BIT;
414
415 if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
416 ind |= I810_SPEC_BIT;
417
418 if (ctx->Fog.Enabled)
419 ind |= I810_FOG_BIT;
420
421 if (ctx->Texture._EnabledUnits & 0x2)
422 /* unit 1 enabled */
423 ind |= I810_TEX1_BIT|I810_TEX0_BIT;
424 else if (ctx->Texture._EnabledUnits & 0x1)
425 /* unit 0 enabled */
426 ind |= I810_TEX0_BIT;
427
428 imesa->SetupIndex = ind;
429
430 if (I810_DEBUG & (DEBUG_VERTS|DEBUG_STATE))
431 i810PrintSetupFlags( __FUNCTION__, ind );
432
433 if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED)) {
434 tnl->Driver.Render.Interp = i810_interp_extras;
435 tnl->Driver.Render.CopyPV = i810_copy_pv_extras;
436 } else {
437 tnl->Driver.Render.Interp = setup_tab[ind].interp;
438 tnl->Driver.Render.CopyPV = setup_tab[ind].copy_pv;
439 }
440
441 if (setup_tab[ind].vertex_format != imesa->Setup[I810_CTXREG_VF]) {
442 I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
443 imesa->Setup[I810_CTXREG_VF] = setup_tab[ind].vertex_format;
444 imesa->vertex_size = setup_tab[ind].vertex_size;
445 }
446 }
447
448
449
450 void *i810_emit_contiguous_verts( GLcontext *ctx,
451 GLuint start,
452 GLuint count,
453 void *dest )
454 {
455 i810ContextPtr imesa = I810_CONTEXT(ctx);
456 GLuint stride = imesa->vertex_size * 4;
457 setup_tab[imesa->SetupIndex].emit( ctx, start, count, dest, stride );
458 return (void *)((char *)dest + stride * (count - start));
459 }
460
461
462
463 void i810InitVB( GLcontext *ctx )
464 {
465 i810ContextPtr imesa = I810_CONTEXT(ctx);
466 GLuint size = TNL_CONTEXT(ctx)->vb.Size;
467
468 imesa->verts = (GLubyte *)ALIGN_MALLOC(size * 4 * 16, 32);
469
470 {
471 static int firsttime = 1;
472 if (firsttime) {
473 init_setup_tab();
474 firsttime = 0;
475 }
476 }
477 }
478
479
480 void i810FreeVB( GLcontext *ctx )
481 {
482 i810ContextPtr imesa = I810_CONTEXT(ctx);
483 if (imesa->verts) {
484 ALIGN_FREE(imesa->verts);
485 imesa->verts = 0;
486 }
487 }