Fixed off by one errors in clipping.
[mesa.git] / src / mesa / drivers / dri / unichrome / via_vb.c
1 /*
2 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
4 *
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, sub license,
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:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
14 * of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25 #include "glheader.h"
26 #include "mtypes.h"
27 #include "imports.h"
28 #include "macros.h"
29 #include "colormac.h"
30
31 #include "swrast_setup/swrast_setup.h"
32 #include "tnl/t_context.h"
33
34 #include "via_context.h"
35 #include "via_vb.h"
36 #include "via_ioctl.h"
37 #include "via_tris.h"
38 #include "via_state.h"
39
40 static struct {
41 void (*emit)(GLcontext *, GLuint, GLuint, void *, GLuint);
42 tnl_interp_func interp;
43 tnl_copy_pv_func copyPv;
44 GLboolean (*check_tex_sizes)(GLcontext *ctx);
45 GLuint vertexSize;
46 GLuint vertexStrideShift;
47 GLuint vertexFormat;
48 } setup_tab[VIA_MAX_SETUP];
49
50 #define TINY_VERTEX_FORMAT 1
51 #define NOTEX_VERTEX_FORMAT 2
52 #define TEX0_VERTEX_FORMAT 3
53 #define TEX1_VERTEX_FORMAT 4
54
55 #define PROJ_TEX1_VERTEX_FORMAT 0
56 #define TEX2_VERTEX_FORMAT 0
57 #define TEX3_VERTEX_FORMAT 0
58 #define PROJ_TEX3_VERTEX_FORMAT 0
59
60 #define DO_XYZW (IND & VIA_XYZW_BIT)
61 #define DO_RGBA (IND & VIA_RGBA_BIT)
62 #define DO_SPEC (IND & VIA_SPEC_BIT)
63 #define DO_FOG (IND & VIA_FOG_BIT)
64 #define DO_TEX0 (IND & VIA_TEX0_BIT)
65 #define DO_TEX1 (IND & VIA_TEX1_BIT)
66 #define DO_TEX2 0
67 #define DO_TEX3 0
68 #define DO_PTEX (IND & VIA_PTEX_BIT)
69
70 #define VERTEX viaVertex
71 #define VERTEX_COLOR via_color_t
72 #define GET_VIEWPORT_MAT() VIA_CONTEXT(ctx)->ViewportMatrix.m
73 #define GET_TEXSOURCE(n) n
74 #define GET_VERTEX_FORMAT() VIA_CONTEXT(ctx)->vertexSize
75 #define GET_VERTEX_SIZE() VIA_CONTEXT(ctx)->vertexSize
76 #define GET_VERTEX_STORE() VIA_CONTEXT(ctx)->verts
77 #define GET_VERTEX_STRIDE_SHIFT() VIA_CONTEXT(ctx)->vertexStrideShift
78 #define GET_UBYTE_COLOR_STORE() &VIA_CONTEXT(ctx)->UbyteColor
79 #define GET_UBYTE_SPEC_COLOR_STORE() &VIA_CONTEXT(ctx)->UbyteSecondaryColor
80 #define INVALIDATE_STORED_VERTICES()
81
82 #define HAVE_HW_VIEWPORT 0
83 #define HAVE_HW_DIVIDE 0
84 #define HAVE_RGBA_COLOR 0
85 #define HAVE_TINY_VERTICES 1
86 #define HAVE_NOTEX_VERTICES 1
87 #define HAVE_TEX0_VERTICES 1
88 #define HAVE_TEX1_VERTICES 1
89 #define HAVE_TEX2_VERTICES 0
90 #define HAVE_TEX3_VERTICES 0
91 #define HAVE_PTEX_VERTICES 0
92
93 #define UNVIEWPORT_VARS GLfloat h = VIA_CONTEXT(ctx)->driDrawable->h
94 #define UNVIEWPORT_X(x) x - SUBPIXEL_X
95 #define UNVIEWPORT_Y(y) - y + h + SUBPIXEL_Y
96 #define UNVIEWPORT_Z(z) z * (float)0xffffffff
97
98 #define PTEX_FALLBACK() FALLBACK(VIA_CONTEXT(ctx), VIA_FALLBACK_TEXTURE, 1)
99
100 #define IMPORT_FLOAT_COLORS via_import_float_colors
101 #define IMPORT_FLOAT_SPEC_COLORS via_import_float_spec_colors
102
103 #define INTERP_VERTEX setup_tab[VIA_CONTEXT(ctx)->setupIndex].interp
104 #define COPY_PV_VERTEX setup_tab[VIA_CONTEXT(ctx)->setupIndex].copyPv
105
106
107 /***********************************************************************
108 * Generate pv-copying and translation functions *
109 ***********************************************************************/
110
111 #define TAG(x) via_##x
112 #include "tnl_dd/t_dd_vb.c"
113
114 /***********************************************************************
115 * Generate vertex emit and interp functions *
116 ***********************************************************************/
117 #define IND (VIA_XYZW_BIT | VIA_RGBA_BIT)
118 #define TAG(x) x##_wg
119 #include "via_dd_vbtmp.h"
120
121 #define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_SPEC_BIT)
122 #define TAG(x) x##_wgs
123 #include "via_dd_vbtmp.h"
124
125 #define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_TEX0_BIT)
126 #define TAG(x) x##_wgt0
127 #include "via_dd_vbtmp.h"
128
129 #define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_TEX0_BIT | VIA_TEX1_BIT)
130 #define TAG(x) x##_wgt0t1
131 #include "via_dd_vbtmp.h"
132
133 #define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_TEX0_BIT | VIA_PTEX_BIT)
134 #define TAG(x) x##_wgpt0
135 #include "via_dd_vbtmp.h"
136
137 #define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_TEX0_BIT | VIA_TEX1_BIT |\
138 VIA_PTEX_BIT)
139 #define TAG(x) x##_wgpt0t1
140 #include "via_dd_vbtmp.h"
141
142 #define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_SPEC_BIT | VIA_TEX0_BIT)
143 #define TAG(x) x##_wgst0
144 #include "via_dd_vbtmp.h"
145
146 #define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_SPEC_BIT | VIA_TEX0_BIT |\
147 VIA_TEX1_BIT)
148 #define TAG(x) x##_wgst0t1
149 #include "via_dd_vbtmp.h"
150
151 #define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_SPEC_BIT | VIA_TEX0_BIT |\
152 VIA_PTEX_BIT)
153 #define TAG(x) x##_wgspt0
154 #include "via_dd_vbtmp.h"
155
156 #define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_SPEC_BIT | VIA_TEX0_BIT |\
157 VIA_TEX1_BIT | VIA_PTEX_BIT)
158 #define TAG(x) x##_wgspt0t1
159 #include "via_dd_vbtmp.h"
160
161 #define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_FOG_BIT)
162 #define TAG(x) x##_wgf
163 #include "via_dd_vbtmp.h"
164
165 #define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_FOG_BIT | VIA_SPEC_BIT)
166 #define TAG(x) x##_wgfs
167 #include "via_dd_vbtmp.h"
168
169 #define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_FOG_BIT | VIA_TEX0_BIT)
170 #define TAG(x) x##_wgft0
171 #include "via_dd_vbtmp.h"
172
173 #define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_FOG_BIT | VIA_TEX0_BIT |\
174 VIA_TEX1_BIT)
175 #define TAG(x) x##_wgft0t1
176 #include "via_dd_vbtmp.h"
177
178 #define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_FOG_BIT | VIA_TEX0_BIT |\
179 VIA_PTEX_BIT)
180 #define TAG(x) x##_wgfpt0
181 #include "via_dd_vbtmp.h"
182
183 #define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_FOG_BIT | VIA_TEX0_BIT |\
184 VIA_TEX1_BIT | VIA_PTEX_BIT)
185 #define TAG(x) x##_wgfpt0t1
186 #include "via_dd_vbtmp.h"
187
188 #define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_FOG_BIT | VIA_SPEC_BIT |\
189 VIA_TEX0_BIT)
190 #define TAG(x) x##_wgfst0
191 #include "via_dd_vbtmp.h"
192
193 #define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_FOG_BIT | VIA_SPEC_BIT |\
194 VIA_TEX0_BIT | VIA_TEX1_BIT)
195 #define TAG(x) x##_wgfst0t1
196 #include "via_dd_vbtmp.h"
197
198 #define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_FOG_BIT | VIA_SPEC_BIT |\
199 VIA_TEX0_BIT | VIA_PTEX_BIT)
200 #define TAG(x) x##_wgfspt0
201 #include "via_dd_vbtmp.h"
202
203 #define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_FOG_BIT | VIA_SPEC_BIT |\
204 VIA_TEX0_BIT | VIA_TEX1_BIT | VIA_PTEX_BIT)
205 #define TAG(x) x##_wgfspt0t1
206 #include "via_dd_vbtmp.h"
207
208 static void init_setup_tab(void) {
209
210 init_wg();
211 init_wgs();
212 init_wgt0();
213 init_wgt0t1();
214 init_wgpt0();
215 init_wgpt0t1();
216 init_wgst0();
217 init_wgst0t1();
218 init_wgspt0();
219 init_wgspt0t1();
220 init_wgf();
221 init_wgfs();
222 init_wgft0();
223 init_wgft0t1();
224 init_wgfpt0();
225 init_wgfpt0t1();
226 init_wgfst0();
227 init_wgfst0t1();
228 init_wgfspt0();
229 init_wgfspt0t1();
230 }
231
232 void viaPrintSetupFlags(char *msg, GLuint flags) {
233 #ifdef DEBUG
234 if (VIA_DEBUG) fprintf(stderr, "%s(%x): %s%s%s%s%s%s\n",
235 msg,
236 (int)flags,
237 (flags & VIA_XYZW_BIT) ? " xyzw," : "",
238 (flags & VIA_RGBA_BIT) ? " rgba," : "",
239 (flags & VIA_SPEC_BIT) ? " spec," : "",
240 (flags & VIA_FOG_BIT) ? " fog," : "",
241 (flags & VIA_TEX0_BIT) ? " tex-0," : "",
242 (flags & VIA_TEX1_BIT) ? " tex-1," : "");
243 #endif
244 }
245
246 void viaCheckTexSizes(GLcontext *ctx) {
247 TNLcontext *tnl = TNL_CONTEXT(ctx);
248 viaContextPtr vmesa = VIA_CONTEXT(ctx);
249 #ifdef DEBUG
250 if (VIA_DEBUG) {
251 fprintf(stderr, "%s - in\n", __FUNCTION__);
252 fprintf(stderr, "setupIndex = %x\n", vmesa->setupIndex);
253 }
254 #endif
255 if (!setup_tab[vmesa->setupIndex].check_tex_sizes(ctx)) {
256 /* Invalidate stored verts
257 */
258 vmesa->setupNewInputs = ~0;
259 vmesa->setupIndex |= VIA_PTEX_BIT;
260
261 if (!vmesa->Fallback &&
262 !(ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) {
263 tnl->Driver.Render.Interp = setup_tab[vmesa->setupIndex].interp;
264 tnl->Driver.Render.CopyPV = setup_tab[vmesa->setupIndex].copyPv;
265 }
266 }
267 #ifdef DEBUG
268 if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
269 #endif
270 }
271
272 void viaBuildVertices(GLcontext *ctx,
273 GLuint start,
274 GLuint count,
275 GLuint newinputs)
276 {
277 viaContextPtr vmesa = VIA_CONTEXT(ctx);
278 GLubyte *v = ((GLubyte *)vmesa->verts + (start << vmesa->vertexStrideShift));
279 GLuint stride = 1 << vmesa->vertexStrideShift;
280 #ifdef DEBUG
281 if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
282 #endif
283 newinputs |= vmesa->setupNewInputs;
284 vmesa->setupNewInputs = 0;
285 if (!newinputs)
286 return;
287 if (newinputs & VERT_BIT_CLIP) {
288 setup_tab[vmesa->setupIndex].emit(ctx, start, count, v, stride);
289 }
290 else {
291 GLuint ind = 0;
292
293 if (newinputs & VERT_BIT_COLOR0)
294 ind |= VIA_RGBA_BIT;
295
296 if (newinputs & VERT_BIT_COLOR1)
297 ind |= VIA_SPEC_BIT;
298
299 if (newinputs & VERT_BIT_TEX0)
300 ind |= VIA_TEX0_BIT;
301
302 if (newinputs & VERT_BIT_TEX1)
303 ind |= VIA_TEX1_BIT;
304
305 if (newinputs & VERT_BIT_FOG)
306 ind |= VIA_FOG_BIT;
307
308 if (vmesa->setupIndex & VIA_PTEX_BIT)
309 ind = ~0;
310
311 ind &= vmesa->setupIndex;
312 ind |= VIA_XYZW_BIT;
313
314 if (ind) {
315 setup_tab[ind].emit(ctx, start, count, v, stride);
316 }
317 }
318 #ifdef DEBUG
319 if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
320 #endif
321 }
322
323 void viaChooseVertexState(GLcontext *ctx) {
324 TNLcontext *tnl = TNL_CONTEXT(ctx);
325 viaContextPtr vmesa = VIA_CONTEXT(ctx);
326 GLuint ind = VIA_XYZW_BIT | VIA_RGBA_BIT;
327 #ifdef DEBUG
328 if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
329 #endif
330 if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
331 ind |= VIA_SPEC_BIT;
332
333 if (ctx->Fog.Enabled)
334 ind |= VIA_FOG_BIT;
335
336 if (ctx->Texture._EnabledUnits > 1)
337 ind |= VIA_TEX1_BIT | VIA_TEX0_BIT;
338 else if (ctx->Texture._EnabledUnits == 1)
339 ind |= VIA_TEX0_BIT;
340
341 vmesa->setupIndex = ind;
342 #ifdef DEBUG
343 if (VIA_DEBUG) fprintf(stderr, "setupIndex = %x\n", vmesa->setupIndex);
344 #endif
345
346 if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED)) {
347 tnl->Driver.Render.Interp = via_interp_extras;
348 tnl->Driver.Render.CopyPV = via_copy_pv_extras;
349 }
350 else {
351 tnl->Driver.Render.Interp = setup_tab[ind].interp;
352 tnl->Driver.Render.CopyPV = setup_tab[ind].copyPv;
353 }
354
355 vmesa->vertexSize = setup_tab[ind].vertexSize;
356 vmesa->vertexStrideShift = setup_tab[ind].vertexStrideShift;
357 #ifdef DEBUG
358 if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
359 #endif
360
361 }
362
363 void via_emit_contiguous_verts(GLcontext *ctx,
364 GLuint start,
365 GLuint count) {
366 viaContextPtr vmesa = VIA_CONTEXT(ctx);
367 GLuint vertexSize = vmesa->vertexSize * 4;
368 GLuint *dest = viaCheckDma(vmesa, (count - start) * vertexSize);
369 #ifdef DEBUG
370 if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
371
372 if (VIA_DEBUG) fprintf(stderr, "choose setup_tab[0x%x]\n", vmesa->setupIndex);
373 #endif
374 setup_tab[vmesa->setupIndex].emit(ctx, start, count, dest, vertexSize);
375 vmesa->dmaLow += (count - start) * vertexSize;
376 #ifdef DEBUG
377 if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
378 #endif
379 }
380
381 void viaInitVB(GLcontext *ctx) {
382 viaContextPtr vmesa = VIA_CONTEXT(ctx);
383 GLuint size = TNL_CONTEXT(ctx)->vb.Size;
384
385 vmesa->verts = ALIGN_MALLOC(size * 4 * 16, 32);
386
387 {
388 static int firsttime = 1;
389 if (firsttime) {
390 init_setup_tab();
391 firsttime = 0;
392 }
393 }
394 }
395
396 void viaFreeVB(GLcontext *ctx) {
397 viaContextPtr vmesa = VIA_CONTEXT(ctx);
398
399 if (vmesa->verts) {
400 ALIGN_FREE(vmesa->verts);
401 vmesa->verts = 0;
402 }
403
404 if (vmesa->UbyteSecondaryColor.Ptr) {
405 ALIGN_FREE((void*)vmesa->UbyteSecondaryColor.Ptr);
406 vmesa->UbyteSecondaryColor.Ptr = 0;
407 }
408
409 if (vmesa->UbyteColor.Ptr) {
410 ALIGN_FREE((void*)vmesa->UbyteColor.Ptr);
411 vmesa->UbyteColor.Ptr = 0;
412 }
413 }