Merge commit 'origin/gallium-0.1'
[mesa.git] / src / mesa / drivers / dri / s3v / s3v_vb.c
1 /*
2 * Author: Max Lingua <sunmax@libero.it>
3 */
4
5 #include "main/glheader.h"
6 #include "main/mtypes.h"
7 #include "main/macros.h"
8 #include "main/colormac.h"
9
10 #include "swrast_setup/swrast_setup.h"
11 #include "tnl/t_context.h"
12 #include "tnl/tnl.h"
13
14 #include "s3v_context.h"
15 #include "s3v_vb.h"
16 #include "s3v_tris.h"
17
18 #define S3V_XYZW_BIT 0x1
19 #define S3V_RGBA_BIT 0x2
20 #define S3V_TEX0_BIT 0x4
21 #define S3V_PTEX_BIT 0x8
22 #define S3V_FOG_BIT 0x10
23 #define S3V_MAX_SETUP 0x20
24
25 static struct {
26 void (*emit)( GLcontext *, GLuint, GLuint, void *, GLuint );
27 tnl_interp_func interp;
28 tnl_copy_pv_func copy_pv;
29 GLboolean (*check_tex_sizes)( GLcontext *ctx );
30 GLuint vertex_size;
31 GLuint vertex_stride_shift;
32 GLuint vertex_format;
33 } setup_tab[S3V_MAX_SETUP];
34
35
36 /* Only one vertex format, atm, so no need to give them names:
37 */
38 #define TINY_VERTEX_FORMAT 1
39 #define NOTEX_VERTEX_FORMAT 0
40 #define TEX0_VERTEX_FORMAT 0
41 #define TEX1_VERTEX_FORMAT 0
42 #define PROJ_TEX1_VERTEX_FORMAT 0
43 #define TEX2_VERTEX_FORMAT 0
44 #define TEX3_VERTEX_FORMAT 0
45 #define PROJ_TEX3_VERTEX_FORMAT 0
46
47 #define DO_XYZW (IND & S3V_XYZW_BIT)
48 #define DO_RGBA (IND & S3V_RGBA_BIT)
49 #define DO_SPEC 0
50 #define DO_FOG (IND & S3V_FOG_BIT)
51 #define DO_TEX0 (IND & S3V_TEX0_BIT)
52 #define DO_TEX1 0
53 #define DO_TEX2 0
54 #define DO_TEX3 0
55 #define DO_PTEX (IND & S3V_PTEX_BIT)
56
57 #define VERTEX s3vVertex
58 #define LOCALVARS /* s3vContextPtr vmesa = S3V_CONTEXT(ctx); */
59 #define GET_VIEWPORT_MAT() 0 /* vmesa->hw_viewport */
60 #define GET_TEXSOURCE(n) n
61 #define GET_VERTEX_FORMAT() 0
62 #define GET_VERTEX_SIZE() S3V_CONTEXT(ctx)->vertex_size * sizeof(GLuint)
63 #define GET_VERTEX_STORE() S3V_CONTEXT(ctx)->verts
64 #define GET_VERTEX_STRIDE_SHIFT() S3V_CONTEXT(ctx)->vertex_stride_shift
65 #define INVALIDATE_STORED_VERTICES()
66 #define GET_UBYTE_COLOR_STORE() &S3V_CONTEXT(ctx)->UbyteColor
67 #define GET_UBYTE_SPEC_COLOR_STORE() &S3V_CONTEXT(ctx)->UbyteSecondaryColor
68
69 #define HAVE_HW_VIEWPORT 1 /* FIXME */
70 #define HAVE_HW_DIVIDE 1
71 #define HAVE_RGBA_COLOR 0 /* we're BGRA */
72 #define HAVE_TINY_VERTICES 1
73 #define HAVE_NOTEX_VERTICES 0
74 #define HAVE_TEX0_VERTICES 0
75 #define HAVE_TEX1_VERTICES 0
76 #define HAVE_TEX2_VERTICES 0
77 #define HAVE_TEX3_VERTICES 0
78 #define HAVE_PTEX_VERTICES 1
79
80 /*
81 #define SUBPIXEL_X -.5
82 #define SUBPIXEL_Y -.5
83 #define UNVIEWPORT_VARS GLfloat h = S3V_CONTEXT(ctx)->driDrawable->h
84 #define UNVIEWPORT_X(x) x - SUBPIXEL_X
85 #define UNVIEWPORT_Y(y) - y + h + SUBPIXEL_Y
86 #define UNVIEWPORT_Z(z) z / vmesa->depth_scale
87 */
88
89 #define PTEX_FALLBACK() /* never needed */
90
91 #define IMPORT_QUALIFIER
92 #define IMPORT_FLOAT_COLORS s3v_import_float_colors
93 #define IMPORT_FLOAT_SPEC_COLORS s3v_import_float_spec_colors
94
95 #define INTERP_VERTEX setup_tab[S3V_CONTEXT(ctx)->SetupIndex].interp
96 #define COPY_PV_VERTEX setup_tab[S3V_CONTEXT(ctx)->SetupIndex].copy_pv
97
98
99
100 /***********************************************************************
101 * Generate pv-copying and translation functions *
102 ***********************************************************************/
103
104 #define TAG(x) s3v_##x
105 #include "tnl_dd/t_dd_vb.c"
106
107 /***********************************************************************
108 * Generate vertex emit and interp functions *
109 ***********************************************************************/
110
111
112 #define IND (S3V_XYZW_BIT|S3V_RGBA_BIT)
113 #define TAG(x) x##_wg
114 #include "tnl_dd/t_dd_vbtmp.h"
115
116 #define IND (S3V_XYZW_BIT|S3V_RGBA_BIT|S3V_TEX0_BIT)
117 #define TAG(x) x##_wgt0
118 #include "tnl_dd/t_dd_vbtmp.h"
119
120 #define IND (S3V_XYZW_BIT|S3V_RGBA_BIT|S3V_TEX0_BIT|S3V_PTEX_BIT)
121 #define TAG(x) x##_wgpt0
122 #include "tnl_dd/t_dd_vbtmp.h"
123
124 #define IND (S3V_TEX0_BIT)
125 #define TAG(x) x##_t0
126 #include "tnl_dd/t_dd_vbtmp.h"
127
128 #define IND (S3V_RGBA_BIT)
129 #define TAG(x) x##_g
130 #include "tnl_dd/t_dd_vbtmp.h"
131
132 #define IND (S3V_RGBA_BIT|S3V_TEX0_BIT)
133 #define TAG(x) x##_gt0
134 #include "tnl_dd/t_dd_vbtmp.h"
135
136 #define IND (S3V_XYZW_BIT|S3V_RGBA_BIT|S3V_FOG_BIT)
137 #define TAG(x) x##_wgf
138 #include "tnl_dd/t_dd_vbtmp.h"
139
140 #define IND (S3V_XYZW_BIT|S3V_RGBA_BIT|S3V_FOG_BIT|S3V_TEX0_BIT)
141 #define TAG(x) x##_wgft0
142 #include "tnl_dd/t_dd_vbtmp.h"
143
144 #define IND (S3V_XYZW_BIT|S3V_RGBA_BIT|S3V_FOG_BIT|S3V_TEX0_BIT|S3V_PTEX_BIT)
145 #define TAG(x) x##_wgfpt0
146 #include "tnl_dd/t_dd_vbtmp.h"
147
148 #define IND (S3V_FOG_BIT)
149 #define TAG(x) x##_f
150 #include "tnl_dd/t_dd_vbtmp.h"
151
152 #define IND (S3V_RGBA_BIT | S3V_FOG_BIT)
153 #define TAG(x) x##_gf
154 #include "tnl_dd/t_dd_vbtmp.h"
155
156 #define IND (S3V_RGBA_BIT | S3V_FOG_BIT | S3V_TEX0_BIT)
157 #define TAG(x) x##_gft0
158 #include "tnl_dd/t_dd_vbtmp.h"
159
160 static void init_setup_tab( void )
161 {
162 init_wg(); /* pos + col */
163 init_wgt0(); /* pos + col + tex0 */
164 init_wgpt0(); /* pos + col + p-tex0 (?) */
165 init_t0(); /* tex0 */
166 init_g(); /* col */
167 init_gt0(); /* col + tex */
168 init_wgf();
169 init_wgft0();
170 init_wgfpt0();
171 init_f();
172 init_gf();
173 init_gft0();
174 }
175
176
177 #if 0
178 void s3vPrintSetupFlags(char *msg, GLuint flags )
179 {
180 fprintf(stderr, "%s(%x): %s%s%s%s%s%s\n",
181 msg,
182 (int)flags,
183 (flags & S3V_XYZW_BIT) ? " xyzw," : "",
184 (flags & S3V_RGBA_BIT) ? " rgba," : "",
185 (flags & S3V_SPEC_BIT) ? " spec," : "",
186 (flags & S3V_FOG_BIT) ? " fog," : "",
187 (flags & S3V_TEX0_BIT) ? " tex-0," : "",
188 (flags & S3V_TEX1_BIT) ? " tex-1," : "");
189 }
190 #endif
191
192
193 void s3vCheckTexSizes( GLcontext *ctx )
194 {
195 TNLcontext *tnl = TNL_CONTEXT(ctx);
196 s3vContextPtr vmesa = S3V_CONTEXT( ctx );
197
198 if (!setup_tab[vmesa->SetupIndex].check_tex_sizes(ctx)) {
199
200 vmesa->SetupIndex |= (S3V_PTEX_BIT|S3V_RGBA_BIT);
201
202 if (1 || !(ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) {
203 tnl->Driver.Render.Interp = setup_tab[vmesa->SetupIndex].interp;
204 tnl->Driver.Render.CopyPV = setup_tab[vmesa->SetupIndex].copy_pv;
205 }
206 }
207 }
208
209 void s3vBuildVertices( GLcontext *ctx,
210 GLuint start,
211 GLuint count,
212 GLuint newinputs )
213 {
214 s3vContextPtr vmesa = S3V_CONTEXT( ctx );
215 GLubyte *v = ((GLubyte *)vmesa->verts +
216 (start<<vmesa->vertex_stride_shift));
217 GLuint stride = 1<<vmesa->vertex_stride_shift;
218
219 DEBUG(("*** s3vBuildVertices ***\n"));
220 DEBUG(("vmesa->SetupNewInputs = 0x%x\n", vmesa->SetupNewInputs));
221 DEBUG(("vmesa->SetupIndex = 0x%x\n", vmesa->SetupIndex));
222
223 #if 1
224 setup_tab[vmesa->SetupIndex].emit( ctx, start, count, v, stride );
225 #else
226 newinputs |= vmesa->SetupNewInputs;
227 vmesa->SetupNewInputs = 0;
228
229 DEBUG(("newinputs is 0x%x\n", newinputs));
230
231 if (!newinputs) {
232 DEBUG(("!newinputs\n"));
233 return;
234 }
235
236 if (newinputs & VERT_CLIP) {
237 setup_tab[vmesa->SetupIndex].emit( ctx, start, count, v, stride );
238 DEBUG(("newinputs & VERT_CLIP\n"));
239 return;
240 } /* else { */
241 /* GLuint ind = 0; */
242
243 if (newinputs & VERT_RGBA) {
244 DEBUG(("newinputs & VERT_RGBA\n"));
245 ind |= S3V_RGBA_BIT;
246 }
247
248 if (newinputs & VERT_TEX0) {
249 DEBUG(("newinputs & VERT_TEX0\n"));
250 ind |= S3V_TEX0_BIT;
251 }
252
253 if (newinputs & VERT_FOG_COORD)
254 ind |= S3V_FOG_BIT;
255
256 if (vmesa->SetupIndex & S3V_PTEX_BIT)
257 ind = ~0;
258
259 ind &= vmesa->SetupIndex;
260
261 DEBUG(("vmesa->SetupIndex = 0x%x\n", vmesa->SetupIndex));
262 DEBUG(("ind = 0x%x\n", ind));
263 DEBUG(("ind & vmesa->SetupIndex = 0x%x\n", (ind & vmesa->SetupIndex)));
264
265 if (ind) {
266 setup_tab[ind].emit( ctx, start, count, v, stride );
267 }
268 #endif
269 }
270
271 void s3vChooseVertexState( GLcontext *ctx )
272 {
273 s3vContextPtr vmesa = S3V_CONTEXT( ctx );
274 TNLcontext *tnl = TNL_CONTEXT(ctx);
275
276 GLuint ind = S3V_XYZW_BIT | S3V_RGBA_BIT;
277
278 /* FIXME: will segv in tnl_dd/t_dd_vbtmp.h (line 196) on some demos */
279 /*
280 if (ctx->Fog.Enabled)
281 ind |= S3V_FOG_BIT;
282 */
283
284
285 if (ctx->Texture.Unit[0]._ReallyEnabled) {
286 _tnl_need_projected_coords( ctx, GL_FALSE );
287 ind |= S3V_TEX0_BIT;
288 } else {
289 _tnl_need_projected_coords( ctx, GL_TRUE );
290 }
291
292 vmesa->SetupIndex = ind;
293
294 if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED)) {
295 tnl->Driver.Render.Interp = s3v_interp_extras;
296 tnl->Driver.Render.CopyPV = s3v_copy_pv_extras;
297 } else {
298 tnl->Driver.Render.Interp = setup_tab[ind].interp;
299 tnl->Driver.Render.CopyPV = setup_tab[ind].copy_pv;
300 }
301 }
302
303
304 void s3vInitVB( GLcontext *ctx )
305 {
306 s3vContextPtr vmesa = S3V_CONTEXT(ctx);
307 GLuint size = TNL_CONTEXT(ctx)->vb.Size;
308
309 vmesa->verts = (char *)ALIGN_MALLOC(size * 4 * 16, 32);
310
311 {
312 static int firsttime = 1;
313 if (firsttime) {
314 init_setup_tab();
315 firsttime = 0;
316 vmesa->vertex_stride_shift = 6 /* 4 */; /* FIXME - only one vertex setup */
317 }
318 }
319 }
320
321
322 void s3vFreeVB( GLcontext *ctx )
323 {
324 s3vContextPtr vmesa = S3V_CONTEXT(ctx);
325 if (vmesa->verts) {
326 ALIGN_FREE(vmesa->verts);
327 vmesa->verts = 0;
328 }
329
330 if (vmesa->UbyteSecondaryColor.Ptr) {
331 ALIGN_FREE((void *)vmesa->UbyteSecondaryColor.Ptr);
332 vmesa->UbyteSecondaryColor.Ptr = 0;
333 }
334
335 if (vmesa->UbyteColor.Ptr) {
336 ALIGN_FREE((void *)vmesa->UbyteColor.Ptr);
337 vmesa->UbyteColor.Ptr = 0;
338 }
339 }