llvmpipe: precalculate some offsets
[mesa.git] / src / gallium / drivers / llvmpipe / lp_setup_tri.c
1 /**************************************************************************
2 *
3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28 /*
29 * Binning code for triangles
30 */
31
32 #include "lp_setup_context.h"
33 #include "lp_rast.h"
34 #include "util/u_math.h"
35 #include "util/u_memory.h"
36
37 #define NUM_CHANNELS 4
38
39 /**
40 * Compute a0 for a constant-valued coefficient (GL_FLAT shading).
41 */
42 static void constant_coef( struct lp_rast_triangle *tri,
43 unsigned slot,
44 const float value,
45 unsigned i )
46 {
47 tri->inputs.a0[slot][i] = value;
48 tri->inputs.dadx[slot][i] = 0;
49 tri->inputs.dady[slot][i] = 0;
50 }
51
52 /**
53 * Compute a0, dadx and dady for a linearly interpolated coefficient,
54 * for a triangle.
55 */
56 static void linear_coef( struct lp_rast_triangle *tri,
57 unsigned slot,
58 const float (*v1)[4],
59 const float (*v2)[4],
60 const float (*v3)[4],
61 unsigned vert_attr,
62 unsigned i)
63 {
64 float a1 = v1[vert_attr][i];
65 float a2 = v2[vert_attr][i];
66 float a3 = v3[vert_attr][i];
67
68 float da12 = a1 - a2;
69 float da31 = a3 - a1;
70 float dadx = (da12 * tri->dy31 - tri->dy12 * da31) * tri->oneoverarea;
71 float dady = (da31 * tri->dx12 - tri->dx31 * da12) * tri->oneoverarea;
72
73 tri->inputs.dadx[slot][i] = dadx;
74 tri->inputs.dady[slot][i] = dady;
75
76 /* calculate a0 as the value which would be sampled for the
77 * fragment at (0,0), taking into account that we want to sample at
78 * pixel centers, in other words (0.5, 0.5).
79 *
80 * this is neat but unfortunately not a good way to do things for
81 * triangles with very large values of dadx or dady as it will
82 * result in the subtraction and re-addition from a0 of a very
83 * large number, which means we'll end up loosing a lot of the
84 * fractional bits and precision from a0. the way to fix this is
85 * to define a0 as the sample at a pixel center somewhere near vmin
86 * instead - i'll switch to this later.
87 */
88 tri->inputs.a0[slot][i] = (v1[vert_attr][i] -
89 (dadx * (v1[0][0] - 0.5f) +
90 dady * (v1[0][1] - 0.5f)));
91 }
92
93
94 /**
95 * Compute a0, dadx and dady for a perspective-corrected interpolant,
96 * for a triangle.
97 * We basically multiply the vertex value by 1/w before computing
98 * the plane coefficients (a0, dadx, dady).
99 * Later, when we compute the value at a particular fragment position we'll
100 * divide the interpolated value by the interpolated W at that fragment.
101 */
102 static void perspective_coef( struct lp_rast_triangle *tri,
103 unsigned slot,
104 const float (*v1)[4],
105 const float (*v2)[4],
106 const float (*v3)[4],
107 unsigned vert_attr,
108 unsigned i)
109 {
110 /* premultiply by 1/w (v[0][3] is always 1/w):
111 */
112 float a1 = v1[vert_attr][i] * v1[0][3];
113 float a2 = v2[vert_attr][i] * v2[0][3];
114 float a3 = v3[vert_attr][i] * v3[0][3];
115 float da12 = a1 - a2;
116 float da31 = a3 - a1;
117 float dadx = (da12 * tri->dy31 - tri->dy12 * da31) * tri->oneoverarea;
118 float dady = (da31 * tri->dx12 - tri->dx31 * da12) * tri->oneoverarea;
119
120
121 tri->inputs.dadx[slot][i] = dadx;
122 tri->inputs.dady[slot][i] = dady;
123 tri->inputs.a0[slot][i] = (a1 -
124 (dadx * (v1[0][0] - 0.5f) +
125 dady * (v1[0][1] - 0.5f)));
126 }
127
128
129 /**
130 * Special coefficient setup for gl_FragCoord.
131 * X and Y are trivial, though Y has to be inverted for OpenGL.
132 * Z and W are copied from position_coef which should have already been computed.
133 * We could do a bit less work if we'd examine gl_FragCoord's swizzle mask.
134 */
135 static void
136 setup_fragcoord_coef(struct lp_rast_triangle *tri,
137 unsigned slot,
138 const float (*v1)[4],
139 const float (*v2)[4],
140 const float (*v3)[4])
141 {
142 /*X*/
143 tri->inputs.a0[slot][0] = 0.0;
144 tri->inputs.dadx[slot][0] = 1.0;
145 tri->inputs.dady[slot][0] = 0.0;
146 /*Y*/
147 tri->inputs.a0[slot][1] = 0.0;
148 tri->inputs.dadx[slot][1] = 0.0;
149 tri->inputs.dady[slot][1] = 1.0;
150 /*Z*/
151 linear_coef(tri, slot, v1, v2, v3, 0, 2);
152 /*W*/
153 linear_coef(tri, slot, v1, v2, v3, 0, 3);
154 }
155
156
157 static void setup_facing_coef( struct lp_rast_triangle *tri,
158 unsigned slot,
159 boolean frontface )
160 {
161 constant_coef( tri, slot, 1.0f - frontface, 0 );
162 constant_coef( tri, slot, 0.0f, 1 ); /* wasted */
163 constant_coef( tri, slot, 0.0f, 2 ); /* wasted */
164 constant_coef( tri, slot, 0.0f, 3 ); /* wasted */
165 }
166
167
168 /**
169 * Compute the tri->coef[] array dadx, dady, a0 values.
170 */
171 static void setup_tri_coefficients( struct setup_context *setup,
172 struct lp_rast_triangle *tri,
173 const float (*v1)[4],
174 const float (*v2)[4],
175 const float (*v3)[4],
176 boolean frontface )
177 {
178 unsigned slot;
179
180 /* The internal position input is in slot zero:
181 */
182 setup_fragcoord_coef(tri, 0, v1, v2, v3);
183
184 /* setup interpolation for all the remaining attrbutes:
185 */
186 for (slot = 0; slot < setup->fs.nr_inputs; slot++) {
187 unsigned vert_attr = setup->fs.input[slot].src_index;
188 unsigned i;
189
190 switch (setup->fs.input[slot].interp) {
191 case LP_INTERP_CONSTANT:
192 for (i = 0; i < NUM_CHANNELS; i++)
193 constant_coef(tri, slot+1, v3[vert_attr][i], i);
194 break;
195
196 case LP_INTERP_LINEAR:
197 for (i = 0; i < NUM_CHANNELS; i++)
198 linear_coef(tri, slot+1, v1, v2, v3, vert_attr, i);
199 break;
200
201 case LP_INTERP_PERSPECTIVE:
202 for (i = 0; i < NUM_CHANNELS; i++)
203 perspective_coef(tri, slot+1, v1, v2, v3, vert_attr, i);
204 break;
205
206 case LP_INTERP_POSITION:
207 /* XXX: fix me - duplicates the values in slot zero.
208 */
209 setup_fragcoord_coef(tri, slot+1, v1, v2, v3);
210 break;
211
212 case LP_INTERP_FACING:
213 setup_facing_coef(tri, slot+1, frontface);
214 break;
215
216 default:
217 assert(0);
218 }
219 }
220 }
221
222
223
224 /* XXX: do this by add/subtracting a large floating point number:
225 */
226 static inline int subpixel_snap( float a )
227 {
228 return util_iround(FIXED_ONE * a);
229 }
230
231
232 static INLINE void bin_triangle( struct cmd_block_list *list,
233 const struct lp_rast_triangle arg )
234 {
235 }
236
237
238 /* to avoid having to allocate power-of-four, square render targets,
239 * end up having a specialized version of the above that runs only at
240 * the topmost level.
241 *
242 * at the topmost level there may be an arbitary number of steps on
243 * either dimension, so this loop needs to be either separately
244 * code-generated and unrolled for each render target size, or kept as
245 * generic looping code:
246 */
247
248 #define MIN3(a,b,c) MIN2(MIN2(a,b),c)
249 #define MAX3(a,b,c) MAX2(MAX2(a,b),c)
250
251 static void
252 do_triangle_ccw(struct setup_context *setup,
253 const float (*v1)[4],
254 const float (*v2)[4],
255 const float (*v3)[4],
256 boolean frontfacing )
257 {
258
259 const int y1 = subpixel_snap(v1[0][1]);
260 const int y2 = subpixel_snap(v2[0][1]);
261 const int y3 = subpixel_snap(v3[0][1]);
262
263 const int x1 = subpixel_snap(v1[0][0]);
264 const int x2 = subpixel_snap(v2[0][0]);
265 const int x3 = subpixel_snap(v3[0][0]);
266
267 struct lp_rast_triangle *tri = get_data( &setup->data, sizeof *tri );
268 float area;
269 int minx, maxx, miny, maxy;
270
271 tri->dx12 = x1 - x2;
272 tri->dx23 = x2 - x3;
273 tri->dx31 = x3 - x1;
274
275 tri->dy12 = y1 - y2;
276 tri->dy23 = y2 - y3;
277 tri->dy31 = y3 - y1;
278
279 area = (tri->dx12 * tri->dy31 -
280 tri->dx31 * tri->dy12);
281
282 /* Cull non-ccw and zero-sized triangles.
283 *
284 * XXX: subject to overflow??
285 */
286 if (area <= 0) {
287 putback_data( &setup->data, sizeof *tri );
288 return;
289 }
290
291 // Bounding rectangle
292 tri->minx = (MIN3(x1, x2, x3) + 0xf) >> FIXED_ORDER;
293 tri->maxx = (MAX3(x1, x2, x3) + 0xf) >> FIXED_ORDER;
294 tri->miny = (MIN3(y1, y2, y3) + 0xf) >> FIXED_ORDER;
295 tri->maxy = (MAX3(y1, y2, y3) + 0xf) >> FIXED_ORDER;
296
297 if (tri->miny == tri->maxy ||
298 tri->minx == tri->maxx) {
299 putback_data( &setup->data, sizeof *tri );
300 return;
301 }
302
303 tri->inputs.state = setup->fs.stored;
304
305 /*
306 */
307 tri->oneoverarea = ((float)FIXED_ONE) / (float)area;
308
309 /* Setup parameter interpolants:
310 */
311 setup_tri_coefficients( setup, tri, v1, v2, v3, frontfacing );
312
313 /* half-edge constants, will be interated over the whole
314 * rendertarget.
315 */
316 tri->c1 = tri->dy12 * x1 - tri->dx12 * y1;
317 tri->c2 = tri->dy23 * x2 - tri->dx23 * y2;
318 tri->c3 = tri->dy31 * x3 - tri->dx31 * y3;
319
320 /* correct for top-left fill convention:
321 */
322 if (tri->dy12 < 0 || (tri->dy12 == 0 && tri->dx12 > 0)) tri->c1++;
323 if (tri->dy23 < 0 || (tri->dy23 == 0 && tri->dx23 > 0)) tri->c2++;
324 if (tri->dy31 < 0 || (tri->dy31 == 0 && tri->dx31 > 0)) tri->c3++;
325
326 tri->dy12 *= FIXED_ONE;
327 tri->dy23 *= FIXED_ONE;
328 tri->dy31 *= FIXED_ONE;
329
330 tri->dx12 *= FIXED_ONE;
331 tri->dx23 *= FIXED_ONE;
332 tri->dx31 *= FIXED_ONE;
333
334 /* find trivial reject offsets for each edge for a single-pixel
335 * sized block. These will be scaled up at each recursive level to
336 * match the active blocksize. Scaling in this way works best if
337 * the blocks are square.
338 */
339 tri->eo1 = 0;
340 if (tri->dy12 < 0) tri->eo1 -= tri->dy12;
341 if (tri->dx12 > 0) tri->eo1 += tri->dx12;
342
343 tri->eo2 = 0;
344 if (tri->dy23 < 0) tri->eo2 -= tri->dy23;
345 if (tri->dx23 > 0) tri->eo2 += tri->dx23;
346
347 tri->eo3 = 0;
348 if (tri->dy31 < 0) tri->eo3 -= tri->dy31;
349 if (tri->dx31 > 0) tri->eo3 += tri->dx31;
350
351 /* Calculate trivial accept offsets from the above.
352 */
353 tri->ei1 = tri->dx12 - tri->dy12 - tri->eo1;
354 tri->ei2 = tri->dx23 - tri->dy23 - tri->eo2;
355 tri->ei3 = tri->dx31 - tri->dy31 - tri->eo3;
356
357 minx = tri->minx / TILESIZE;
358 miny = tri->miny / TILESIZE;
359 maxx = tri->maxx / TILESIZE;
360 maxy = tri->maxy / TILESIZE;
361
362 {
363 int xstep1 = -tri->dy12;
364 int xstep2 = -tri->dy23;
365 int xstep3 = -tri->dy31;
366
367 int ystep1 = tri->dx12;
368 int ystep2 = tri->dx23;
369 int ystep3 = tri->dx31;
370
371 int ix, iy;
372 int qx, qy;
373 int i = 0;
374
375 for (qy = 0; qy < 4; qy += 2) {
376 for (qx = 0; qx < 4; qx += 2) {
377 for (iy = 0; iy < 2; iy++) {
378 for (ix = 0; ix < 2; ix++, i++) {
379 tri->step[0][i] = (xstep1 * (qx+ix)) + (ystep1 * (qy+iy));
380 tri->step[1][i] = (xstep2 * (qx+ix)) + (ystep2 * (qy+iy));
381 tri->step[2][i] = (xstep3 * (qx+ix)) + (ystep3 * (qy+iy));
382 }
383 }
384 }
385 }
386 }
387
388 /* Convert to tile coordinates:
389 */
390 if (miny == maxy && minx == maxx)
391 {
392 /* Triangle is contained in a single tile:
393 */
394 bin_command( &setup->tile[minx][miny], lp_rast_triangle,
395 lp_rast_arg_triangle(tri) );
396 }
397 else
398 {
399 int c1 = (tri->c1 +
400 tri->dx12 * miny * TILESIZE -
401 tri->dy12 * minx * TILESIZE);
402 int c2 = (tri->c2 +
403 tri->dx23 * miny * TILESIZE -
404 tri->dy23 * minx * TILESIZE);
405 int c3 = (tri->c3 +
406 tri->dx31 * miny * TILESIZE -
407 tri->dy31 * minx * TILESIZE);
408
409 int ei1 = tri->ei1 << TILE_ORDER;
410 int ei2 = tri->ei2 << TILE_ORDER;
411 int ei3 = tri->ei3 << TILE_ORDER;
412
413 int eo1 = tri->eo1 << TILE_ORDER;
414 int eo2 = tri->eo2 << TILE_ORDER;
415 int eo3 = tri->eo3 << TILE_ORDER;
416
417 int xstep1 = -(tri->dy12 << TILE_ORDER);
418 int xstep2 = -(tri->dy23 << TILE_ORDER);
419 int xstep3 = -(tri->dy31 << TILE_ORDER);
420
421 int ystep1 = tri->dx12 << TILE_ORDER;
422 int ystep2 = tri->dx23 << TILE_ORDER;
423 int ystep3 = tri->dx31 << TILE_ORDER;
424 int x, y;
425
426
427 /* Subdivide space into NxM blocks, where each block is square and
428 * power-of-four in dimension.
429 *
430 * Trivially accept or reject blocks, else jump to per-pixel
431 * examination above.
432 */
433 for (y = miny; y <= maxy; y++)
434 {
435 int cx1 = c1;
436 int cx2 = c2;
437 int cx3 = c3;
438
439 for (x = minx; x <= maxx; x++)
440 {
441 assert(cx1 ==
442 tri->c1 +
443 tri->dx12 * y * TILESIZE -
444 tri->dy12 * x * TILESIZE);
445 assert(cx2 ==
446 tri->c2 +
447 tri->dx23 * y * TILESIZE -
448 tri->dy23 * x * TILESIZE);
449 assert(cx3 ==
450 tri->c3 +
451 tri->dx31 * y * TILESIZE -
452 tri->dy31 * x * TILESIZE);
453
454 if (cx1 + eo1 < 0 ||
455 cx2 + eo2 < 0 ||
456 cx3 + eo3 < 0)
457 {
458 /* do nothing */
459 }
460 else if (cx1 + ei1 > 0 &&
461 cx2 + ei2 > 0 &&
462 cx3 + ei3 > 0)
463 {
464 /* shade whole tile */
465 bin_command( &setup->tile[x][y], lp_rast_shade_tile,
466 lp_rast_arg_inputs(&tri->inputs) );
467 }
468 else
469 {
470 /* shade partial tile */
471 bin_command( &setup->tile[x][y],
472 lp_rast_triangle,
473 lp_rast_arg_triangle(tri) );
474 }
475
476 /* Iterate cx values across the region:
477 */
478 cx1 += xstep1;
479 cx2 += xstep2;
480 cx3 += xstep3;
481 }
482
483 /* Iterate c values down the region:
484 */
485 c1 += ystep1;
486 c2 += ystep2;
487 c3 += ystep3;
488 }
489 }
490 }
491
492 static void triangle_cw( struct setup_context *setup,
493 const float (*v0)[4],
494 const float (*v1)[4],
495 const float (*v2)[4] )
496 {
497 do_triangle_ccw( setup, v1, v0, v2, !setup->ccw_is_frontface );
498 }
499
500 static void triangle_ccw( struct setup_context *setup,
501 const float (*v0)[4],
502 const float (*v1)[4],
503 const float (*v2)[4] )
504 {
505 do_triangle_ccw( setup, v0, v1, v2, setup->ccw_is_frontface );
506 }
507
508 static void triangle_both( struct setup_context *setup,
509 const float (*v0)[4],
510 const float (*v1)[4],
511 const float (*v2)[4] )
512 {
513 /* edge vectors e = v0 - v2, f = v1 - v2 */
514 const float ex = v0[0][0] - v2[0][0];
515 const float ey = v0[0][1] - v2[0][1];
516 const float fx = v1[0][0] - v2[0][0];
517 const float fy = v1[0][1] - v2[0][1];
518
519 /* det = cross(e,f).z */
520 if (ex * fy - ey * fx < 0)
521 triangle_ccw( setup, v0, v1, v2 );
522 else
523 triangle_cw( setup, v0, v1, v2 );
524 }
525
526 static void triangle_nop( struct setup_context *setup,
527 const float (*v0)[4],
528 const float (*v1)[4],
529 const float (*v2)[4] )
530 {
531 }
532
533
534 void
535 lp_setup_choose_triangle( struct setup_context *setup )
536 {
537 switch (setup->cullmode) {
538 case PIPE_WINDING_NONE:
539 setup->triangle = triangle_both;
540 break;
541 case PIPE_WINDING_CCW:
542 setup->triangle = triangle_cw;
543 break;
544 case PIPE_WINDING_CW:
545 setup->triangle = triangle_ccw;
546 break;
547 default:
548 setup->triangle = triangle_nop;
549 break;
550 }
551 }
552
553