Import vtx-0-2-branch
[mesa.git] / src / mesa / drivers / dri / gamma / gamma_vb.c
1 /* $XFree86: xc/lib/GL/mesa/src/drv/gamma/gamma_vb.c,v 1.4 2003/03/26 20:43:48 tsi Exp $ */
2 /*
3 * Copyright 2001 by Alan Hourihane.
4 *
5 * Permission to use, copy, modify, distribute, and sell this software and its
6 * documentation for any purpose is hereby granted without fee, provided that
7 * the above copyright notice appear in all copies and that both that
8 * copyright notice and this permission notice appear in supporting
9 * documentation, and that the name of Alan Hourihane not be used in
10 * advertising or publicity pertaining to distribution of the software without
11 * specific, written prior permission. Alan Hourihane makes no representations
12 * about the suitability of this software for any purpose. It is provided
13 * "as is" without express or implied warranty.
14 *
15 * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17 * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
21 * PERFORMANCE OF THIS SOFTWARE.
22 *
23 * Authors: Alan Hourihane, <alanh@tungstengraphics.com>
24 * Keith Whitwell, <keith@tungstengraphics.com>
25 *
26 * 3DLabs Gamma driver.
27 */
28
29 #include "glheader.h"
30 #include "mtypes.h"
31 #include "imports.h"
32 #include "macros.h"
33 #include "colormac.h"
34
35 #include "swrast_setup/swrast_setup.h"
36 #include "tnl/t_context.h"
37 #include "tnl/tnl.h"
38
39 #include "gamma_context.h"
40 #include "gamma_vb.h"
41 #include "gamma_tris.h"
42
43
44 #define GAMMA_TEX0_BIT 0x1
45 #define GAMMA_RGBA_BIT 0x2
46 #define GAMMA_XYZW_BIT 0x4
47 #define GAMMA_PTEX_BIT 0x8
48 #define GAMMA_FOG_BIT 0x10
49 #define GAMMA_SPEC_BIT 0x20
50 #define GAMMA_MAX_SETUP 0x40
51
52 static struct {
53 void (*emit)( GLcontext *, GLuint, GLuint, void *, GLuint );
54 interp_func interp;
55 copy_pv_func copy_pv;
56 GLboolean (*check_tex_sizes)( GLcontext *ctx );
57 GLuint vertex_size;
58 GLuint vertex_stride_shift;
59 GLuint vertex_format;
60 } setup_tab[GAMMA_MAX_SETUP];
61
62 #define TINY_VERTEX_FORMAT 1
63 #define NOTEX_VERTEX_FORMAT 2
64 #define TEX0_VERTEX_FORMAT 3
65 #define TEX1_VERTEX_FORMAT 0
66 #define PROJ_TEX1_VERTEX_FORMAT 0
67 #define TEX2_VERTEX_FORMAT 0
68 #define TEX3_VERTEX_FORMAT 0
69 #define PROJ_TEX3_VERTEX_FORMAT 0
70
71 #define DO_XYZW (IND & GAMMA_XYZW_BIT)
72 #define DO_RGBA (IND & GAMMA_RGBA_BIT)
73 #define DO_SPEC (IND & GAMMA_SPEC_BIT)
74 #define DO_FOG (IND & GAMMA_FOG_BIT)
75 #define DO_TEX0 (IND & GAMMA_TEX0_BIT)
76 #define DO_TEX1 0
77 #define DO_TEX2 0
78 #define DO_TEX3 0
79 #define DO_PTEX (IND & GAMMA_PTEX_BIT)
80
81 #define VERTEX gammaVertex
82 #define VERTEX_COLOR gamma_color_t
83 #define GET_VIEWPORT_MAT() 0
84 #define GET_TEXSOURCE(n) n
85 #define GET_VERTEX_FORMAT() GAMMA_CONTEXT(ctx)->vertex_format
86 #define GET_VERTEX_STORE() GAMMA_CONTEXT(ctx)->verts
87 #define GET_VERTEX_STRIDE_SHIFT() GAMMA_CONTEXT(ctx)->vertex_stride_shift
88 #define INVALIDATE_STORED_VERTICES()
89 #define GET_UBYTE_COLOR_STORE() &GAMMA_CONTEXT(ctx)->UbyteColor
90 #define GET_UBYTE_SPEC_COLOR_STORE() &GAMMA_CONTEXT(ctx)->UbyteSecondaryColor
91
92 #define HAVE_HW_VIEWPORT 1
93 #define HAVE_HW_DIVIDE 1
94 #define HAVE_RGBA_COLOR 0 /* we're BGRA */
95 #define HAVE_TINY_VERTICES 1
96 #define HAVE_NOTEX_VERTICES 1
97 #define HAVE_TEX0_VERTICES 1
98 #define HAVE_TEX1_VERTICES 0
99 #define HAVE_TEX2_VERTICES 0
100 #define HAVE_TEX3_VERTICES 0
101 #define HAVE_PTEX_VERTICES 1
102
103 #define PTEX_FALLBACK() /* never needed */
104
105 #define IMPORT_QUALIFIER
106 #define IMPORT_FLOAT_COLORS gamma_import_float_colors
107 #define IMPORT_FLOAT_SPEC_COLORS gamma_import_float_spec_colors
108
109 #define INTERP_VERTEX setup_tab[GAMMA_CONTEXT(ctx)->SetupIndex].interp
110 #define COPY_PV_VERTEX setup_tab[GAMMA_CONTEXT(ctx)->SetupIndex].copy_pv
111
112
113
114 /***********************************************************************
115 * Generate pv-copying and translation functions *
116 ***********************************************************************/
117
118 #define TAG(x) gamma_##x
119 #include "tnl_dd/t_dd_vb.c"
120
121 /***********************************************************************
122 * Generate vertex emit and interp functions *
123 ***********************************************************************/
124
125 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT)
126 #define TAG(x) x##_wg
127 #include "tnl_dd/t_dd_vbtmp.h"
128
129 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_SPEC_BIT)
130 #define TAG(x) x##_wgs
131 #include "tnl_dd/t_dd_vbtmp.h"
132
133 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_TEX0_BIT)
134 #define TAG(x) x##_wgt0
135 #include "tnl_dd/t_dd_vbtmp.h"
136
137 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_TEX0_BIT|GAMMA_PTEX_BIT)
138 #define TAG(x) x##_wgpt0
139 #include "tnl_dd/t_dd_vbtmp.h"
140
141 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_SPEC_BIT|GAMMA_TEX0_BIT)
142 #define TAG(x) x##_wgst0
143 #include "tnl_dd/t_dd_vbtmp.h"
144
145 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_SPEC_BIT|GAMMA_TEX0_BIT|\
146 GAMMA_PTEX_BIT)
147 #define TAG(x) x##_wgspt0
148 #include "tnl_dd/t_dd_vbtmp.h"
149
150 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_FOG_BIT)
151 #define TAG(x) x##_wgf
152 #include "tnl_dd/t_dd_vbtmp.h"
153
154 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_FOG_BIT|GAMMA_SPEC_BIT)
155 #define TAG(x) x##_wgfs
156 #include "tnl_dd/t_dd_vbtmp.h"
157
158 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_FOG_BIT|GAMMA_TEX0_BIT)
159 #define TAG(x) x##_wgft0
160 #include "tnl_dd/t_dd_vbtmp.h"
161
162 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_FOG_BIT|GAMMA_TEX0_BIT|\
163 GAMMA_PTEX_BIT)
164 #define TAG(x) x##_wgfpt0
165 #include "tnl_dd/t_dd_vbtmp.h"
166
167 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_FOG_BIT|GAMMA_SPEC_BIT|\
168 GAMMA_TEX0_BIT)
169 #define TAG(x) x##_wgfst0
170 #include "tnl_dd/t_dd_vbtmp.h"
171
172 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_FOG_BIT|GAMMA_SPEC_BIT|\
173 GAMMA_TEX0_BIT|GAMMA_PTEX_BIT)
174 #define TAG(x) x##_wgfspt0
175 #include "tnl_dd/t_dd_vbtmp.h"
176
177 #define IND (GAMMA_TEX0_BIT)
178 #define TAG(x) x##_t0
179 #include "tnl_dd/t_dd_vbtmp.h"
180
181 #define IND (GAMMA_FOG_BIT)
182 #define TAG(x) x##_f
183 #include "tnl_dd/t_dd_vbtmp.h"
184
185 #define IND (GAMMA_FOG_BIT|GAMMA_TEX0_BIT)
186 #define TAG(x) x##_ft0
187 #include "tnl_dd/t_dd_vbtmp.h"
188
189 #define IND (GAMMA_RGBA_BIT)
190 #define TAG(x) x##_g
191 #include "tnl_dd/t_dd_vbtmp.h"
192
193 #define IND (GAMMA_RGBA_BIT|GAMMA_SPEC_BIT)
194 #define TAG(x) x##_gs
195 #include "tnl_dd/t_dd_vbtmp.h"
196
197 #define IND (GAMMA_RGBA_BIT|GAMMA_TEX0_BIT)
198 #define TAG(x) x##_gt0
199 #include "tnl_dd/t_dd_vbtmp.h"
200
201 #define IND (GAMMA_RGBA_BIT|GAMMA_SPEC_BIT|GAMMA_TEX0_BIT)
202 #define TAG(x) x##_gst0
203 #include "tnl_dd/t_dd_vbtmp.h"
204
205 #define IND (GAMMA_RGBA_BIT|GAMMA_FOG_BIT)
206 #define TAG(x) x##_gf
207 #include "tnl_dd/t_dd_vbtmp.h"
208
209 #define IND (GAMMA_RGBA_BIT|GAMMA_FOG_BIT|GAMMA_SPEC_BIT)
210 #define TAG(x) x##_gfs
211 #include "tnl_dd/t_dd_vbtmp.h"
212
213 #define IND (GAMMA_RGBA_BIT|GAMMA_FOG_BIT|GAMMA_TEX0_BIT)
214 #define TAG(x) x##_gft0
215 #include "tnl_dd/t_dd_vbtmp.h"
216
217 #define IND (GAMMA_RGBA_BIT|GAMMA_FOG_BIT|GAMMA_SPEC_BIT|GAMMA_TEX0_BIT)
218 #define TAG(x) x##_gfst0
219 #include "tnl_dd/t_dd_vbtmp.h"
220
221 static void init_setup_tab( void )
222 {
223 init_wg();
224 init_wgs();
225 init_wgt0();
226 init_wgpt0();
227 init_wgst0();
228 init_wgspt0();
229 init_wgf();
230 init_wgfs();
231 init_wgft0();
232 init_wgfpt0();
233 init_wgfst0();
234 init_wgfspt0();
235 init_t0();
236 init_f();
237 init_ft0();
238 init_g();
239 init_gs();
240 init_gt0();
241 init_gst0();
242 init_gf();
243 init_gfs();
244 init_gft0();
245 init_gfst0();
246 }
247
248 void gammaCheckTexSizes( GLcontext *ctx )
249 {
250 TNLcontext *tnl = TNL_CONTEXT(ctx);
251 gammaContextPtr gmesa = GAMMA_CONTEXT( ctx );
252
253 if (!setup_tab[gmesa->SetupIndex].check_tex_sizes(ctx)) {
254 /* Invalidate stored verts
255 */
256 gmesa->SetupNewInputs = ~0;
257 gmesa->SetupIndex |= GAMMA_PTEX_BIT;
258
259 if (!(ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) {
260 tnl->Driver.Render.Interp = setup_tab[gmesa->SetupIndex].interp;
261 tnl->Driver.Render.CopyPV = setup_tab[gmesa->SetupIndex].copy_pv;
262 }
263 }
264 }
265
266 void gammaBuildVertices( GLcontext *ctx,
267 GLuint start,
268 GLuint count,
269 GLuint newinputs )
270 {
271 gammaContextPtr gmesa = GAMMA_CONTEXT( ctx );
272 GLubyte *v = ((GLubyte *)gmesa->verts + (start<<gmesa->vertex_stride_shift));
273 GLuint stride = 1<<gmesa->vertex_stride_shift;
274
275 newinputs |= gmesa->SetupNewInputs;
276 gmesa->SetupNewInputs = 0;
277
278 if (!newinputs)
279 return;
280
281 if (newinputs & VERT_BIT_POS) {
282 setup_tab[gmesa->SetupIndex].emit( ctx, start, count, v, stride );
283 } else {
284 GLuint ind = 0;
285
286 if (newinputs & VERT_BIT_COLOR0)
287 ind |= GAMMA_RGBA_BIT;
288
289 if (newinputs & VERT_BIT_COLOR1)
290 ind |= GAMMA_SPEC_BIT;
291
292 if (newinputs & VERT_BIT_TEX0)
293 ind |= GAMMA_TEX0_BIT;
294
295 if (newinputs & VERT_BIT_FOG)
296 ind |= GAMMA_FOG_BIT;
297
298 if (gmesa->SetupIndex & GAMMA_PTEX_BIT)
299 ind = ~0;
300
301 ind &= gmesa->SetupIndex;
302
303 if (ind) {
304 setup_tab[ind].emit( ctx, start, count, v, stride );
305 }
306 }
307 }
308
309 void gammaChooseVertexState( GLcontext *ctx )
310 {
311 gammaContextPtr gmesa = GAMMA_CONTEXT( ctx );
312 TNLcontext *tnl = TNL_CONTEXT(ctx);
313 GLuint ind = GAMMA_XYZW_BIT|GAMMA_RGBA_BIT;
314
315 if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
316 ind |= GAMMA_SPEC_BIT;
317
318 if (ctx->Fog.Enabled)
319 ind |= GAMMA_FOG_BIT;
320
321 if (ctx->Texture.Unit[0]._ReallyEnabled) {
322 _tnl_need_projected_coords( ctx, GL_FALSE );
323 ind |= GAMMA_TEX0_BIT;
324 } else
325 _tnl_need_projected_coords( ctx, GL_FALSE );
326
327 gmesa->SetupIndex = ind;
328
329 if (setup_tab[ind].vertex_format != gmesa->vertex_format) {
330 gmesa->vertex_format = setup_tab[ind].vertex_format;
331 gmesa->vertex_size = setup_tab[ind].vertex_size;
332 gmesa->vertex_stride_shift = setup_tab[ind].vertex_stride_shift;
333 }
334
335 if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED)) {
336 tnl->Driver.Render.Interp = gamma_interp_extras;
337 tnl->Driver.Render.CopyPV = gamma_copy_pv_extras;
338 } else {
339 tnl->Driver.Render.Interp = setup_tab[ind].interp;
340 tnl->Driver.Render.CopyPV = setup_tab[ind].copy_pv;
341 }
342 }
343
344
345 void gammaInitVB( GLcontext *ctx )
346 {
347 gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
348 GLuint size = TNL_CONTEXT(ctx)->vb.Size;
349
350 gmesa->verts = (GLubyte *)ALIGN_MALLOC(size * 4 * 16, 32);
351
352 {
353 static int firsttime = 1;
354 if (firsttime) {
355 init_setup_tab();
356 firsttime = 0;
357 gmesa->vertex_stride_shift = 6; /* FIXME - only one vertex setup */
358 }
359 }
360 }
361
362
363 void gammaFreeVB( GLcontext *ctx )
364 {
365 gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
366 if (gmesa->verts) {
367 ALIGN_FREE(gmesa->verts);
368 gmesa->verts = 0;
369 }
370
371 if (gmesa->UbyteSecondaryColor.Ptr) {
372 ALIGN_FREE(gmesa->UbyteSecondaryColor.Ptr);
373 gmesa->UbyteSecondaryColor.Ptr = 0;
374 }
375
376 if (gmesa->UbyteColor.Ptr) {
377 ALIGN_FREE(gmesa->UbyteColor.Ptr);
378 gmesa->UbyteColor.Ptr = 0;
379 }
380 }