[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