2 * Copyright 2002 by Alan Hourihane, Sychdyn, North Wales, UK.
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of Alan Hourihane not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission. Alan Hourihane makes no representations
11 * about the suitability of this software for any purpose. It is provided
12 * "as is" without express or implied warranty.
14 * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
22 * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
24 * Trident CyberBladeXP driver.
27 #include "main/glheader.h"
28 #include "main/mtypes.h"
29 #include "main/macros.h"
30 #include "main/colormac.h"
32 #include "swrast_setup/swrast_setup.h"
33 #include "swrast/swrast.h"
34 #include "tnl/t_context.h"
37 #include "trident_context.h"
39 #define TRIDENT_TEX1_BIT 0x1
40 #define TRIDENT_TEX0_BIT 0x2
41 #define TRIDENT_RGBA_BIT 0x4
42 #define TRIDENT_SPEC_BIT 0x8
43 #define TRIDENT_FOG_BIT 0x10
44 #define TRIDENT_XYZW_BIT 0x20
45 #define TRIDENT_PTEX_BIT 0x40
46 #define TRIDENT_MAX_SETUP 0x80
49 void (*emit
)( GLcontext
*, GLuint
, GLuint
, void *, GLuint
);
50 tnl_interp_func interp
;
51 tnl_copy_pv_func copy_pv
;
52 GLboolean (*check_tex_sizes
)( GLcontext
*ctx
);
54 GLuint vertex_stride_shift
;
56 } setup_tab
[TRIDENT_MAX_SETUP
];
58 #define TINY_VERTEX_FORMAT 1
59 #define NOTEX_VERTEX_FORMAT 2
60 #define TEX0_VERTEX_FORMAT 3
61 #define TEX1_VERTEX_FORMAT 4
62 #define PROJ_TEX1_VERTEX_FORMAT 5
63 #define TEX2_VERTEX_FORMAT 6
64 #define TEX3_VERTEX_FORMAT 7
65 #define PROJ_TEX3_VERTEX_FORMAT 8
67 #define DO_XYZW (IND & TRIDENT_XYZW_BIT)
68 #define DO_RGBA (IND & TRIDENT_RGBA_BIT)
69 #define DO_SPEC (IND & TRIDENT_SPEC_BIT)
70 #define DO_FOG (IND & TRIDENT_FOG_BIT)
71 #define DO_TEX0 (IND & TRIDENT_TEX0_BIT)
72 #define DO_TEX1 (IND & TRIDENT_TEX1_BIT)
75 #define DO_PTEX (IND & TRIDENT_PTEX_BIT)
77 #define VERTEX tridentVertex
78 #define VERTEX_COLOR trident_color_t
79 #define LOCALVARS tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
80 #define GET_VIEWPORT_MAT() tmesa->hw_viewport
81 #define GET_TEXSOURCE(n) tmesa->tmu_source[n]
82 #define GET_VERTEX_FORMAT() tmesa->vertex_format
83 #define GET_VERTEX_SIZE() tmesa->vertex_size
84 #define GET_VERTEX_STORE() tmesa->verts
85 #define GET_VERTEX_STRIDE_SHIFT() tmesa->vertex_stride_shift
86 #define GET_UBYTE_COLOR_STORE() &tmesa->UbyteColor
87 #define GET_UBYTE_SPEC_COLOR_STORE() &tmesa->UbyteSecondaryColor
89 #define HAVE_HW_VIEWPORT 0
90 #define HAVE_HW_DIVIDE 0
91 #define HAVE_RGBA_COLOR 0
92 #define HAVE_TINY_VERTICES 1
93 #define HAVE_NOTEX_VERTICES 1
94 #define HAVE_TEX0_VERTICES 1
95 #define HAVE_TEX1_VERTICES 1
96 #define HAVE_TEX2_VERTICES 0
97 #define HAVE_TEX3_VERTICES 0
98 #define HAVE_PTEX_VERTICES 0
100 #define UNVIEWPORT_VARS \
101 const GLfloat dx = - tmesa->drawX - SUBPIXEL_X; \
102 const GLfloat dy = (tmesa->driDrawable->h + \
103 tmesa->drawY + SUBPIXEL_Y); \
104 const GLfloat sz = 1.0 / tmesa->depth_scale
106 #define UNVIEWPORT_X(x) x + dx;
107 #define UNVIEWPORT_Y(y) - y + dy;
108 #define UNVIEWPORT_Z(z) z * sz;
110 #define PTEX_FALLBACK() tridentFallback(TRIDENT_CONTEXT(ctx), TRIDENT_FALLBACK_TEXTURE, 1)
112 #define IMPORT_FLOAT_COLORS trident_import_float_colors
113 #define IMPORT_FLOAT_SPEC_COLORS trident_import_float_spec_colors
115 #define INTERP_VERTEX setup_tab[tmesa->SetupIndex].interp
116 #define COPY_PV_VERTEX setup_tab[tmesa->SetupIndex].copy_pv
118 /***********************************************************************
119 * Generate pv-copying and translation functions *
120 ***********************************************************************/
122 #define TAG(x) trident_##x
123 #include "tnl_dd/t_dd_vb.c"
125 /***********************************************************************
126 * Generate vertex emit and interp functions *
127 ***********************************************************************/
129 #define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT)
130 #define TAG(x) x##_wg
131 #include "tnl_dd/t_dd_vbtmp.h"
133 #define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_SPEC_BIT)
134 #define TAG(x) x##_wgs
135 #include "tnl_dd/t_dd_vbtmp.h"
137 #define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_TEX0_BIT)
138 #define TAG(x) x##_wgt0
139 #include "tnl_dd/t_dd_vbtmp.h"
141 #define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_TEX0_BIT|TRIDENT_TEX1_BIT)
142 #define TAG(x) x##_wgt0t1
143 #include "tnl_dd/t_dd_vbtmp.h"
145 #define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_TEX0_BIT|TRIDENT_PTEX_BIT)
146 #define TAG(x) x##_wgpt0
147 #include "tnl_dd/t_dd_vbtmp.h"
149 #define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_SPEC_BIT|TRIDENT_TEX0_BIT)
150 #define TAG(x) x##_wgst0
151 #include "tnl_dd/t_dd_vbtmp.h"
153 #define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_SPEC_BIT|TRIDENT_TEX0_BIT|TRIDENT_TEX1_BIT)
154 #define TAG(x) x##_wgst0t1
155 #include "tnl_dd/t_dd_vbtmp.h"
157 #define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_SPEC_BIT|TRIDENT_TEX0_BIT|TRIDENT_PTEX_BIT)
158 #define TAG(x) x##_wgspt0
159 #include "tnl_dd/t_dd_vbtmp.h"
161 #define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_FOG_BIT)
162 #define TAG(x) x##_wgf
163 #include "tnl_dd/t_dd_vbtmp.h"
165 #define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_FOG_BIT|TRIDENT_SPEC_BIT)
166 #define TAG(x) x##_wgfs
167 #include "tnl_dd/t_dd_vbtmp.h"
169 #define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_FOG_BIT|TRIDENT_TEX0_BIT)
170 #define TAG(x) x##_wgft0
171 #include "tnl_dd/t_dd_vbtmp.h"
173 #define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_FOG_BIT|TRIDENT_TEX0_BIT|TRIDENT_TEX1_BIT)
174 #define TAG(x) x##_wgft0t1
175 #include "tnl_dd/t_dd_vbtmp.h"
177 #define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_FOG_BIT|TRIDENT_TEX0_BIT|TRIDENT_PTEX_BIT)
178 #define TAG(x) x##_wgfpt0
179 #include "tnl_dd/t_dd_vbtmp.h"
181 #define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_FOG_BIT|TRIDENT_SPEC_BIT|TRIDENT_TEX0_BIT)
182 #define TAG(x) x##_wgfst0
183 #include "tnl_dd/t_dd_vbtmp.h"
185 #define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_FOG_BIT|TRIDENT_SPEC_BIT|TRIDENT_TEX0_BIT|TRIDENT_TEX1_BIT)
186 #define TAG(x) x##_wgfst0t1
187 #include "tnl_dd/t_dd_vbtmp.h"
189 #define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_FOG_BIT|TRIDENT_SPEC_BIT|TRIDENT_TEX0_BIT|TRIDENT_PTEX_BIT)
190 #define TAG(x) x##_wgfspt0
191 #include "tnl_dd/t_dd_vbtmp.h"
193 #define IND (TRIDENT_TEX0_BIT)
194 #define TAG(x) x##_t0
195 #include "tnl_dd/t_dd_vbtmp.h"
197 #define IND (TRIDENT_TEX0_BIT|TRIDENT_TEX1_BIT)
198 #define TAG(x) x##_t0t1
199 #include "tnl_dd/t_dd_vbtmp.h"
201 #define IND (TRIDENT_FOG_BIT)
203 #include "tnl_dd/t_dd_vbtmp.h"
205 #define IND (TRIDENT_FOG_BIT|TRIDENT_TEX0_BIT)
206 #define TAG(x) x##_ft0
207 #include "tnl_dd/t_dd_vbtmp.h"
209 #define IND (TRIDENT_FOG_BIT|TRIDENT_TEX0_BIT|TRIDENT_TEX1_BIT)
210 #define TAG(x) x##_ft0t1
211 #include "tnl_dd/t_dd_vbtmp.h"
213 #define IND (TRIDENT_RGBA_BIT)
215 #include "tnl_dd/t_dd_vbtmp.h"
217 #define IND (TRIDENT_RGBA_BIT|TRIDENT_SPEC_BIT)
218 #define TAG(x) x##_gs
219 #include "tnl_dd/t_dd_vbtmp.h"
221 #define IND (TRIDENT_RGBA_BIT|TRIDENT_TEX0_BIT)
222 #define TAG(x) x##_gt0
223 #include "tnl_dd/t_dd_vbtmp.h"
225 #define IND (TRIDENT_RGBA_BIT|TRIDENT_TEX0_BIT|TRIDENT_TEX1_BIT)
226 #define TAG(x) x##_gt0t1
227 #include "tnl_dd/t_dd_vbtmp.h"
229 #define IND (TRIDENT_RGBA_BIT|TRIDENT_SPEC_BIT|TRIDENT_TEX0_BIT)
230 #define TAG(x) x##_gst0
231 #include "tnl_dd/t_dd_vbtmp.h"
233 #define IND (TRIDENT_RGBA_BIT|TRIDENT_SPEC_BIT|TRIDENT_TEX0_BIT|TRIDENT_TEX1_BIT)
234 #define TAG(x) x##_gst0t1
235 #include "tnl_dd/t_dd_vbtmp.h"
237 #define IND (TRIDENT_RGBA_BIT|TRIDENT_FOG_BIT)
238 #define TAG(x) x##_gf
239 #include "tnl_dd/t_dd_vbtmp.h"
241 #define IND (TRIDENT_RGBA_BIT|TRIDENT_FOG_BIT|TRIDENT_SPEC_BIT)
242 #define TAG(x) x##_gfs
243 #include "tnl_dd/t_dd_vbtmp.h"
245 #define IND (TRIDENT_RGBA_BIT|TRIDENT_FOG_BIT|TRIDENT_TEX0_BIT)
246 #define TAG(x) x##_gft0
247 #include "tnl_dd/t_dd_vbtmp.h"
249 #define IND (TRIDENT_RGBA_BIT|TRIDENT_FOG_BIT|TRIDENT_TEX0_BIT|TRIDENT_TEX1_BIT)
250 #define TAG(x) x##_gft0t1
251 #include "tnl_dd/t_dd_vbtmp.h"
253 #define IND (TRIDENT_RGBA_BIT|TRIDENT_FOG_BIT|TRIDENT_SPEC_BIT|TRIDENT_TEX0_BIT)
254 #define TAG(x) x##_gfst0
255 #include "tnl_dd/t_dd_vbtmp.h"
257 #define IND (TRIDENT_RGBA_BIT|TRIDENT_FOG_BIT|TRIDENT_SPEC_BIT|TRIDENT_TEX0_BIT|TRIDENT_TEX1_BIT)
258 #define TAG(x) x##_gfst0t1
259 #include "tnl_dd/t_dd_vbtmp.h"
261 static void init_setup_tab( void )
298 void tridentBuildVertices( GLcontext
*ctx
,
303 tridentContextPtr tmesa
= TRIDENT_CONTEXT( ctx
);
304 GLubyte
*v
= ((GLubyte
*)tmesa
->verts
+ (start
<<tmesa
->vertex_stride_shift
));
305 GLuint stride
= 1<<tmesa
->vertex_stride_shift
;
307 newinputs
|= tmesa
->SetupNewInputs
;
308 tmesa
->SetupNewInputs
= 0;
313 if (newinputs
& VERT_BIT_POS
) {
314 setup_tab
[tmesa
->SetupIndex
].emit( ctx
, start
, count
, v
, stride
);
318 if (newinputs
& VERT_BIT_COLOR0
)
319 ind
|= TRIDENT_RGBA_BIT
;
321 if (newinputs
& VERT_BIT_COLOR1
)
322 ind
|= TRIDENT_SPEC_BIT
;
324 if (newinputs
& VERT_BIT_TEX0
)
325 ind
|= TRIDENT_TEX0_BIT
;
327 if (newinputs
& VERT_BIT_TEX1
)
328 ind
|= TRIDENT_TEX1_BIT
;
330 if (newinputs
& VERT_BIT_FOG
)
331 ind
|= TRIDENT_FOG_BIT
;
333 if (tmesa
->SetupIndex
& TRIDENT_PTEX_BIT
)
336 ind
&= tmesa
->SetupIndex
;
339 setup_tab
[ind
].emit( ctx
, start
, count
, v
, stride
);
344 void tridentCheckTexSizes( GLcontext
*ctx
)
346 tridentContextPtr tmesa
= TRIDENT_CONTEXT( ctx
);
348 if (!setup_tab
[tmesa
->SetupIndex
].check_tex_sizes(ctx
)) {
349 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
351 /* Invalidate stored verts
353 tmesa
->SetupNewInputs
= ~0;
354 tmesa
->SetupIndex
|= TRIDENT_PTEX_BIT
;
356 if (!tmesa
->Fallback
&&
357 !(ctx
->_TriangleCaps
& (DD_TRI_LIGHT_TWOSIDE
|DD_TRI_UNFILLED
))) {
358 tnl
->Driver
.Render
.Interp
= setup_tab
[tmesa
->SetupIndex
].interp
;
359 tnl
->Driver
.Render
.CopyPV
= setup_tab
[tmesa
->SetupIndex
].copy_pv
;
364 void tridentChooseVertexState( GLcontext
*ctx
)
366 tridentContextPtr tmesa
= TRIDENT_CONTEXT( ctx
);
367 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
368 GLuint ind
= TRIDENT_XYZW_BIT
|TRIDENT_RGBA_BIT
;
370 if (ctx
->_TriangleCaps
& DD_SEPARATE_SPECULAR
)
371 ind
|= TRIDENT_SPEC_BIT
;
373 if (ctx
->Fog
.Enabled
)
374 ind
|= TRIDENT_FOG_BIT
;
376 if (ctx
->Texture
.Unit
[0]._ReallyEnabled
) {
377 ind
|= TRIDENT_TEX0_BIT
;
378 if (ctx
->Texture
.Unit
[1]._ReallyEnabled
) {
379 ind
|= TRIDENT_TEX1_BIT
;
383 tmesa
->SetupIndex
= ind
;
385 if (ctx
->_TriangleCaps
& (DD_TRI_LIGHT_TWOSIDE
|DD_TRI_UNFILLED
)) {
386 tnl
->Driver
.Render
.Interp
= trident_interp_extras
;
387 tnl
->Driver
.Render
.CopyPV
= trident_copy_pv_extras
;
389 tnl
->Driver
.Render
.Interp
= setup_tab
[ind
].interp
;
390 tnl
->Driver
.Render
.CopyPV
= setup_tab
[ind
].copy_pv
;
393 if (setup_tab
[ind
].vertex_format
!= tmesa
->vertex_format
) {
394 tmesa
->vertex_format
= setup_tab
[ind
].vertex_format
;
395 tmesa
->vertex_size
= setup_tab
[ind
].vertex_size
;
396 tmesa
->vertex_stride_shift
= setup_tab
[ind
].vertex_stride_shift
;
400 void tridentInitVB( GLcontext
*ctx
)
402 tridentContextPtr tmesa
= TRIDENT_CONTEXT(ctx
);
403 GLuint size
= TNL_CONTEXT(ctx
)->vb
.Size
;
405 tmesa
->verts
= (GLubyte
*)ALIGN_MALLOC( size
* 16 * 4, 32 );
408 static int firsttime
= 1;
416 void tridentFreeVB( GLcontext
*ctx
)
418 tridentContextPtr tmesa
= TRIDENT_CONTEXT(ctx
);
421 ALIGN_FREE(tmesa
->verts
);
425 if (tmesa
->UbyteSecondaryColor
.Ptr
) {
426 ALIGN_FREE((void *)tmesa
->UbyteSecondaryColor
.Ptr
);
427 tmesa
->UbyteSecondaryColor
.Ptr
= 0;
430 if (tmesa
->UbyteColor
.Ptr
) {
431 ALIGN_FREE((void *)tmesa
->UbyteColor
.Ptr
);
432 tmesa
->UbyteColor
.Ptr
= 0;