zink: fix line-width calculation
authorDuncan Hopkins <duncan@thefoundry.co.uk>
Wed, 10 Jul 2019 13:50:16 +0000 (14:50 +0100)
committerErik Faye-Lund <erik.faye-lund@collabora.com>
Mon, 28 Oct 2019 08:51:48 +0000 (08:51 +0000)
There's two things that goes wrong in this code on some drivers:
1. Rounding off the line-width to granularity can push it outside the
   legal range.
2. A granularity of 0.0 results in NaN, because we divide by zero.

So let's make this code a bit more robust.

Acked-by: Jordan Justen <jordan.l.justen@intel.com>
src/gallium/drivers/zink/zink_state.c

index 709627079d81199ab53a7945f703a2da5d99c11e..07da1be2bf8ab1c763499f3beb99bd2c9a28d079 100644 (file)
@@ -359,7 +359,19 @@ zink_delete_depth_stencil_alpha_state(struct pipe_context *pctx,
 static float
 round_to_granularity(float value, float granularity)
 {
-   return (float)(round(value / granularity) * granularity);
+   return roundf(value / granularity) * granularity;
+}
+
+static float
+line_width(float width, float granularity, const float range[2])
+{
+   assert(granularity >= 0);
+   assert(range[0] <= range[1]);
+
+   if (granularity > 0)
+      width = round_to_granularity(width, granularity);
+
+   return CLAMP(width, range[0], range[1]);
 }
 
 static void *
@@ -395,8 +407,9 @@ zink_create_rasterizer_state(struct pipe_context *pctx,
    state->offset_clamp = rs_state->offset_clamp;
    state->offset_scale = rs_state->offset_scale;
 
-   state->line_width = round_to_granularity(rs_state->line_width,
-                                     screen->props.limits.lineWidthGranularity);
+   state->line_width = line_width(rs_state->line_width,
+                                  screen->props.limits.lineWidthGranularity,
+                                  screen->props.limits.lineWidthRange);
 
    return state;
 }