Remove CVS keywords.
[mesa.git] / src / mesa / drivers / dri / gamma / gamma_vb.c
1 /*
2 * Copyright 2001 by Alan Hourihane.
3 *
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.
13 *
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.
21 *
22 * Authors: Alan Hourihane, <alanh@tungstengraphics.com>
23 * Keith Whitwell, <keith@tungstengraphics.com>
24 *
25 * 3DLabs Gamma driver.
26 */
27
28 #include "glheader.h"
29 #include "mtypes.h"
30 #include "imports.h"
31 #include "macros.h"
32 #include "colormac.h"
33
34 #include "swrast_setup/swrast_setup.h"
35 #include "tnl/t_context.h"
36 #include "tnl/tnl.h"
37
38 #include "gamma_context.h"
39 #include "gamma_vb.h"
40 #include "gamma_tris.h"
41
42
43 #define GAMMA_TEX0_BIT 0x1
44 #define GAMMA_RGBA_BIT 0x2
45 #define GAMMA_XYZW_BIT 0x4
46 #define GAMMA_PTEX_BIT 0x8
47 #define GAMMA_FOG_BIT 0x10
48 #define GAMMA_SPEC_BIT 0x20
49 #define GAMMA_MAX_SETUP 0x40
50
51 static struct {
52 void (*emit)( GLcontext *, GLuint, GLuint, void *, GLuint );
53 tnl_interp_func interp;
54 tnl_copy_pv_func copy_pv;
55 GLboolean (*check_tex_sizes)( GLcontext *ctx );
56 GLuint vertex_size;
57 GLuint vertex_format;
58 } setup_tab[GAMMA_MAX_SETUP];
59
60 #define TINY_VERTEX_FORMAT 1
61 #define NOTEX_VERTEX_FORMAT 2
62 #define TEX0_VERTEX_FORMAT 3
63 #define TEX1_VERTEX_FORMAT 0
64 #define PROJ_TEX1_VERTEX_FORMAT 0
65 #define TEX2_VERTEX_FORMAT 0
66 #define TEX3_VERTEX_FORMAT 0
67 #define PROJ_TEX3_VERTEX_FORMAT 0
68
69 #define DO_XYZW (IND & GAMMA_XYZW_BIT)
70 #define DO_RGBA (IND & GAMMA_RGBA_BIT)
71 #define DO_SPEC (IND & GAMMA_SPEC_BIT)
72 #define DO_FOG (IND & GAMMA_FOG_BIT)
73 #define DO_TEX0 (IND & GAMMA_TEX0_BIT)
74 #define DO_TEX1 0
75 #define DO_TEX2 0
76 #define DO_TEX3 0
77 #define DO_PTEX (IND & GAMMA_PTEX_BIT)
78
79 #define VERTEX gammaVertex
80 #define VERTEX_COLOR gamma_color_t
81 #define GET_VIEWPORT_MAT() 0
82 #define GET_TEXSOURCE(n) n
83 #define GET_VERTEX_FORMAT() GAMMA_CONTEXT(ctx)->vertex_format
84 #define GET_VERTEX_STORE() GAMMA_CONTEXT(ctx)->verts
85 #define GET_VERTEX_SIZE() GAMMA_CONTEXT(ctx)->vertex_size * sizeof(GLuint)
86 #define INVALIDATE_STORED_VERTICES()
87
88 #define HAVE_HW_VIEWPORT 1
89 #define HAVE_HW_DIVIDE 1
90 #define HAVE_RGBA_COLOR 0 /* we're BGRA */
91 #define HAVE_TINY_VERTICES 1
92 #define HAVE_NOTEX_VERTICES 1
93 #define HAVE_TEX0_VERTICES 1
94 #define HAVE_TEX1_VERTICES 0
95 #define HAVE_TEX2_VERTICES 0
96 #define HAVE_TEX3_VERTICES 0
97 #define HAVE_PTEX_VERTICES 1
98
99 #define PTEX_FALLBACK() /* never needed */
100
101 #define INTERP_VERTEX setup_tab[GAMMA_CONTEXT(ctx)->SetupIndex].interp
102 #define COPY_PV_VERTEX setup_tab[GAMMA_CONTEXT(ctx)->SetupIndex].copy_pv
103
104
105
106 /***********************************************************************
107 * Generate pv-copying and translation functions *
108 ***********************************************************************/
109
110 #define TAG(x) gamma_##x
111 #include "tnl_dd/t_dd_vb.c"
112
113 /***********************************************************************
114 * Generate vertex emit and interp functions *
115 ***********************************************************************/
116
117 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT)
118 #define TAG(x) x##_wg
119 #include "tnl_dd/t_dd_vbtmp.h"
120
121 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_SPEC_BIT)
122 #define TAG(x) x##_wgs
123 #include "tnl_dd/t_dd_vbtmp.h"
124
125 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_TEX0_BIT)
126 #define TAG(x) x##_wgt0
127 #include "tnl_dd/t_dd_vbtmp.h"
128
129 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_TEX0_BIT|GAMMA_PTEX_BIT)
130 #define TAG(x) x##_wgpt0
131 #include "tnl_dd/t_dd_vbtmp.h"
132
133 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_SPEC_BIT|GAMMA_TEX0_BIT)
134 #define TAG(x) x##_wgst0
135 #include "tnl_dd/t_dd_vbtmp.h"
136
137 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_SPEC_BIT|GAMMA_TEX0_BIT|\
138 GAMMA_PTEX_BIT)
139 #define TAG(x) x##_wgspt0
140 #include "tnl_dd/t_dd_vbtmp.h"
141
142 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_FOG_BIT)
143 #define TAG(x) x##_wgf
144 #include "tnl_dd/t_dd_vbtmp.h"
145
146 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_FOG_BIT|GAMMA_SPEC_BIT)
147 #define TAG(x) x##_wgfs
148 #include "tnl_dd/t_dd_vbtmp.h"
149
150 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_FOG_BIT|GAMMA_TEX0_BIT)
151 #define TAG(x) x##_wgft0
152 #include "tnl_dd/t_dd_vbtmp.h"
153
154 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_FOG_BIT|GAMMA_TEX0_BIT|\
155 GAMMA_PTEX_BIT)
156 #define TAG(x) x##_wgfpt0
157 #include "tnl_dd/t_dd_vbtmp.h"
158
159 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_FOG_BIT|GAMMA_SPEC_BIT|\
160 GAMMA_TEX0_BIT)
161 #define TAG(x) x##_wgfst0
162 #include "tnl_dd/t_dd_vbtmp.h"
163
164 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_FOG_BIT|GAMMA_SPEC_BIT|\
165 GAMMA_TEX0_BIT|GAMMA_PTEX_BIT)
166 #define TAG(x) x##_wgfspt0
167 #include "tnl_dd/t_dd_vbtmp.h"
168
169 #define IND (GAMMA_TEX0_BIT)
170 #define TAG(x) x##_t0
171 #include "tnl_dd/t_dd_vbtmp.h"
172
173 #define IND (GAMMA_FOG_BIT)
174 #define TAG(x) x##_f
175 #include "tnl_dd/t_dd_vbtmp.h"
176
177 #define IND (GAMMA_FOG_BIT|GAMMA_TEX0_BIT)
178 #define TAG(x) x##_ft0
179 #include "tnl_dd/t_dd_vbtmp.h"
180
181 #define IND (GAMMA_RGBA_BIT)
182 #define TAG(x) x##_g
183 #include "tnl_dd/t_dd_vbtmp.h"
184
185 #define IND (GAMMA_RGBA_BIT|GAMMA_SPEC_BIT)
186 #define TAG(x) x##_gs
187 #include "tnl_dd/t_dd_vbtmp.h"
188
189 #define IND (GAMMA_RGBA_BIT|GAMMA_TEX0_BIT)
190 #define TAG(x) x##_gt0
191 #include "tnl_dd/t_dd_vbtmp.h"
192
193 #define IND (GAMMA_RGBA_BIT|GAMMA_SPEC_BIT|GAMMA_TEX0_BIT)
194 #define TAG(x) x##_gst0
195 #include "tnl_dd/t_dd_vbtmp.h"
196
197 #define IND (GAMMA_RGBA_BIT|GAMMA_FOG_BIT)
198 #define TAG(x) x##_gf
199 #include "tnl_dd/t_dd_vbtmp.h"
200
201 #define IND (GAMMA_RGBA_BIT|GAMMA_FOG_BIT|GAMMA_SPEC_BIT)
202 #define TAG(x) x##_gfs
203 #include "tnl_dd/t_dd_vbtmp.h"
204
205 #define IND (GAMMA_RGBA_BIT|GAMMA_FOG_BIT|GAMMA_TEX0_BIT)
206 #define TAG(x) x##_gft0
207 #include "tnl_dd/t_dd_vbtmp.h"
208
209 #define IND (GAMMA_RGBA_BIT|GAMMA_FOG_BIT|GAMMA_SPEC_BIT|GAMMA_TEX0_BIT)
210 #define TAG(x) x##_gfst0
211 #include "tnl_dd/t_dd_vbtmp.h"
212
213 static void init_setup_tab( void )
214 {
215 init_wg();
216 init_wgs();
217 init_wgt0();
218 init_wgpt0();
219 init_wgst0();
220 init_wgspt0();
221 init_wgf();
222 init_wgfs();
223 init_wgft0();
224 init_wgfpt0();
225 init_wgfst0();
226 init_wgfspt0();
227 init_t0();
228 init_f();
229 init_ft0();
230 init_g();
231 init_gs();
232 init_gt0();
233 init_gst0();
234 init_gf();
235 init_gfs();
236 init_gft0();
237 init_gfst0();
238 }
239
240 void gammaCheckTexSizes( GLcontext *ctx )
241 {
242 TNLcontext *tnl = TNL_CONTEXT(ctx);
243 gammaContextPtr gmesa = GAMMA_CONTEXT( ctx );
244
245 if (!setup_tab[gmesa->SetupIndex].check_tex_sizes(ctx)) {
246 /* Invalidate stored verts
247 */
248 gmesa->SetupNewInputs = ~0;
249 gmesa->SetupIndex |= GAMMA_PTEX_BIT;
250
251 if (!(ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) {
252 tnl->Driver.Render.Interp = setup_tab[gmesa->SetupIndex].interp;
253 tnl->Driver.Render.CopyPV = setup_tab[gmesa->SetupIndex].copy_pv;
254 }
255 }
256 }
257
258 void gammaBuildVertices( GLcontext *ctx,
259 GLuint start,
260 GLuint count,
261 GLuint newinputs )
262 {
263 gammaContextPtr gmesa = GAMMA_CONTEXT( ctx );
264 GLuint stride = gmesa->vertex_size * sizeof(int);
265 GLubyte *v = ((GLubyte *)gmesa->verts + (start * stride));
266
267 newinputs |= gmesa->SetupNewInputs;
268 gmesa->SetupNewInputs = 0;
269
270 if (!newinputs)
271 return;
272
273 if (newinputs & VERT_BIT_POS) {
274 setup_tab[gmesa->SetupIndex].emit( ctx, start, count, v, stride );
275 } else {
276 GLuint ind = 0;
277
278 if (newinputs & VERT_BIT_COLOR0)
279 ind |= GAMMA_RGBA_BIT;
280
281 if (newinputs & VERT_BIT_COLOR1)
282 ind |= GAMMA_SPEC_BIT;
283
284 if (newinputs & VERT_BIT_TEX0)
285 ind |= GAMMA_TEX0_BIT;
286
287 if (newinputs & VERT_BIT_FOG)
288 ind |= GAMMA_FOG_BIT;
289
290 if (gmesa->SetupIndex & GAMMA_PTEX_BIT)
291 ind = ~0;
292
293 ind &= gmesa->SetupIndex;
294
295 if (ind) {
296 setup_tab[ind].emit( ctx, start, count, v, stride );
297 }
298 }
299 }
300
301 void gammaChooseVertexState( GLcontext *ctx )
302 {
303 gammaContextPtr gmesa = GAMMA_CONTEXT( ctx );
304 TNLcontext *tnl = TNL_CONTEXT(ctx);
305 GLuint ind = GAMMA_XYZW_BIT|GAMMA_RGBA_BIT;
306
307 if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
308 ind |= GAMMA_SPEC_BIT;
309
310 if (ctx->Fog.Enabled)
311 ind |= GAMMA_FOG_BIT;
312
313 if (ctx->Texture.Unit[0]._ReallyEnabled) {
314 _tnl_need_projected_coords( ctx, GL_FALSE );
315 ind |= GAMMA_TEX0_BIT;
316 } else
317 _tnl_need_projected_coords( ctx, GL_FALSE );
318
319 gmesa->SetupIndex = ind;
320
321 if (setup_tab[ind].vertex_format != gmesa->vertex_format) {
322 gmesa->vertex_format = setup_tab[ind].vertex_format;
323 gmesa->vertex_size = setup_tab[ind].vertex_size;
324 }
325
326 if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED)) {
327 tnl->Driver.Render.Interp = gamma_interp_extras;
328 tnl->Driver.Render.CopyPV = gamma_copy_pv_extras;
329 } else {
330 tnl->Driver.Render.Interp = setup_tab[ind].interp;
331 tnl->Driver.Render.CopyPV = setup_tab[ind].copy_pv;
332 }
333 }
334
335
336 void gammaInitVB( GLcontext *ctx )
337 {
338 gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
339 GLuint size = TNL_CONTEXT(ctx)->vb.Size;
340
341 gmesa->verts = (GLubyte *)ALIGN_MALLOC(size * 4 * 16, 32);
342
343 {
344 static int firsttime = 1;
345 if (firsttime) {
346 init_setup_tab();
347 firsttime = 0;
348 gmesa->vertex_size = 16; /* FIXME - only one vertex setup */
349 }
350 }
351 }
352
353
354 void gammaFreeVB( GLcontext *ctx )
355 {
356 gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
357 if (gmesa->verts) {
358 ALIGN_FREE(gmesa->verts);
359 gmesa->verts = 0;
360 }
361 }