[Mesa-dev] [PATCH 2/2] mesa: reduce CPU overhead when updating the viewport

Marek Olšák maraeo at gmail.com
Thu Aug 3 22:34:25 UTC 2017


Same thing about FLUSH_VERTICES as in patch 1.

Marek

On Wed, Aug 2, 2017 at 9:42 PM, Samuel Pitoiset
<samuel.pitoiset at gmail.com> wrote:
> Before:
> DrawElements (1 VBO, 8 UBO, 8 Tex) w/ viewport change: 3.61 million (43.7%)
>
> After:
> DrawElements (1 VBO, 8 UBO, 8 Tex) w/ viewport change: 4.95 million (60.2%)
>
> Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
> ---
>  src/mesa/main/viewport.c | 89 +++++++++++++++++++++++++++++++-----------------
>  1 file changed, 58 insertions(+), 31 deletions(-)
>
> diff --git a/src/mesa/main/viewport.c b/src/mesa/main/viewport.c
> index fc384909e6..ac23f2b93a 100644
> --- a/src/mesa/main/viewport.c
> +++ b/src/mesa/main/viewport.c
> @@ -35,6 +35,36 @@
>  #include "mtypes.h"
>  #include "viewport.h"
>
> +static bool
> +is_viewport_equal(struct gl_context *ctx, unsigned idx,
> +                  GLfloat x, GLfloat y, GLfloat width, GLfloat height)
> +{
> +   return ctx->ViewportArray[idx].X == x &&
> +          ctx->ViewportArray[idx].Width == width &&
> +          ctx->ViewportArray[idx].Y == y &&
> +          ctx->ViewportArray[idx].Height == height;
> +}
> +
> +static void
> +set_new_viewport(struct gl_context *ctx, unsigned idx,
> +                 GLfloat x, GLfloat y, GLfloat width, GLfloat height)
> +{
> +   ctx->ViewportArray[idx].X = x;
> +   ctx->ViewportArray[idx].Width = width;
> +   ctx->ViewportArray[idx].Y = y;
> +   ctx->ViewportArray[idx].Height = height;
> +}
> +
> +static void
> +flush_viewport(struct gl_context *ctx)
> +{
> +   FLUSH_VERTICES(ctx, ctx->DriverFlags.NewViewport ? 0 : _NEW_VIEWPORT);
> +   ctx->NewDriverState |= ctx->DriverFlags.NewViewport;
> +
> +   if (ctx->Driver.Viewport)
> +      ctx->Driver.Viewport(ctx);
> +}
> +
>  static void
>  clamp_viewport(struct gl_context *ctx, GLfloat *x, GLfloat *y,
>                 GLfloat *width, GLfloat *height)
> @@ -61,26 +91,6 @@ clamp_viewport(struct gl_context *ctx, GLfloat *x, GLfloat *y,
>     }
>  }
>
> -static void
> -set_viewport_no_notify(struct gl_context *ctx, unsigned idx,
> -                       GLfloat x, GLfloat y,
> -                       GLfloat width, GLfloat height)
> -{
> -   if (ctx->ViewportArray[idx].X == x &&
> -       ctx->ViewportArray[idx].Width == width &&
> -       ctx->ViewportArray[idx].Y == y &&
> -       ctx->ViewportArray[idx].Height == height)
> -      return;
> -
> -   FLUSH_VERTICES(ctx, ctx->DriverFlags.NewViewport ? 0 : _NEW_VIEWPORT);
> -   ctx->NewDriverState |= ctx->DriverFlags.NewViewport;
> -
> -   ctx->ViewportArray[idx].X = x;
> -   ctx->ViewportArray[idx].Width = width;
> -   ctx->ViewportArray[idx].Y = y;
> -   ctx->ViewportArray[idx].Height = height;
> -}
> -
>  struct gl_viewport_inputs {
>     GLfloat X, Y;                /**< position */
>     GLfloat Width, Height;       /**< size */
> @@ -95,6 +105,7 @@ viewport(struct gl_context *ctx, GLint x, GLint y, GLsizei width,
>           GLsizei height)
>  {
>     struct gl_viewport_inputs input = { x, y, width, height };
> +   bool changed = false;
>
>     /* Clamp the viewport to the implementation dependent values. */
>     clamp_viewport(ctx, &input.X, &input.Y, &input.Width, &input.Height);
> @@ -110,11 +121,17 @@ viewport(struct gl_context *ctx, GLint x, GLint y, GLsizei width,
>      * Set all of the viewports supported by the implementation, but only
>      * signal the driver once at the end.
>      */
> -   for (unsigned i = 0; i < ctx->Const.MaxViewports; i++)
> -      set_viewport_no_notify(ctx, i, input.X, input.Y, input.Width, input.Height);
> +   for (unsigned i = 0; i < ctx->Const.MaxViewports; i++) {
> +      if (!changed && is_viewport_equal(ctx, i, input.X, input.Y,
> +                                        input.Width, input.Height))
> +         continue;
>
> -   if (ctx->Driver.Viewport)
> -      ctx->Driver.Viewport(ctx);
> +      changed = true;
> +      set_new_viewport(ctx, i, x, y, width, height);
> +   }
> +
> +   if (changed)
> +      flush_viewport(ctx);
>  }
>
>  /**
> @@ -164,26 +181,36 @@ _mesa_set_viewport(struct gl_context *ctx, unsigned idx, GLfloat x, GLfloat y,
>                      GLfloat width, GLfloat height)
>  {
>     clamp_viewport(ctx, &x, &y, &width, &height);
> -   set_viewport_no_notify(ctx, idx, x, y, width, height);
>
> -   if (ctx->Driver.Viewport)
> -      ctx->Driver.Viewport(ctx);
> +   if (is_viewport_equal(ctx, idx, x, y, width, height))
> +      return;
> +
> +   set_new_viewport(ctx, idx, x, y, width, height);
> +   flush_viewport(ctx);
>  }
>
>  static void
>  viewport_array(struct gl_context *ctx, GLuint first, GLsizei count,
>                 struct gl_viewport_inputs *inputs)
>  {
> +   bool changed = false;
> +
>     for (GLsizei i = 0; i < count; i++) {
>        clamp_viewport(ctx, &inputs[i].X, &inputs[i].Y,
>                       &inputs[i].Width, &inputs[i].Height);
>
> -      set_viewport_no_notify(ctx, i + first, inputs[i].X, inputs[i].Y,
> -                             inputs[i].Width, inputs[i].Height);
> +      if (!changed && is_viewport_equal(ctx, i + first,
> +                                        inputs[i].X, inputs[i].Y,
> +                                        inputs[i].Width, inputs[i].Height))
> +         continue;
> +
> +      changed = true;
> +      set_new_viewport(ctx, i + first, inputs[i].X, inputs[i].Y,
> +                       inputs[i].Width, inputs[i].Height);
>     }
>
> -   if (ctx->Driver.Viewport)
> -      ctx->Driver.Viewport(ctx);
> +   if (changed)
> +      flush_viewport(ctx);
>  }
>
>  void GLAPIENTRY
> --
> 2.13.3
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list