1 /**************************************************************************
3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
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:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
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.
26 **************************************************************************/
29 * Binning code for triangles
32 #include "util/u_math.h"
33 #include "util/u_memory.h"
35 #include "lp_setup_context.h"
37 #include "lp_state_fs.h"
39 #define NUM_CHANNELS 4
45 /* fixed point vertex coordinates */
49 /* float x,y deltas - all from the original coordinates
66 subpixel_snap(float a
)
68 return util_iround(FIXED_ONE
* a
);
74 return a
* (1.0 / FIXED_ONE
);
80 * Compute a0 for a constant-valued coefficient (GL_FLAT shading).
82 static void constant_coef( struct lp_rast_triangle
*tri
,
87 tri
->inputs
.a0
[slot
][i
] = value
;
88 tri
->inputs
.dadx
[slot
][i
] = 0.0f
;
89 tri
->inputs
.dady
[slot
][i
] = 0.0f
;
94 static void linear_coef( struct lp_rast_triangle
*tri
,
95 const struct tri_info
*info
,
100 float a0
= info
->v0
[vert_attr
][i
];
101 float a1
= info
->v1
[vert_attr
][i
];
102 float a2
= info
->v2
[vert_attr
][i
];
104 float da01
= a0
- a1
;
105 float da20
= a2
- a0
;
106 float dadx
= (da01
* info
->dy20
- info
->dy01
* da20
) * info
->oneoverarea
;
107 float dady
= (da20
* info
->dx01
- info
->dx20
* da01
) * info
->oneoverarea
;
109 tri
->inputs
.dadx
[slot
][i
] = dadx
;
110 tri
->inputs
.dady
[slot
][i
] = dady
;
112 /* calculate a0 as the value which would be sampled for the
113 * fragment at (0,0), taking into account that we want to sample at
114 * pixel centers, in other words (0.5, 0.5).
116 * this is neat but unfortunately not a good way to do things for
117 * triangles with very large values of dadx or dady as it will
118 * result in the subtraction and re-addition from a0 of a very
119 * large number, which means we'll end up loosing a lot of the
120 * fractional bits and precision from a0. the way to fix this is
121 * to define a0 as the sample at a pixel center somewhere near vmin
122 * instead - i'll switch to this later.
124 tri
->inputs
.a0
[slot
][i
] = (a0
-
125 (dadx
* (info
->v0
[0][0] - info
->pixel_offset
) +
126 dady
* (info
->v0
[0][1] - info
->pixel_offset
)));
131 * Compute a0, dadx and dady for a perspective-corrected interpolant,
133 * We basically multiply the vertex value by 1/w before computing
134 * the plane coefficients (a0, dadx, dady).
135 * Later, when we compute the value at a particular fragment position we'll
136 * divide the interpolated value by the interpolated W at that fragment.
138 static void perspective_coef( struct lp_rast_triangle
*tri
,
139 const struct tri_info
*info
,
144 /* premultiply by 1/w (v[0][3] is always 1/w):
146 float a0
= info
->v0
[vert_attr
][i
] * info
->v0
[0][3];
147 float a1
= info
->v1
[vert_attr
][i
] * info
->v1
[0][3];
148 float a2
= info
->v2
[vert_attr
][i
] * info
->v2
[0][3];
149 float da01
= a0
- a1
;
150 float da20
= a2
- a0
;
151 float dadx
= (da01
* info
->dy20
- info
->dy01
* da20
) * info
->oneoverarea
;
152 float dady
= (da20
* info
->dx01
- info
->dx20
* da01
) * info
->oneoverarea
;
154 tri
->inputs
.dadx
[slot
][i
] = dadx
;
155 tri
->inputs
.dady
[slot
][i
] = dady
;
156 tri
->inputs
.a0
[slot
][i
] = (a0
-
157 (dadx
* (info
->v0
[0][0] - info
->pixel_offset
) +
158 dady
* (info
->v0
[0][1] - info
->pixel_offset
)));
163 * Special coefficient setup for gl_FragCoord.
164 * X and Y are trivial
165 * Z and W are copied from position_coef which should have already been computed.
166 * We could do a bit less work if we'd examine gl_FragCoord's swizzle mask.
169 setup_fragcoord_coef(struct lp_rast_triangle
*tri
,
170 const struct tri_info
*info
,
175 if (usage_mask
& TGSI_WRITEMASK_X
) {
176 tri
->inputs
.a0
[slot
][0] = 0.0;
177 tri
->inputs
.dadx
[slot
][0] = 1.0;
178 tri
->inputs
.dady
[slot
][0] = 0.0;
182 if (usage_mask
& TGSI_WRITEMASK_Y
) {
183 tri
->inputs
.a0
[slot
][1] = 0.0;
184 tri
->inputs
.dadx
[slot
][1] = 0.0;
185 tri
->inputs
.dady
[slot
][1] = 1.0;
189 if (usage_mask
& TGSI_WRITEMASK_Z
) {
190 linear_coef(tri
, info
, slot
, 0, 2);
194 if (usage_mask
& TGSI_WRITEMASK_W
) {
195 linear_coef(tri
, info
, slot
, 0, 3);
201 * Setup the fragment input attribute with the front-facing value.
202 * \param frontface is the triangle front facing?
204 static void setup_facing_coef( struct lp_rast_triangle
*tri
,
209 /* convert TRUE to 1.0 and FALSE to -1.0 */
210 if (usage_mask
& TGSI_WRITEMASK_X
)
211 constant_coef( tri
, slot
, 2.0f
* frontface
- 1.0f
, 0 );
213 if (usage_mask
& TGSI_WRITEMASK_Y
)
214 constant_coef( tri
, slot
, 0.0f
, 1 ); /* wasted */
216 if (usage_mask
& TGSI_WRITEMASK_Z
)
217 constant_coef( tri
, slot
, 0.0f
, 2 ); /* wasted */
219 if (usage_mask
& TGSI_WRITEMASK_W
)
220 constant_coef( tri
, slot
, 0.0f
, 3 ); /* wasted */
225 * Compute the tri->coef[] array dadx, dady, a0 values.
227 static void setup_tri_coefficients( struct lp_setup_context
*setup
,
228 struct lp_rast_triangle
*tri
,
229 const struct tri_info
*info
)
231 unsigned fragcoord_usage_mask
= TGSI_WRITEMASK_XYZ
;
235 /* setup interpolation for all the remaining attributes:
237 for (slot
= 0; slot
< setup
->fs
.nr_inputs
; slot
++) {
238 unsigned vert_attr
= setup
->fs
.input
[slot
].src_index
;
239 unsigned usage_mask
= setup
->fs
.input
[slot
].usage_mask
;
241 switch (setup
->fs
.input
[slot
].interp
) {
242 case LP_INTERP_CONSTANT
:
243 if (setup
->flatshade_first
) {
244 for (i
= 0; i
< NUM_CHANNELS
; i
++)
245 if (usage_mask
& (1 << i
))
246 constant_coef(tri
, slot
+1, info
->v0
[vert_attr
][i
], i
);
249 for (i
= 0; i
< NUM_CHANNELS
; i
++)
250 if (usage_mask
& (1 << i
))
251 constant_coef(tri
, slot
+1, info
->v2
[vert_attr
][i
], i
);
255 case LP_INTERP_LINEAR
:
256 for (i
= 0; i
< NUM_CHANNELS
; i
++)
257 if (usage_mask
& (1 << i
))
258 linear_coef(tri
, info
, slot
+1, vert_attr
, i
);
261 case LP_INTERP_PERSPECTIVE
:
262 for (i
= 0; i
< NUM_CHANNELS
; i
++)
263 if (usage_mask
& (1 << i
))
264 perspective_coef(tri
, info
, slot
+1, vert_attr
, i
);
265 fragcoord_usage_mask
|= TGSI_WRITEMASK_W
;
268 case LP_INTERP_POSITION
:
270 * The generated pixel interpolators will pick up the coeffs from
271 * slot 0, so all need to ensure that the usage mask is covers all
274 fragcoord_usage_mask
|= usage_mask
;
277 case LP_INTERP_FACING
:
278 setup_facing_coef(tri
, slot
+1, info
->frontfacing
, usage_mask
);
286 /* The internal position input is in slot zero:
288 setup_fragcoord_coef(tri
, info
, 0, fragcoord_usage_mask
);
291 for (i
= 0; i
< NUM_CHANNELS
; i
++) {
292 float a0
= tri
->inputs
.a0
[0][i
];
293 float dadx
= tri
->inputs
.dadx
[0][i
];
294 float dady
= tri
->inputs
.dady
[0][i
];
296 debug_printf("POS.%c: a0 = %f, dadx = %f, dady = %f\n",
301 for (slot
= 0; slot
< setup
->fs
.nr_inputs
; slot
++) {
302 unsigned usage_mask
= setup
->fs
.input
[slot
].usage_mask
;
303 for (i
= 0; i
< NUM_CHANNELS
; i
++) {
304 if (usage_mask
& (1 << i
)) {
305 float a0
= tri
->inputs
.a0
[1 + slot
][i
];
306 float dadx
= tri
->inputs
.dadx
[1 + slot
][i
];
307 float dady
= tri
->inputs
.dady
[1 + slot
][i
];
309 debug_printf("IN[%u].%c: a0 = %f, dadx = %f, dady = %f\n",
325 * Alloc space for a new triangle plus the input.a0/dadx/dady arrays
326 * immediately after it.
327 * The memory is allocated from the per-scene pool, not per-tile.
328 * \param tri_size returns number of bytes allocated
329 * \param nr_inputs number of fragment shader inputs
330 * \return pointer to triangle space
332 static INLINE
struct lp_rast_triangle
*
333 alloc_triangle(struct lp_scene
*scene
,
338 unsigned input_array_sz
= NUM_CHANNELS
* (nr_inputs
+ 1) * sizeof(float);
339 struct lp_rast_triangle
*tri
;
340 unsigned tri_bytes
, bytes
;
343 tri_bytes
= align(Offset(struct lp_rast_triangle
, plane
[nr_planes
]), 16);
344 bytes
= tri_bytes
+ (3 * input_array_sz
);
346 tri
= lp_scene_alloc_aligned( scene
, bytes
, 16 );
349 inputs
= ((char *)tri
) + tri_bytes
;
350 tri
->inputs
.a0
= (float (*)[4]) inputs
;
351 tri
->inputs
.dadx
= (float (*)[4]) (inputs
+ input_array_sz
);
352 tri
->inputs
.dady
= (float (*)[4]) (inputs
+ 2 * input_array_sz
);
361 lp_setup_print_vertex(struct lp_setup_context
*setup
,
367 debug_printf(" wpos (%s[0]) xyzw %f %f %f %f\n",
369 v
[0][0], v
[0][1], v
[0][2], v
[0][3]);
371 for (i
= 0; i
< setup
->fs
.nr_inputs
; i
++) {
372 const float *in
= v
[setup
->fs
.input
[i
].src_index
];
374 debug_printf(" in[%d] (%s[%d]) %s%s%s%s ",
376 name
, setup
->fs
.input
[i
].src_index
,
377 (setup
->fs
.input
[i
].usage_mask
& 0x1) ? "x" : " ",
378 (setup
->fs
.input
[i
].usage_mask
& 0x2) ? "y" : " ",
379 (setup
->fs
.input
[i
].usage_mask
& 0x4) ? "z" : " ",
380 (setup
->fs
.input
[i
].usage_mask
& 0x8) ? "w" : " ");
382 for (j
= 0; j
< 4; j
++)
383 if (setup
->fs
.input
[i
].usage_mask
& (1<<j
))
384 debug_printf("%.5f ", in
[j
]);
392 * Print triangle vertex attribs (for debug).
395 lp_setup_print_triangle(struct lp_setup_context
*setup
,
396 const float (*v0
)[4],
397 const float (*v1
)[4],
398 const float (*v2
)[4])
400 debug_printf("triangle\n");
403 const float ex
= v0
[0][0] - v2
[0][0];
404 const float ey
= v0
[0][1] - v2
[0][1];
405 const float fx
= v1
[0][0] - v2
[0][0];
406 const float fy
= v1
[0][1] - v2
[0][1];
408 /* det = cross(e,f).z */
409 const float det
= ex
* fy
- ey
* fx
;
411 debug_printf(" - ccw\n");
413 debug_printf(" - cw\n");
415 debug_printf(" - zero area\n");
418 lp_setup_print_vertex(setup
, "v0", v0
);
419 lp_setup_print_vertex(setup
, "v1", v1
);
420 lp_setup_print_vertex(setup
, "v2", v2
);
424 lp_rast_cmd lp_rast_tri_tab
[8] = {
425 NULL
, /* should be impossible */
436 * Do basic setup for triangle rasterization and determine which
437 * framebuffer tiles are touched. Put the triangle in the scene's
438 * bins for the tiles which we overlap.
441 do_triangle_ccw(struct lp_setup_context
*setup
,
442 const float (*v1
)[4],
443 const float (*v2
)[4],
444 const float (*v3
)[4],
445 boolean frontfacing
)
448 struct lp_scene
*scene
= lp_setup_get_current_scene(setup
);
449 struct lp_fragment_shader_variant
*variant
= setup
->fs
.current
.variant
;
450 struct lp_rast_triangle
*tri
;
451 struct tri_info info
;
453 int minx
, maxx
, miny
, maxy
;
454 int ix0
, ix1
, iy0
, iy1
;
460 lp_setup_print_triangle(setup
, v1
, v2
, v3
);
462 if (setup
->scissor_test
) {
470 tri
= alloc_triangle(scene
,
478 tri
->v
[0][0] = v1
[0][0];
479 tri
->v
[1][0] = v2
[0][0];
480 tri
->v
[2][0] = v3
[0][0];
481 tri
->v
[0][1] = v1
[0][1];
482 tri
->v
[1][1] = v2
[0][1];
483 tri
->v
[2][1] = v3
[0][1];
486 /* x/y positions in fixed point */
487 info
.x
[0] = subpixel_snap(v1
[0][0] - setup
->pixel_offset
);
488 info
.x
[1] = subpixel_snap(v2
[0][0] - setup
->pixel_offset
);
489 info
.x
[2] = subpixel_snap(v3
[0][0] - setup
->pixel_offset
);
490 info
.y
[0] = subpixel_snap(v1
[0][1] - setup
->pixel_offset
);
491 info
.y
[1] = subpixel_snap(v2
[0][1] - setup
->pixel_offset
);
492 info
.y
[2] = subpixel_snap(v3
[0][1] - setup
->pixel_offset
);
494 tri
->plane
[0].dcdy
= info
.x
[0] - info
.x
[1];
495 tri
->plane
[1].dcdy
= info
.x
[1] - info
.x
[2];
496 tri
->plane
[2].dcdy
= info
.x
[2] - info
.x
[0];
498 tri
->plane
[0].dcdx
= info
.y
[0] - info
.y
[1];
499 tri
->plane
[1].dcdx
= info
.y
[1] - info
.y
[2];
500 tri
->plane
[2].dcdx
= info
.y
[2] - info
.y
[0];
502 area
= (tri
->plane
[0].dcdy
* tri
->plane
[2].dcdx
-
503 tri
->plane
[2].dcdy
* tri
->plane
[0].dcdx
);
507 /* Cull non-ccw and zero-sized triangles.
509 * XXX: subject to overflow??
512 lp_scene_putback_data( scene
, tri_bytes
);
513 LP_COUNT(nr_culled_tris
);
517 /* Bounding rectangle (in pixels) */
519 /* Yes this is necessary to accurately calculate bounding boxes
520 * with the two fill-conventions we support. GL (normally) ends
521 * up needing a bottom-left fill convention, which requires
522 * slightly different rounding.
524 int adj
= (setup
->pixel_offset
!= 0) ? 1 : 0;
526 minx
= (MIN3(info
.x
[0], info
.x
[1], info
.x
[2]) + (FIXED_ONE
-1)) >> FIXED_ORDER
;
527 maxx
= (MAX3(info
.x
[0], info
.x
[1], info
.x
[2]) + (FIXED_ONE
-1)) >> FIXED_ORDER
;
528 miny
= (MIN3(info
.y
[0], info
.y
[1], info
.y
[2]) + (FIXED_ONE
-1) + adj
) >> FIXED_ORDER
;
529 maxy
= (MAX3(info
.y
[0], info
.y
[1], info
.y
[2]) + (FIXED_ONE
-1) + adj
) >> FIXED_ORDER
;
532 if (setup
->scissor_test
) {
533 minx
= MAX2(minx
, setup
->scissor
.current
.minx
);
534 maxx
= MIN2(maxx
, setup
->scissor
.current
.maxx
);
535 miny
= MAX2(miny
, setup
->scissor
.current
.miny
);
536 maxy
= MIN2(maxy
, setup
->scissor
.current
.maxy
);
539 minx
= MAX2(minx
, 0);
540 miny
= MAX2(miny
, 0);
541 maxx
= MIN2(maxx
, scene
->fb
.width
);
542 maxy
= MIN2(maxy
, scene
->fb
.height
);
546 if (miny
>= maxy
|| minx
>= maxx
) {
547 lp_scene_putback_data( scene
, tri_bytes
);
548 LP_COUNT(nr_culled_tris
);
554 info
.pixel_offset
= setup
->pixel_offset
;
558 info
.dx01
= info
.v0
[0][0] - info
.v1
[0][0];
559 info
.dx20
= info
.v2
[0][0] - info
.v0
[0][0];
560 info
.dy01
= info
.v0
[0][1] - info
.v1
[0][1];
561 info
.dy20
= info
.v2
[0][1] - info
.v0
[0][1];
562 info
.oneoverarea
= 1.0f
/ (info
.dx01
* info
.dy20
- info
.dx20
* info
.dy01
);
563 info
.frontfacing
= frontfacing
;
565 /* Setup parameter interpolants:
567 setup_tri_coefficients( setup
, tri
, &info
);
569 tri
->inputs
.facing
= frontfacing
? 1.0F
: -1.0F
;
570 tri
->inputs
.state
= setup
->fs
.stored
;
574 for (i
= 0; i
< 3; i
++) {
575 struct lp_rast_plane
*plane
= &tri
->plane
[i
];
577 /* half-edge constants, will be interated over the whole render
580 plane
->c
= plane
->dcdx
* info
.x
[i
] - plane
->dcdy
* info
.y
[i
];
582 /* correct for top-left vs. bottom-left fill convention.
584 * note that we're overloading gl_rasterization_rules to mean
585 * both (0.5,0.5) pixel centers *and* bottom-left filling
588 * GL actually has a top-left filling convention, but GL's
589 * notion of "top" differs from gallium's...
591 * Also, sometimes (in FBO cases) GL will render upside down
592 * to its usual method, in which case it will probably want
593 * to use the opposite, top-left convention.
595 if (plane
->dcdx
< 0) {
596 /* both fill conventions want this - adjust for left edges */
599 else if (plane
->dcdx
== 0) {
600 if (setup
->pixel_offset
== 0) {
601 /* correct for top-left fill convention:
603 if (plane
->dcdy
> 0) plane
->c
++;
606 /* correct for bottom-left fill convention:
608 if (plane
->dcdy
< 0) plane
->c
++;
612 plane
->dcdx
*= FIXED_ONE
;
613 plane
->dcdy
*= FIXED_ONE
;
615 /* find trivial reject offsets for each edge for a single-pixel
616 * sized block. These will be scaled up at each recursive level to
617 * match the active blocksize. Scaling in this way works best if
618 * the blocks are square.
621 if (plane
->dcdx
< 0) plane
->eo
-= plane
->dcdx
;
622 if (plane
->dcdy
> 0) plane
->eo
+= plane
->dcdy
;
624 /* Calculate trivial accept offsets from the above.
626 plane
->ei
= plane
->dcdy
- plane
->dcdx
- plane
->eo
;
631 * When rasterizing scissored tris, use the intersection of the
632 * triangle bounding box and the scissor rect to generate the
635 * This permits us to cut off the triangle "tails" that are present
636 * in the intermediate recursive levels caused when two of the
637 * triangles edges don't diverge quickly enough to trivially reject
638 * exterior blocks from the triangle.
640 * It's not really clear if it's worth worrying about these tails,
641 * but since we generate the planes for each scissored tri, it's
642 * free to trim them in this case.
644 * Note that otherwise, the scissor planes only vary in 'C' value,
645 * and even then only on state-changes. Could alternatively store
646 * these planes elsewhere.
648 if (nr_planes
== 7) {
649 tri
->plane
[3].dcdx
= -1;
650 tri
->plane
[3].dcdy
= 0;
651 tri
->plane
[3].c
= 1-minx
;
652 tri
->plane
[3].ei
= 0;
653 tri
->plane
[3].eo
= 1;
655 tri
->plane
[4].dcdx
= 1;
656 tri
->plane
[4].dcdy
= 0;
657 tri
->plane
[4].c
= maxx
;
658 tri
->plane
[4].ei
= -1;
659 tri
->plane
[4].eo
= 0;
661 tri
->plane
[5].dcdx
= 0;
662 tri
->plane
[5].dcdy
= 1;
663 tri
->plane
[5].c
= 1-miny
;
664 tri
->plane
[5].ei
= 0;
665 tri
->plane
[5].eo
= 1;
667 tri
->plane
[6].dcdx
= 0;
668 tri
->plane
[6].dcdy
= -1;
669 tri
->plane
[6].c
= maxy
;
670 tri
->plane
[6].ei
= -1;
671 tri
->plane
[6].eo
= 0;
676 * All fields of 'tri' are now set. The remaining code here is
677 * concerned with binning.
680 /* Convert to tile coordinates, and inclusive ranges:
682 if (nr_planes
== 3) {
685 int ix1
= (maxx
-1) / 16;
686 int iy1
= (maxy
-1) / 16;
688 if (iy0
== iy1
&& ix0
== ix1
)
691 /* Triangle is contained in a single 16x16 block:
693 int mask
= (ix0
& 3) | ((iy0
& 3) << 4);
695 lp_scene_bin_command( scene
, ix0
/4, iy0
/4,
696 lp_rast_triangle_3_16
,
697 lp_rast_arg_triangle(tri
, mask
) );
702 ix0
= minx
/ TILE_SIZE
;
703 iy0
= miny
/ TILE_SIZE
;
704 ix1
= (maxx
-1) / TILE_SIZE
;
705 iy1
= (maxy
-1) / TILE_SIZE
;
708 * Clamp to framebuffer size
710 assert(ix0
== MAX2(ix0
, 0));
711 assert(iy0
== MAX2(iy0
, 0));
712 assert(ix1
== MIN2(ix1
, scene
->tiles_x
- 1));
713 assert(iy1
== MIN2(iy1
, scene
->tiles_y
- 1));
715 /* Determine which tile(s) intersect the triangle's bounding box
717 if (iy0
== iy1
&& ix0
== ix1
)
719 /* Triangle is contained in a single tile:
721 lp_scene_bin_command( scene
, ix0
, iy0
,
722 lp_rast_tri_tab
[nr_planes
],
723 lp_rast_arg_triangle(tri
, (1<<nr_planes
)-1) );
734 for (i
= 0; i
< nr_planes
; i
++) {
735 c
[i
] = (tri
->plane
[i
].c
+
736 tri
->plane
[i
].dcdy
* iy0
* TILE_SIZE
-
737 tri
->plane
[i
].dcdx
* ix0
* TILE_SIZE
);
739 ei
[i
] = tri
->plane
[i
].ei
<< TILE_ORDER
;
740 eo
[i
] = tri
->plane
[i
].eo
<< TILE_ORDER
;
741 xstep
[i
] = -(tri
->plane
[i
].dcdx
<< TILE_ORDER
);
742 ystep
[i
] = tri
->plane
[i
].dcdy
<< TILE_ORDER
;
747 /* Test tile-sized blocks against the triangle.
748 * Discard blocks fully outside the tri. If the block is fully
749 * contained inside the tri, bin an lp_rast_shade_tile command.
750 * Else, bin a lp_rast_triangle command.
752 for (y
= iy0
; y
<= iy1
; y
++)
754 boolean in
= FALSE
; /* are we inside the triangle? */
757 for (i
= 0; i
< nr_planes
; i
++)
760 for (x
= ix0
; x
<= ix1
; x
++)
765 for (i
= 0; i
< nr_planes
; i
++) {
766 int planeout
= cx
[i
] + eo
[i
];
767 int planepartial
= cx
[i
] + ei
[i
] - 1;
768 out
|= (planeout
>> 31);
769 partial
|= (planepartial
>> 31) & (1<<i
);
775 break; /* exiting triangle, all done with this row */
776 LP_COUNT(nr_empty_64
);
779 /* Not trivially accepted by at least one plane -
780 * rasterize/shade partial tile
782 int count
= util_bitcount(partial
);
784 lp_scene_bin_command( scene
, x
, y
,
785 lp_rast_tri_tab
[count
],
786 lp_rast_arg_triangle(tri
, partial
) );
788 LP_COUNT(nr_partially_covered_64
);
791 /* triangle covers the whole tile- shade whole tile */
792 LP_COUNT(nr_fully_covered_64
);
794 if (variant
->opaque
&&
796 lp_scene_bin_reset( scene
, x
, y
);
798 lp_scene_bin_command( scene
, x
, y
,
800 lp_rast_arg_inputs(&tri
->inputs
) );
803 /* Iterate cx values across the region:
805 for (i
= 0; i
< nr_planes
; i
++)
809 /* Iterate c values down the region:
811 for (i
= 0; i
< nr_planes
; i
++)
819 * Draw triangle if it's CW, cull otherwise.
821 static void triangle_cw( struct lp_setup_context
*setup
,
822 const float (*v0
)[4],
823 const float (*v1
)[4],
824 const float (*v2
)[4] )
826 do_triangle_ccw( setup
, v1
, v0
, v2
, !setup
->ccw_is_frontface
);
831 * Draw triangle if it's CCW, cull otherwise.
833 static void triangle_ccw( struct lp_setup_context
*setup
,
834 const float (*v0
)[4],
835 const float (*v1
)[4],
836 const float (*v2
)[4] )
838 do_triangle_ccw( setup
, v0
, v1
, v2
, setup
->ccw_is_frontface
);
844 * Draw triangle whether it's CW or CCW.
846 static void triangle_both( struct lp_setup_context
*setup
,
847 const float (*v0
)[4],
848 const float (*v1
)[4],
849 const float (*v2
)[4] )
851 /* edge vectors e = v0 - v2, f = v1 - v2 */
852 const float ex
= v0
[0][0] - v2
[0][0];
853 const float ey
= v0
[0][1] - v2
[0][1];
854 const float fx
= v1
[0][0] - v2
[0][0];
855 const float fy
= v1
[0][1] - v2
[0][1];
857 /* det = cross(e,f).z */
858 const float det
= ex
* fy
- ey
* fx
;
860 triangle_ccw( setup
, v0
, v1
, v2
);
862 triangle_cw( setup
, v0
, v1
, v2
);
866 static void triangle_nop( struct lp_setup_context
*setup
,
867 const float (*v0
)[4],
868 const float (*v1
)[4],
869 const float (*v2
)[4] )
875 lp_setup_choose_triangle( struct lp_setup_context
*setup
)
877 switch (setup
->cullmode
) {
879 setup
->triangle
= triangle_both
;
882 setup
->triangle
= setup
->ccw_is_frontface
? triangle_ccw
: triangle_cw
;
884 case PIPE_FACE_FRONT
:
885 setup
->triangle
= setup
->ccw_is_frontface
? triangle_cw
: triangle_ccw
;
888 setup
->triangle
= triangle_nop
;