[Mesa-dev] [PATCH 2/2] draw: fix different sign logic when clipping
Jose Fonseca
jfonseca at vmware.com
Tue Apr 24 20:34:07 UTC 2018
On 24/04/18 17:27, sroland at vmware.com wrote:
> From: Roland Scheidegger <sroland at vmware.com>
>
> The logic was flawed, since mul(x,y) will be <= 0 (exactly 0) when
> the sign is the same but both numbers are sufficiently small
> (if the product is smaller than 2^-128).
> This could apparently lead to emitting a sufficient amount of
> additional bogus vertices to overflow the allocated array for them,
> hitting an assertion (still safe with release builds since we just
> aborted clipping after the assertion in this case - I'm however unsure
> if this is now really no longer possible, so that code stays).
> Not sure if the additional vertices could cause other grief, I didn't
> see anything wrong even when hitting the assertion.
>
> Essentially, both +-0 are treated as positive (the vertex is considered
> to be inside the clip volume for this plane), so integrate the logic
> determining different sign into the branch there.
> ---
> src/gallium/auxiliary/draw/draw_pipe_clip.c | 13 ++++++-------
> 1 file changed, 6 insertions(+), 7 deletions(-)
>
> diff --git a/src/gallium/auxiliary/draw/draw_pipe_clip.c b/src/gallium/auxiliary/draw/draw_pipe_clip.c
> index b7a1b5c..6af5c09 100644
> --- a/src/gallium/auxiliary/draw/draw_pipe_clip.c
> +++ b/src/gallium/auxiliary/draw/draw_pipe_clip.c
> @@ -47,11 +47,6 @@
> /** Set to 1 to enable printing of coords before/after clipping */
> #define DEBUG_CLIP 0
>
> -
> -#ifndef DIFFERENT_SIGNS
> -#define DIFFERENT_SIGNS(x, y) ((x) * (y) <= 0.0F && (x) - (y) != 0.0F)
> -#endif
> -
> #define MAX_CLIPPED_VERTICES ((2 * (6 + PIPE_MAX_CLIP_PLANES))+1)
>
>
> @@ -479,6 +474,7 @@ do_clip_tri(struct draw_stage *stage,
> for (i = 1; i <= n; i++) {
> struct vertex_header *vert = inlist[i];
> boolean *edge = &inEdges[i];
> + boolean different_sign;
>
> float dp = getclipdist(clipper, vert, plane_idx);
>
> @@ -491,9 +487,12 @@ do_clip_tri(struct draw_stage *stage,
> return;
> outEdges[outcount] = *edge_prev;
> outlist[outcount++] = vert_prev;
> + different_sign = dp < 0.0f;
> + } else {
> + different_sign = !(dp < 0.0f);
> }
>
> - if (DIFFERENT_SIGNS(dp, dp_prev)) {
> + if (different_sign) {
> struct vertex_header *new_vert;
> boolean *new_edge;
>
> @@ -511,7 +510,7 @@ do_clip_tri(struct draw_stage *stage,
>
> if (dp < 0.0f) {
> /* Going out of bounds. Avoid division by zero as we
> - * know dp != dp_prev from DIFFERENT_SIGNS, above.
> + * know dp != dp_prev from different_sign, above.
> */
> float t = dp / (dp - dp_prev);
> interp( clipper, new_vert, t, vert, vert_prev, viewport_index );
>
Series looks good to me.
Reviewed-by: Jose Fonseca <jfonseca at vmware.com>
More information about the mesa-dev
mailing list