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.
33 #include "swrast_setup/swrast_setup.h"
34 #include "tnl/t_context.h"
36 #include "i810screen.h"
39 #include "i810context.h"
41 #include "i810ioctl.h"
43 #include "i810state.h"
46 #define I810_TEX1_BIT 0x1
47 #define I810_TEX0_BIT 0x2
48 #define I810_RGBA_BIT 0x4
49 #define I810_SPEC_BIT 0x8
50 #define I810_FOG_BIT 0x10
51 #define I810_XYZW_BIT 0x20
52 #define I810_PTEX_BIT 0x40
53 #define I810_MAX_SETUP 0x80
56 void (*emit
)( GLcontext
*, GLuint
, GLuint
, void *, GLuint
);
57 tnl_interp_func interp
;
58 tnl_copy_pv_func copy_pv
;
59 GLboolean (*check_tex_sizes
)( GLcontext
*ctx
);
62 } setup_tab
[I810_MAX_SETUP
];
64 #define TINY_VERTEX_FORMAT (GFX_OP_VERTEX_FMT | \
65 VF_TEXCOORD_COUNT_0 | \
69 #define NOTEX_VERTEX_FORMAT (GFX_OP_VERTEX_FMT | \
70 VF_TEXCOORD_COUNT_0 | \
71 VF_SPEC_FOG_ENABLE | \
75 #define TEX0_VERTEX_FORMAT (GFX_OP_VERTEX_FMT | \
76 VF_TEXCOORD_COUNT_1 | \
77 VF_SPEC_FOG_ENABLE | \
81 #define TEX1_VERTEX_FORMAT (GFX_OP_VERTEX_FMT | \
82 VF_TEXCOORD_COUNT_2 | \
83 VF_SPEC_FOG_ENABLE | \
87 #define PROJ_TEX1_VERTEX_FORMAT 0
88 #define TEX2_VERTEX_FORMAT 0
89 #define TEX3_VERTEX_FORMAT 0
90 #define PROJ_TEX3_VERTEX_FORMAT 0
92 #define DO_XYZW (IND & I810_XYZW_BIT)
93 #define DO_RGBA (IND & I810_RGBA_BIT)
94 #define DO_SPEC (IND & I810_SPEC_BIT)
95 #define DO_FOG (IND & I810_FOG_BIT)
96 #define DO_TEX0 (IND & I810_TEX0_BIT)
97 #define DO_TEX1 (IND & I810_TEX1_BIT)
100 #define DO_PTEX (IND & I810_PTEX_BIT)
102 #define VERTEX i810Vertex
103 #define VERTEX_COLOR i810_color_t
104 #define GET_VIEWPORT_MAT() I810_CONTEXT(ctx)->ViewportMatrix.m
105 #define GET_TEXSOURCE(n) n
106 #define GET_VERTEX_FORMAT() I810_CONTEXT(ctx)->Setup[I810_CTXREG_VF]
107 #define GET_VERTEX_STORE() I810_CONTEXT(ctx)->verts
108 #define GET_VERTEX_SIZE() I810_CONTEXT(ctx)->vertex_size * sizeof(GLuint)
109 #define INVALIDATE_STORED_VERTICES()
111 #define HAVE_HW_VIEWPORT 0
112 #define HAVE_HW_DIVIDE 0
113 #define HAVE_RGBA_COLOR 0
114 #define HAVE_TINY_VERTICES 1
115 #define HAVE_NOTEX_VERTICES 1
116 #define HAVE_TEX0_VERTICES 1
117 #define HAVE_TEX1_VERTICES 1
118 #define HAVE_TEX2_VERTICES 0
119 #define HAVE_TEX3_VERTICES 0
120 #define HAVE_PTEX_VERTICES 0
122 #define UNVIEWPORT_VARS GLfloat h = I810_CONTEXT(ctx)->driDrawable->h
123 #define UNVIEWPORT_X(x) x - SUBPIXEL_X
124 #define UNVIEWPORT_Y(y) - y + h + SUBPIXEL_Y
125 #define UNVIEWPORT_Z(z) z * (float)0xffff
127 #define PTEX_FALLBACK() FALLBACK(I810_CONTEXT(ctx), I810_FALLBACK_TEXTURE, 1)
129 #define INTERP_VERTEX setup_tab[I810_CONTEXT(ctx)->SetupIndex].interp
130 #define COPY_PV_VERTEX setup_tab[I810_CONTEXT(ctx)->SetupIndex].copy_pv
133 /***********************************************************************
134 * Generate pv-copying and translation functions *
135 ***********************************************************************/
137 #define TAG(x) i810_##x
138 #include "tnl_dd/t_dd_vb.c"
140 /***********************************************************************
141 * Generate vertex emit and interp functions *
142 ***********************************************************************/
145 #define IND (I810_XYZW_BIT|I810_RGBA_BIT)
146 #define TAG(x) x##_wg
147 #include "tnl_dd/t_dd_vbtmp.h"
149 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_SPEC_BIT)
150 #define TAG(x) x##_wgs
151 #include "tnl_dd/t_dd_vbtmp.h"
153 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_TEX0_BIT)
154 #define TAG(x) x##_wgt0
155 #include "tnl_dd/t_dd_vbtmp.h"
157 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_TEX0_BIT|I810_TEX1_BIT)
158 #define TAG(x) x##_wgt0t1
159 #include "tnl_dd/t_dd_vbtmp.h"
161 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_TEX0_BIT|I810_PTEX_BIT)
162 #define TAG(x) x##_wgpt0
163 #include "tnl_dd/t_dd_vbtmp.h"
165 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT)
166 #define TAG(x) x##_wgst0
167 #include "tnl_dd/t_dd_vbtmp.h"
169 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT|\
171 #define TAG(x) x##_wgst0t1
172 #include "tnl_dd/t_dd_vbtmp.h"
174 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT|\
176 #define TAG(x) x##_wgspt0
177 #include "tnl_dd/t_dd_vbtmp.h"
179 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT)
180 #define TAG(x) x##_wgf
181 #include "tnl_dd/t_dd_vbtmp.h"
183 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT)
184 #define TAG(x) x##_wgfs
185 #include "tnl_dd/t_dd_vbtmp.h"
187 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT)
188 #define TAG(x) x##_wgft0
189 #include "tnl_dd/t_dd_vbtmp.h"
191 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT|\
193 #define TAG(x) x##_wgft0t1
194 #include "tnl_dd/t_dd_vbtmp.h"
196 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT|\
198 #define TAG(x) x##_wgfpt0
199 #include "tnl_dd/t_dd_vbtmp.h"
201 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT|\
203 #define TAG(x) x##_wgfst0
204 #include "tnl_dd/t_dd_vbtmp.h"
206 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT|\
207 I810_TEX0_BIT|I810_TEX1_BIT)
208 #define TAG(x) x##_wgfst0t1
209 #include "tnl_dd/t_dd_vbtmp.h"
211 #define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT|\
212 I810_TEX0_BIT|I810_PTEX_BIT)
213 #define TAG(x) x##_wgfspt0
214 #include "tnl_dd/t_dd_vbtmp.h"
216 #define IND (I810_TEX0_BIT)
217 #define TAG(x) x##_t0
218 #include "tnl_dd/t_dd_vbtmp.h"
220 #define IND (I810_TEX0_BIT|I810_TEX1_BIT)
221 #define TAG(x) x##_t0t1
222 #include "tnl_dd/t_dd_vbtmp.h"
224 #define IND (I810_FOG_BIT)
226 #include "tnl_dd/t_dd_vbtmp.h"
228 #define IND (I810_FOG_BIT|I810_TEX0_BIT)
229 #define TAG(x) x##_ft0
230 #include "tnl_dd/t_dd_vbtmp.h"
232 #define IND (I810_FOG_BIT|I810_TEX0_BIT|I810_TEX1_BIT)
233 #define TAG(x) x##_ft0t1
234 #include "tnl_dd/t_dd_vbtmp.h"
236 #define IND (I810_RGBA_BIT)
238 #include "tnl_dd/t_dd_vbtmp.h"
240 #define IND (I810_RGBA_BIT|I810_SPEC_BIT)
241 #define TAG(x) x##_gs
242 #include "tnl_dd/t_dd_vbtmp.h"
244 #define IND (I810_RGBA_BIT|I810_TEX0_BIT)
245 #define TAG(x) x##_gt0
246 #include "tnl_dd/t_dd_vbtmp.h"
248 #define IND (I810_RGBA_BIT|I810_TEX0_BIT|I810_TEX1_BIT)
249 #define TAG(x) x##_gt0t1
250 #include "tnl_dd/t_dd_vbtmp.h"
252 #define IND (I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT)
253 #define TAG(x) x##_gst0
254 #include "tnl_dd/t_dd_vbtmp.h"
256 #define IND (I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT|I810_TEX1_BIT)
257 #define TAG(x) x##_gst0t1
258 #include "tnl_dd/t_dd_vbtmp.h"
260 #define IND (I810_RGBA_BIT|I810_FOG_BIT)
261 #define TAG(x) x##_gf
262 #include "tnl_dd/t_dd_vbtmp.h"
264 #define IND (I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT)
265 #define TAG(x) x##_gfs
266 #include "tnl_dd/t_dd_vbtmp.h"
268 #define IND (I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT)
269 #define TAG(x) x##_gft0
270 #include "tnl_dd/t_dd_vbtmp.h"
272 #define IND (I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT|I810_TEX1_BIT)
273 #define TAG(x) x##_gft0t1
274 #include "tnl_dd/t_dd_vbtmp.h"
276 #define IND (I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT|I810_TEX0_BIT)
277 #define TAG(x) x##_gfst0
278 #include "tnl_dd/t_dd_vbtmp.h"
280 #define IND (I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT|I810_TEX0_BIT|\
282 #define TAG(x) x##_gfst0t1
283 #include "tnl_dd/t_dd_vbtmp.h"
286 static void init_setup_tab( void )
325 static void i810PrintSetupFlags(const char *msg
, GLuint flags
)
327 fprintf(stderr
, "%s(%x): %s%s%s%s%s%s\n",
330 (flags
& I810_XYZW_BIT
) ? " xyzw," : "",
331 (flags
& I810_RGBA_BIT
) ? " rgba," : "",
332 (flags
& I810_SPEC_BIT
) ? " spec," : "",
333 (flags
& I810_FOG_BIT
) ? " fog," : "",
334 (flags
& I810_TEX0_BIT
) ? " tex-0," : "",
335 (flags
& I810_TEX1_BIT
) ? " tex-1," : "");
340 void i810CheckTexSizes( GLcontext
*ctx
)
342 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
343 i810ContextPtr imesa
= I810_CONTEXT( ctx
);
345 if (!setup_tab
[imesa
->SetupIndex
].check_tex_sizes(ctx
)) {
346 /* Invalidate stored verts
348 imesa
->SetupNewInputs
= ~0;
349 imesa
->SetupIndex
|= I810_PTEX_BIT
;
351 if (!imesa
->Fallback
&&
352 !(ctx
->_TriangleCaps
& (DD_TRI_LIGHT_TWOSIDE
|DD_TRI_UNFILLED
))) {
353 tnl
->Driver
.Render
.Interp
= setup_tab
[imesa
->SetupIndex
].interp
;
354 tnl
->Driver
.Render
.CopyPV
= setup_tab
[imesa
->SetupIndex
].copy_pv
;
356 if (imesa
->Fallback
) {
357 tnl
->Driver
.Render
.Start(ctx
);
362 void i810BuildVertices( GLcontext
*ctx
,
367 i810ContextPtr imesa
= I810_CONTEXT( ctx
);
368 GLuint stride
= imesa
->vertex_size
* sizeof(int);
369 GLubyte
*v
= ((GLubyte
*)imesa
->verts
+ (start
* stride
));
371 if (0) fprintf(stderr
, "%s\n", __FUNCTION__
);
373 newinputs
|= imesa
->SetupNewInputs
;
374 imesa
->SetupNewInputs
= 0;
379 if (newinputs
& VERT_BIT_POS
) {
380 setup_tab
[imesa
->SetupIndex
].emit( ctx
, start
, count
, v
, stride
);
384 if (newinputs
& VERT_BIT_COLOR0
)
385 ind
|= I810_RGBA_BIT
;
387 if (newinputs
& VERT_BIT_COLOR1
)
388 ind
|= I810_SPEC_BIT
;
390 if (newinputs
& VERT_BIT_TEX0
)
391 ind
|= I810_TEX0_BIT
;
393 if (newinputs
& VERT_BIT_TEX1
)
394 ind
|= I810_TEX1_BIT
;
396 if (newinputs
& VERT_BIT_FOG
)
399 if (imesa
->SetupIndex
& I810_PTEX_BIT
)
402 ind
&= imesa
->SetupIndex
;
405 setup_tab
[ind
].emit( ctx
, start
, count
, v
, stride
);
410 void i810ChooseVertexState( GLcontext
*ctx
)
412 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
413 i810ContextPtr imesa
= I810_CONTEXT( ctx
);
414 GLuint ind
= I810_XYZW_BIT
|I810_RGBA_BIT
;
416 if (ctx
->_TriangleCaps
& DD_SEPARATE_SPECULAR
)
417 ind
|= I810_SPEC_BIT
;
419 if (ctx
->Fog
.Enabled
)
422 if (ctx
->Texture
._EnabledUnits
& 0x2)
424 ind
|= I810_TEX1_BIT
|I810_TEX0_BIT
;
425 else if (ctx
->Texture
._EnabledUnits
& 0x1)
427 ind
|= I810_TEX0_BIT
;
429 imesa
->SetupIndex
= ind
;
431 if (I810_DEBUG
& (DEBUG_VERTS
|DEBUG_STATE
))
432 i810PrintSetupFlags( __FUNCTION__
, ind
);
434 if (ctx
->_TriangleCaps
& (DD_TRI_LIGHT_TWOSIDE
|DD_TRI_UNFILLED
)) {
435 tnl
->Driver
.Render
.Interp
= i810_interp_extras
;
436 tnl
->Driver
.Render
.CopyPV
= i810_copy_pv_extras
;
438 tnl
->Driver
.Render
.Interp
= setup_tab
[ind
].interp
;
439 tnl
->Driver
.Render
.CopyPV
= setup_tab
[ind
].copy_pv
;
442 if (setup_tab
[ind
].vertex_format
!= imesa
->Setup
[I810_CTXREG_VF
]) {
443 I810_STATECHANGE(imesa
, I810_UPLOAD_CTX
);
444 imesa
->Setup
[I810_CTXREG_VF
] = setup_tab
[ind
].vertex_format
;
445 imesa
->vertex_size
= setup_tab
[ind
].vertex_size
;
451 void *i810_emit_contiguous_verts( GLcontext
*ctx
,
456 i810ContextPtr imesa
= I810_CONTEXT(ctx
);
457 GLuint stride
= imesa
->vertex_size
* 4;
458 setup_tab
[imesa
->SetupIndex
].emit( ctx
, start
, count
, dest
, stride
);
459 return (void *)((char *)dest
+ stride
* (count
- start
));
464 void i810InitVB( GLcontext
*ctx
)
466 i810ContextPtr imesa
= I810_CONTEXT(ctx
);
467 GLuint size
= TNL_CONTEXT(ctx
)->vb
.Size
;
469 imesa
->verts
= (GLubyte
*)ALIGN_MALLOC(size
* 4 * 16, 32);
472 static int firsttime
= 1;
481 void i810FreeVB( GLcontext
*ctx
)
483 i810ContextPtr imesa
= I810_CONTEXT(ctx
);
485 ALIGN_FREE(imesa
->verts
);