2 * GLX Hardware Device Driver for Intel i810
3 * Copyright (C) 1999 Keith Whitwell
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:
12 * The above copyright notice and this permission notice shall be included
13 * in all copies or substantial portions of the Software.
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.
23 * Adapted for use on the I830M:
24 * Jeff Hartmann <jhartmann@2d3d.com>
26 /* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_vb.c,v 1.5 2002/12/10 01:26:54 dawes Exp $ */
34 #include "swrast_setup/swrast_setup.h"
35 #include "tnl/t_context.h"
37 #include "i830_screen.h"
40 #include "i830_context.h"
42 #include "i830_ioctl.h"
43 #include "i830_tris.h"
44 #include "i830_state.h"
46 #define I830_TEX1_BIT 0x1
47 #define I830_TEX0_BIT 0x2
48 #define I830_RGBA_BIT 0x4
49 #define I830_SPEC_BIT 0x8
50 #define I830_FOG_BIT 0x10
51 #define I830_XYZW_BIT 0x20
52 #define I830_PTEX_BIT 0x40
53 #define I830_MAX_SETUP 0x80
56 void (*emit
)( GLcontext
*, GLuint
, GLuint
, void *, GLuint
);
59 GLboolean (*check_tex_sizes
)( GLcontext
*ctx
);
62 } setup_tab
[I830_MAX_SETUP
];
64 #define TINY_VERTEX_FORMAT (STATE3D_VERTEX_FORMAT_CMD | \
65 VRTX_TEX_COORD_COUNT(0) | \
69 #define NOTEX_VERTEX_FORMAT (STATE3D_VERTEX_FORMAT_CMD | \
70 VRTX_TEX_COORD_COUNT(0) | \
75 #define TEX0_VERTEX_FORMAT (STATE3D_VERTEX_FORMAT_CMD | \
76 VRTX_TEX_COORD_COUNT(1) | \
81 #define TEX1_VERTEX_FORMAT (STATE3D_VERTEX_FORMAT_CMD | \
82 VRTX_TEX_COORD_COUNT(2) | \
88 /* I'm cheating here hardcore : if bit 31 is set I know to emit
89 * a vf2 state == TEXCOORDFMT_3D. We never mix 2d/3d texcoords,
90 * so this solution works for now.
93 #define PROJ_TEX1_VERTEX_FORMAT ((1<<31) | \
94 STATE3D_VERTEX_FORMAT_CMD | \
95 VRTX_TEX_COORD_COUNT(2) | \
100 /* Might want to do these later */
101 #define TEX2_VERTEX_FORMAT 0
102 #define TEX3_VERTEX_FORMAT 0
103 #define PROJ_TEX3_VERTEX_FORMAT 0
105 #define DO_XYZW (IND & I830_XYZW_BIT)
106 #define DO_RGBA (IND & I830_RGBA_BIT)
107 #define DO_SPEC (IND & I830_SPEC_BIT)
108 #define DO_FOG (IND & I830_FOG_BIT)
109 #define DO_TEX0 (IND & I830_TEX0_BIT)
110 #define DO_TEX1 (IND & I830_TEX1_BIT)
113 #define DO_PTEX (IND & I830_PTEX_BIT)
115 #define VERTEX i830Vertex
116 #define VERTEX_COLOR i830_color_t
117 #define GET_VIEWPORT_MAT() I830_CONTEXT(ctx)->ViewportMatrix.m
118 #define GET_TEXSOURCE(n) n
119 #define GET_VERTEX_FORMAT() I830_CONTEXT(ctx)->vertex_format
120 #define GET_VERTEX_STORE() ((GLubyte *)I830_CONTEXT(ctx)->verts)
121 #define GET_VERTEX_SIZE() I830_CONTEXT(ctx)->vertex_size * sizeof(int)
122 #define INVALIDATE_STORED_VERTICES()
124 #define HAVE_HW_VIEWPORT 0
125 #define HAVE_HW_DIVIDE 0
126 #define HAVE_RGBA_COLOR 0
127 #define HAVE_TINY_VERTICES 1
128 #define HAVE_NOTEX_VERTICES 1
129 #define HAVE_TEX0_VERTICES 1
130 #define HAVE_TEX1_VERTICES 1
131 #define HAVE_TEX2_VERTICES 0
132 #define HAVE_TEX3_VERTICES 0
133 #define HAVE_PTEX_VERTICES 1
135 #define UNVIEWPORT_VARS GLfloat h = I830_CONTEXT(ctx)->driDrawable->h
136 #define UNVIEWPORT_X(x) x - SUBPIXEL_X
137 #define UNVIEWPORT_Y(y) - y + h + SUBPIXEL_Y
138 #define UNVIEWPORT_Z(z) z * (float)I830_CONTEXT(ctx)->ClearDepth
140 #define PTEX_FALLBACK() FALLBACK(I830_CONTEXT(ctx), I830_FALLBACK_TEXTURE, 1)
142 #define INTERP_VERTEX setup_tab[I830_CONTEXT(ctx)->SetupIndex].interp
143 #define COPY_PV_VERTEX setup_tab[I830_CONTEXT(ctx)->SetupIndex].copy_pv
146 /***********************************************************************
147 * Generate pv-copying and translation functions *
148 ***********************************************************************/
150 #define TAG(x) i830_##x
151 #include "tnl_dd/t_dd_vb.c"
153 /***********************************************************************
154 * Generate vertex emit and interp functions *
155 ***********************************************************************/
157 #define IND (I830_XYZW_BIT|I830_RGBA_BIT)
158 #define TAG(x) x##_wg
159 #include "tnl_dd/t_dd_vbtmp.h"
161 #define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_SPEC_BIT)
162 #define TAG(x) x##_wgs
163 #include "tnl_dd/t_dd_vbtmp.h"
165 #define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_TEX0_BIT)
166 #define TAG(x) x##_wgt0
167 #include "tnl_dd/t_dd_vbtmp.h"
169 #define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_TEX0_BIT|I830_TEX1_BIT)
170 #define TAG(x) x##_wgt0t1
171 #include "tnl_dd/t_dd_vbtmp.h"
173 #define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_TEX0_BIT|I830_PTEX_BIT)
174 #define TAG(x) x##_wgpt0
175 #include "tnl_dd/t_dd_vbtmp.h"
177 #define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_SPEC_BIT|I830_TEX0_BIT)
178 #define TAG(x) x##_wgst0
179 #include "tnl_dd/t_dd_vbtmp.h"
181 #define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_SPEC_BIT|I830_TEX0_BIT|\
183 #define TAG(x) x##_wgst0t1
184 #include "tnl_dd/t_dd_vbtmp.h"
186 #define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_SPEC_BIT|I830_TEX0_BIT|\
188 #define TAG(x) x##_wgspt0
189 #include "tnl_dd/t_dd_vbtmp.h"
191 #define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT)
192 #define TAG(x) x##_wgf
193 #include "tnl_dd/t_dd_vbtmp.h"
195 #define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT)
196 #define TAG(x) x##_wgfs
197 #include "tnl_dd/t_dd_vbtmp.h"
199 #define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_TEX0_BIT)
200 #define TAG(x) x##_wgft0
201 #include "tnl_dd/t_dd_vbtmp.h"
203 #define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_TEX0_BIT|\
205 #define TAG(x) x##_wgft0t1
206 #include "tnl_dd/t_dd_vbtmp.h"
208 #define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_TEX0_BIT|\
210 #define TAG(x) x##_wgfpt0
211 #include "tnl_dd/t_dd_vbtmp.h"
213 #define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT|\
215 #define TAG(x) x##_wgfst0
216 #include "tnl_dd/t_dd_vbtmp.h"
218 #define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT|\
219 I830_TEX0_BIT|I830_TEX1_BIT)
220 #define TAG(x) x##_wgfst0t1
221 #include "tnl_dd/t_dd_vbtmp.h"
223 #define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT|\
224 I830_TEX0_BIT|I830_PTEX_BIT)
225 #define TAG(x) x##_wgfspt0
226 #include "tnl_dd/t_dd_vbtmp.h"
228 #define IND (I830_TEX0_BIT)
229 #define TAG(x) x##_t0
230 #include "tnl_dd/t_dd_vbtmp.h"
232 #define IND (I830_TEX0_BIT|I830_TEX1_BIT)
233 #define TAG(x) x##_t0t1
234 #include "tnl_dd/t_dd_vbtmp.h"
236 #define IND (I830_FOG_BIT)
238 #include "tnl_dd/t_dd_vbtmp.h"
240 #define IND (I830_FOG_BIT|I830_TEX0_BIT)
241 #define TAG(x) x##_ft0
242 #include "tnl_dd/t_dd_vbtmp.h"
244 #define IND (I830_FOG_BIT|I830_TEX0_BIT|I830_TEX1_BIT)
245 #define TAG(x) x##_ft0t1
246 #include "tnl_dd/t_dd_vbtmp.h"
248 #define IND (I830_RGBA_BIT)
250 #include "tnl_dd/t_dd_vbtmp.h"
252 #define IND (I830_RGBA_BIT|I830_SPEC_BIT)
253 #define TAG(x) x##_gs
254 #include "tnl_dd/t_dd_vbtmp.h"
256 #define IND (I830_RGBA_BIT|I830_TEX0_BIT)
257 #define TAG(x) x##_gt0
258 #include "tnl_dd/t_dd_vbtmp.h"
260 #define IND (I830_RGBA_BIT|I830_TEX0_BIT|I830_TEX1_BIT)
261 #define TAG(x) x##_gt0t1
262 #include "tnl_dd/t_dd_vbtmp.h"
264 #define IND (I830_RGBA_BIT|I830_SPEC_BIT|I830_TEX0_BIT)
265 #define TAG(x) x##_gst0
266 #include "tnl_dd/t_dd_vbtmp.h"
268 #define IND (I830_RGBA_BIT|I830_SPEC_BIT|I830_TEX0_BIT|I830_TEX1_BIT)
269 #define TAG(x) x##_gst0t1
270 #include "tnl_dd/t_dd_vbtmp.h"
272 #define IND (I830_RGBA_BIT|I830_FOG_BIT)
273 #define TAG(x) x##_gf
274 #include "tnl_dd/t_dd_vbtmp.h"
276 #define IND (I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT)
277 #define TAG(x) x##_gfs
278 #include "tnl_dd/t_dd_vbtmp.h"
280 #define IND (I830_RGBA_BIT|I830_FOG_BIT|I830_TEX0_BIT)
281 #define TAG(x) x##_gft0
282 #include "tnl_dd/t_dd_vbtmp.h"
284 #define IND (I830_RGBA_BIT|I830_FOG_BIT|I830_TEX0_BIT|I830_TEX1_BIT)
285 #define TAG(x) x##_gft0t1
286 #include "tnl_dd/t_dd_vbtmp.h"
288 #define IND (I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT|I830_TEX0_BIT)
289 #define TAG(x) x##_gfst0
290 #include "tnl_dd/t_dd_vbtmp.h"
292 #define IND (I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT|I830_TEX0_BIT|\
294 #define TAG(x) x##_gfst0t1
295 #include "tnl_dd/t_dd_vbtmp.h"
297 /* Add functions for proj texturing for t0 and t1 */
298 #define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_TEX0_BIT|I830_TEX1_BIT|\
300 #define TAG(x) x##_wgpt0t1
301 #include "tnl_dd/t_dd_vbtmp.h"
303 #define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_SPEC_BIT|I830_TEX0_BIT|\
304 I830_TEX1_BIT|I830_PTEX_BIT)
305 #define TAG(x) x##_wgspt0t1
306 #include "tnl_dd/t_dd_vbtmp.h"
308 #define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_TEX0_BIT|\
309 I830_TEX1_BIT|I830_PTEX_BIT)
310 #define TAG(x) x##_wgfpt0t1
311 #include "tnl_dd/t_dd_vbtmp.h"
313 #define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT|\
314 I830_TEX1_BIT|I830_TEX0_BIT|I830_PTEX_BIT)
315 #define TAG(x) x##_wgfspt0t1
316 #include "tnl_dd/t_dd_vbtmp.h"
319 static void init_setup_tab( void )
354 /* Add proj texturing on t1 */
363 void i830PrintSetupFlags(char *msg
, GLuint flags
)
365 fprintf(stderr
, "%s(%x): %s%s%s%s%s%s%s\n",
368 (flags
& I830_XYZW_BIT
) ? " xyzw," : "",
369 (flags
& I830_RGBA_BIT
) ? " rgba," : "",
370 (flags
& I830_SPEC_BIT
) ? " spec," : "",
371 (flags
& I830_FOG_BIT
) ? " fog," : "",
372 (flags
& I830_TEX0_BIT
) ? " tex-0," : "",
373 (flags
& I830_TEX1_BIT
) ? " tex-1," : "",
374 (flags
& I830_PTEX_BIT
) ? " ptex," : "");
377 void i830CheckTexSizes( GLcontext
*ctx
)
379 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
380 i830ContextPtr imesa
= I830_CONTEXT( ctx
);
382 if (!setup_tab
[imesa
->SetupIndex
].check_tex_sizes(ctx
)) {
383 int ind
= imesa
->SetupIndex
|= I830_PTEX_BIT
;
385 if(setup_tab
[ind
].vertex_format
!= imesa
->vertex_format
) {
386 int vfmt
= setup_tab
[ind
].vertex_format
;
388 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
389 imesa
->Setup
[I830_CTXREG_VF
] = ~(1<<31) & vfmt
;
391 if (vfmt
& (1<<31)) {
393 imesa
->Setup
[I830_CTXREG_VF2
] = (STATE3D_VERTEX_FORMAT_2_CMD
|
394 VRTX_TEX_SET_0_FMT(TEXCOORDFMT_3D
) |
395 VRTX_TEX_SET_1_FMT(TEXCOORDFMT_3D
) |
396 VRTX_TEX_SET_2_FMT(TEXCOORDFMT_3D
) |
397 VRTX_TEX_SET_3_FMT(TEXCOORDFMT_3D
));
398 i830UpdateTexUnitProj( ctx
, 0, GL_TRUE
);
399 i830UpdateTexUnitProj( ctx
, 1, GL_TRUE
);
402 /* Normal texturing */
403 imesa
->Setup
[I830_CTXREG_VF2
] = (STATE3D_VERTEX_FORMAT_2_CMD
|
404 VRTX_TEX_SET_0_FMT(TEXCOORDFMT_2D
) |
405 VRTX_TEX_SET_1_FMT(TEXCOORDFMT_2D
) |
406 VRTX_TEX_SET_2_FMT(TEXCOORDFMT_2D
) |
407 VRTX_TEX_SET_3_FMT(TEXCOORDFMT_2D
));
408 i830UpdateTexUnitProj( ctx
, 0, GL_FALSE
);
409 i830UpdateTexUnitProj( ctx
, 1, GL_FALSE
);
411 imesa
->vertex_format
= vfmt
;
412 imesa
->vertex_size
= setup_tab
[ind
].vertex_size
;
415 if (!imesa
->Fallback
&&
416 !(ctx
->_TriangleCaps
& (DD_TRI_LIGHT_TWOSIDE
|DD_TRI_UNFILLED
))) {
417 tnl
->Driver
.Render
.Interp
= setup_tab
[imesa
->SetupIndex
].interp
;
418 tnl
->Driver
.Render
.CopyPV
= setup_tab
[imesa
->SetupIndex
].copy_pv
;
423 void i830BuildVertices( GLcontext
*ctx
,
428 i830ContextPtr imesa
= I830_CONTEXT( ctx
);
429 GLuint stride
= imesa
->vertex_size
* sizeof(int);
430 GLubyte
*v
= ((GLubyte
*) imesa
->verts
+ (start
* stride
));
432 if (0) fprintf(stderr
, "%s\n", __FUNCTION__
);
434 newinputs
|= imesa
->SetupNewInputs
;
435 imesa
->SetupNewInputs
= 0;
440 if (newinputs
& VERT_BIT_POS
) {
441 setup_tab
[imesa
->SetupIndex
].emit( ctx
, start
, count
, v
, stride
);
445 if (newinputs
& VERT_BIT_COLOR0
)
446 ind
|= I830_RGBA_BIT
;
448 if (newinputs
& VERT_BIT_COLOR1
)
449 ind
|= I830_SPEC_BIT
;
451 if (newinputs
& VERT_BIT_TEX0
)
452 ind
|= I830_TEX0_BIT
;
454 if (newinputs
& VERT_BIT_TEX1
)
455 ind
|= I830_TEX1_BIT
;
457 if (newinputs
& VERT_BIT_FOG
)
461 if (imesa
->SetupIndex
& I830_PTEX_BIT
)
465 ind
&= imesa
->SetupIndex
;
468 setup_tab
[ind
].emit( ctx
, start
, count
, v
, stride
);
473 void i830ChooseVertexState( GLcontext
*ctx
)
475 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
476 i830ContextPtr imesa
= I830_CONTEXT( ctx
);
477 GLuint ind
= I830_XYZW_BIT
|I830_RGBA_BIT
;
479 if (ctx
->_TriangleCaps
& DD_SEPARATE_SPECULAR
)
480 ind
|= I830_SPEC_BIT
;
482 if (ctx
->Fog
.Enabled
)
485 if (ctx
->Texture
._EnabledUnits
& 0x2)
487 ind
|= I830_TEX1_BIT
|I830_TEX0_BIT
;
488 else if (ctx
->Texture
._EnabledUnits
& 0x1)
490 ind
|= I830_TEX0_BIT
;
492 imesa
->SetupIndex
= ind
;
494 if (I830_DEBUG
& (DEBUG_VERTS
|DEBUG_STATE
))
495 i830PrintSetupFlags( __FUNCTION__
, ind
);
497 if (ctx
->_TriangleCaps
& (DD_TRI_LIGHT_TWOSIDE
|DD_TRI_UNFILLED
)) {
498 tnl
->Driver
.Render
.Interp
= i830_interp_extras
;
499 tnl
->Driver
.Render
.CopyPV
= i830_copy_pv_extras
;
501 tnl
->Driver
.Render
.Interp
= setup_tab
[ind
].interp
;
502 tnl
->Driver
.Render
.CopyPV
= setup_tab
[ind
].copy_pv
;
505 if (setup_tab
[ind
].vertex_format
!= imesa
->vertex_format
) {
506 int vfmt
= setup_tab
[ind
].vertex_format
;
508 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
509 imesa
->Setup
[I830_CTXREG_VF
] = ~(1<<31) & vfmt
;
511 if (vfmt
& (1<<31)) {
513 imesa
->Setup
[I830_CTXREG_VF2
] = (STATE3D_VERTEX_FORMAT_2_CMD
|
514 VRTX_TEX_SET_0_FMT(TEXCOORDFMT_3D
) |
515 VRTX_TEX_SET_1_FMT(TEXCOORDFMT_3D
) |
516 VRTX_TEX_SET_2_FMT(TEXCOORDFMT_3D
) |
517 VRTX_TEX_SET_3_FMT(TEXCOORDFMT_3D
));
518 i830UpdateTexUnitProj( ctx
, 0, GL_TRUE
);
519 i830UpdateTexUnitProj( ctx
, 1, GL_TRUE
);
521 /* Normal texturing */
522 imesa
->Setup
[I830_CTXREG_VF2
] = (STATE3D_VERTEX_FORMAT_2_CMD
|
523 VRTX_TEX_SET_0_FMT(TEXCOORDFMT_2D
) |
524 VRTX_TEX_SET_1_FMT(TEXCOORDFMT_2D
) |
525 VRTX_TEX_SET_2_FMT(TEXCOORDFMT_2D
) |
526 VRTX_TEX_SET_3_FMT(TEXCOORDFMT_2D
));
527 i830UpdateTexUnitProj( ctx
, 0, GL_FALSE
);
528 i830UpdateTexUnitProj( ctx
, 1, GL_FALSE
);
530 imesa
->vertex_format
= vfmt
;
531 imesa
->vertex_size
= setup_tab
[ind
].vertex_size
;
537 void *i830_emit_contiguous_verts( GLcontext
*ctx
,
542 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
543 GLuint stride
= imesa
->vertex_size
* 4;
544 setup_tab
[imesa
->SetupIndex
].emit( ctx
, start
, count
, dest
, stride
);
545 return (void *)((char *)dest
+ stride
* (count
- start
));
550 void i830InitVB( GLcontext
*ctx
)
552 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
553 GLuint size
= TNL_CONTEXT(ctx
)->vb
.Size
;
555 imesa
->verts
= (char *)ALIGN_MALLOC(size
* 4 * 16, 32);
558 static int firsttime
= 1;
567 void i830FreeVB( GLcontext
*ctx
)
569 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
571 ALIGN_FREE(imesa
->verts
);