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

Samuel Pitoiset samuel.pitoiset at gmail.com
Fri Aug 4 06:56:47 UTC 2017



On 08/04/2017 12:33 AM, Marek Olšák wrote:
> Hi Samuel,
> 
> FLUSH_VERTICES must be called *before* any of the states are changed, not after.

My mistake, please ignore this series...

Samuel.

> 
> 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/ scissor change: 3.67 million (44.4%)
>>
>> After:
>> DrawElements (1 VBO, 8 UBO, 8 Tex) w/ scissor change: 5.02 million (62.1%)
>>
>> Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
>> ---
>>   src/mesa/main/scissor.c | 79 ++++++++++++++++++++++++++++++-------------------
>>   1 file changed, 48 insertions(+), 31 deletions(-)
>>
>> diff --git a/src/mesa/main/scissor.c b/src/mesa/main/scissor.c
>> index b38db06bc8..c2d85bae2e 100644
>> --- a/src/mesa/main/scissor.c
>> +++ b/src/mesa/main/scissor.c
>> @@ -29,28 +29,20 @@
>>   #include "main/mtypes.h"
>>   #include "main/scissor.h"
>>
>> +static bool
>> +is_scissor_equal(struct gl_context *ctx, unsigned idx,
>> +                 GLint x, GLint y, GLsizei width, GLsizei height)
>> +{
>> +   return ctx->Scissor.ScissorArray[idx].X == x &&
>> +          ctx->Scissor.ScissorArray[idx].Y == y &&
>> +          ctx->Scissor.ScissorArray[idx].Width == width &&
>> +          ctx->Scissor.ScissorArray[idx].Height == height;
>> +}
>>
>> -/**
>> - * Set scissor rectangle data directly in ScissorArray
>> - *
>> - * This is an internal function that performs no error checking on the
>> - * supplied data.  It also does \b not call \c dd_function_table::Scissor.
>> - *
>> - * \sa _mesa_set_scissor
>> - */
>>   static void
>> -set_scissor_no_notify(struct gl_context *ctx, unsigned idx,
>> -                      GLint x, GLint y, GLsizei width, GLsizei height)
>> +set_new_scissor(struct gl_context *ctx, unsigned idx,
>> +                GLint x, GLint y, GLsizei width, GLsizei height)
>>   {
>> -   if (x == ctx->Scissor.ScissorArray[idx].X &&
>> -       y == ctx->Scissor.ScissorArray[idx].Y &&
>> -       width == ctx->Scissor.ScissorArray[idx].Width &&
>> -       height == ctx->Scissor.ScissorArray[idx].Height)
>> -      return;
>> -
>> -   FLUSH_VERTICES(ctx, ctx->DriverFlags.NewScissorRect ? 0 : _NEW_SCISSOR);
>> -   ctx->NewDriverState |= ctx->DriverFlags.NewScissorRect;
>> -
>>      ctx->Scissor.ScissorArray[idx].X = x;
>>      ctx->Scissor.ScissorArray[idx].Y = y;
>>      ctx->Scissor.ScissorArray[idx].Width = width;
>> @@ -58,8 +50,19 @@ set_scissor_no_notify(struct gl_context *ctx, unsigned idx,
>>   }
>>
>>   static void
>> +flush_scissor(struct gl_context *ctx)
>> +{
>> +   FLUSH_VERTICES(ctx, ctx->DriverFlags.NewScissorRect ? 0 : _NEW_SCISSOR);
>> +   ctx->NewDriverState |= ctx->DriverFlags.NewScissorRect;
>> +
>> +   if (ctx->Driver.Scissor)
>> +      ctx->Driver.Scissor(ctx);
>> +}
>> +
>> +static void
>>   scissor(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei height)
>>   {
>> +   bool changed = false;
>>      unsigned i;
>>
>>      /* The GL_ARB_viewport_array spec says:
>> @@ -74,11 +77,16 @@ scissor(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei height)
>>       * Set the scissor rectangle for all of the viewports supported by the
>>       * implementation, but only signal the driver once at the end.
>>       */
>> -   for (i = 0; i < ctx->Const.MaxViewports; i++)
>> -      set_scissor_no_notify(ctx, i, x, y, width, height);
>> +   for (i = 0; i < ctx->Const.MaxViewports; i++) {
>> +      if (!changed && is_scissor_equal(ctx, i, x, y, width, height))
>> +         continue;
>>
>> -   if (ctx->Driver.Scissor)
>> -      ctx->Driver.Scissor(ctx);
>> +      changed = true;
>> +      set_new_scissor(ctx, i, x, y, width, height);
>> +   }
>> +
>> +   if (changed)
>> +      flush_scissor(ctx);
>>   }
>>
>>   /**
>> @@ -125,23 +133,31 @@ void
>>   _mesa_set_scissor(struct gl_context *ctx, unsigned idx,
>>                     GLint x, GLint y, GLsizei width, GLsizei height)
>>   {
>> -   set_scissor_no_notify(ctx, idx, x, y, width, height);
>> +   if (is_scissor_equal(ctx, idx, x, y, width, height))
>> +      return;
>>
>> -   if (ctx->Driver.Scissor)
>> -      ctx->Driver.Scissor(ctx);
>> +   set_new_scissor(ctx, idx, x, y, width, height);
>> +   flush_scissor(ctx);
>>   }
>>
>>   static void
>>   scissor_array(struct gl_context *ctx, GLuint first, GLsizei count,
>>                 struct gl_scissor_rect *rect)
>>   {
>> +   bool changed = false;
>> +
>>      for (GLsizei i = 0; i < count; i++) {
>> -      set_scissor_no_notify(ctx, i + first, rect[i].X, rect[i].Y,
>> -                            rect[i].Width, rect[i].Height);
>> +      if (!changed && is_scissor_equal(ctx, i + first, rect[i].X, rect[i].Y,
>> +                                       rect[i].Width, rect[i].Height))
>> +         continue;
>> +
>> +      changed = true;
>> +      set_new_scissor(ctx, i + first, rect[i].X, rect[i].Y,
>> +                      rect[i].Width, rect[i].Height);
>>      }
>>
>> -   if (ctx->Driver.Scissor)
>> -      ctx->Driver.Scissor(ctx);
>> +   if (changed)
>> +      flush_scissor(ctx);
>>   }
>>
>>   /**
>> @@ -328,5 +344,6 @@ _mesa_init_scissor(struct gl_context *ctx)
>>       * so just initialize all of them.
>>       */
>>      for (i = 0; i < MAX_VIEWPORTS; i++)
>> -      set_scissor_no_notify(ctx, i, 0, 0, 0, 0);
>> +      set_new_scissor(ctx, i, 0, 0, 0, 0);
>> +   flush_scissor(ctx);
>>   }
>> --
>> 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