mesa: stop using _NEW_STENCIL with st/mesa, use DriverFlags.NewStencil instead
authorMarek Olšák <marek.olsak@amd.com>
Fri, 9 Jun 2017 18:51:20 +0000 (20:51 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Wed, 21 Jun 2017 23:51:02 +0000 (01:51 +0200)
This bypasses _mesa_update_state_locked.

Before:
   DrawElements ( 1 VBOs, 4 UBOs,  8 Tex) w/ stencil enable change:    3.99 million
   DrawArrays   ( 1 VBOs, 4 UBOs,  8 Tex) w/ stencil enable change:    4.56 million

After:
   DrawElements ( 1 VBOs, 4 UBOs,  8 Tex) w/ stencil enable change:    4.93 million
   DrawArrays   ( 1 VBOs, 4 UBOs,  8 Tex) w/ stencil enable change:    5.84 million

It's quite a difference in the draw call rate when ctx->NewState stays
equal to 0 the whole time.

Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
Reviewed-by: Brian Paul <brianp@vmware.com>
Reviewed-by: Timothy Arceri <tarceri@itsqueeze.com>
src/mesa/main/enable.c
src/mesa/main/mtypes.h
src/mesa/main/stencil.c
src/mesa/state_tracker/st_context.c

index 066beb6422bc89ccc6e88cd862a2cde60dadb81d..522b71ecfc71b02305c8ecc1a55a2cac5564ee4c 100644 (file)
@@ -679,7 +679,8 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state)
       case GL_STENCIL_TEST:
          if (ctx->Stencil.Enabled == state)
             return;
-         FLUSH_VERTICES(ctx, _NEW_STENCIL);
+         FLUSH_VERTICES(ctx, ctx->DriverFlags.NewStencil ? 0 : _NEW_STENCIL);
+         ctx->NewDriverState |= ctx->DriverFlags.NewStencil;
          ctx->Stencil.Enabled = state;
          break;
       case GL_TEXTURE_1D:
@@ -905,7 +906,8 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state)
          CHECK_EXTENSION(EXT_stencil_two_side, cap);
          if (ctx->Stencil.TestTwoSide == state)
             return;
-         FLUSH_VERTICES(ctx, _NEW_STENCIL);
+         FLUSH_VERTICES(ctx, ctx->DriverFlags.NewStencil ? 0 : _NEW_STENCIL);
+         ctx->NewDriverState |= ctx->DriverFlags.NewStencil;
          ctx->Stencil.TestTwoSide = state;
          if (state) {
             ctx->Stencil._BackFace = 2;
index 8872c38a02b8f7078bf97e3bd3f537a834d04cef..4e7011bb7018bf2cc46f69371f165e5b205f0c5a 100644 (file)
@@ -4481,6 +4481,9 @@ struct gl_driver_flags
 
    /** gl_context::Scissor::ScissorArray */
    uint64_t NewScissorRect;
+
+   /** gl_context::Stencil */
+   uint64_t NewStencil;
 };
 
 struct gl_uniform_buffer_binding
index 612ad38dcc1472ea2862b008fffed0e919ad56df..d89312ce12ddd9ae0335d58446483a12fdfa8bee 100644 (file)
@@ -157,7 +157,8 @@ _mesa_StencilFuncSeparateATI( GLenum frontfunc, GLenum backfunc, GLint ref, GLui
        ctx->Stencil.Ref[0] == ref &&
        ctx->Stencil.Ref[1] == ref)
       return;
-   FLUSH_VERTICES(ctx, _NEW_STENCIL);
+   FLUSH_VERTICES(ctx, ctx->DriverFlags.NewStencil ? 0 : _NEW_STENCIL);
+   ctx->NewDriverState |= ctx->DriverFlags.NewStencil;
    ctx->Stencil.Function[0]  = frontfunc;
    ctx->Stencil.Function[1]  = backfunc;
    ctx->Stencil.Ref[0]       = ctx->Stencil.Ref[1]       = ref;
@@ -194,7 +195,8 @@ stencil_func(struct gl_context *ctx, GLenum func, GLint ref, GLuint mask)
           ctx->Stencil.ValueMask[face] == mask &&
           ctx->Stencil.Ref[face] == ref)
          return;
-      FLUSH_VERTICES(ctx, _NEW_STENCIL);
+      FLUSH_VERTICES(ctx, ctx->DriverFlags.NewStencil ? 0 : _NEW_STENCIL);
+      ctx->NewDriverState |= ctx->DriverFlags.NewStencil;
       ctx->Stencil.Function[face] = func;
       ctx->Stencil.Ref[face] = ref;
       ctx->Stencil.ValueMask[face] = mask;
@@ -215,7 +217,8 @@ stencil_func(struct gl_context *ctx, GLenum func, GLint ref, GLuint mask)
           ctx->Stencil.Ref[0] == ref &&
           ctx->Stencil.Ref[1] == ref)
          return;
-      FLUSH_VERTICES(ctx, _NEW_STENCIL);
+      FLUSH_VERTICES(ctx, ctx->DriverFlags.NewStencil ? 0 : _NEW_STENCIL);
+      ctx->NewDriverState |= ctx->DriverFlags.NewStencil;
       ctx->Stencil.Function[0]  = ctx->Stencil.Function[1]  = func;
       ctx->Stencil.Ref[0]       = ctx->Stencil.Ref[1]       = ref;
       ctx->Stencil.ValueMask[0] = ctx->Stencil.ValueMask[1] = mask;
@@ -279,7 +282,8 @@ _mesa_StencilMask( GLuint mask )
        */
       if (ctx->Stencil.WriteMask[face] == mask)
          return;
-      FLUSH_VERTICES(ctx, _NEW_STENCIL);
+      FLUSH_VERTICES(ctx, ctx->DriverFlags.NewStencil ? 0 : _NEW_STENCIL);
+      ctx->NewDriverState |= ctx->DriverFlags.NewStencil;
       ctx->Stencil.WriteMask[face] = mask;
 
       /* Only propagate the change to the driver if EXT_stencil_two_side
@@ -294,7 +298,8 @@ _mesa_StencilMask( GLuint mask )
       if (ctx->Stencil.WriteMask[0] == mask &&
           ctx->Stencil.WriteMask[1] == mask)
          return;
-      FLUSH_VERTICES(ctx, _NEW_STENCIL);
+      FLUSH_VERTICES(ctx, ctx->DriverFlags.NewStencil ? 0 : _NEW_STENCIL);
+      ctx->NewDriverState |= ctx->DriverFlags.NewStencil;
       ctx->Stencil.WriteMask[0] = ctx->Stencil.WriteMask[1] = mask;
       if (ctx->Driver.StencilMaskSeparate) {
          ctx->Driver.StencilMaskSeparate(ctx,
@@ -331,7 +336,8 @@ stencil_op(struct gl_context *ctx, GLenum fail, GLenum zfail, GLenum zpass)
           ctx->Stencil.ZPassFunc[face] == zpass &&
           ctx->Stencil.FailFunc[face] == fail)
          return;
-      FLUSH_VERTICES(ctx, _NEW_STENCIL);
+      FLUSH_VERTICES(ctx, ctx->DriverFlags.NewStencil ? 0 : _NEW_STENCIL);
+      ctx->NewDriverState |= ctx->DriverFlags.NewStencil;
       ctx->Stencil.ZFailFunc[face] = zfail;
       ctx->Stencil.ZPassFunc[face] = zpass;
       ctx->Stencil.FailFunc[face] = fail;
@@ -352,7 +358,8 @@ stencil_op(struct gl_context *ctx, GLenum fail, GLenum zfail, GLenum zpass)
           ctx->Stencil.FailFunc[0] == fail &&
           ctx->Stencil.FailFunc[1] == fail)
          return;
-      FLUSH_VERTICES(ctx, _NEW_STENCIL);
+      FLUSH_VERTICES(ctx, ctx->DriverFlags.NewStencil ? 0 : _NEW_STENCIL);
+      ctx->NewDriverState |= ctx->DriverFlags.NewStencil;
       ctx->Stencil.ZFailFunc[0] = ctx->Stencil.ZFailFunc[1] = zfail;
       ctx->Stencil.ZPassFunc[0] = ctx->Stencil.ZPassFunc[1] = zpass;
       ctx->Stencil.FailFunc[0]  = ctx->Stencil.FailFunc[1]  = fail;
@@ -435,7 +442,8 @@ stencil_op_separate(struct gl_context *ctx, GLenum face, GLenum sfail,
       if (ctx->Stencil.ZFailFunc[0] != zfail ||
           ctx->Stencil.ZPassFunc[0] != zpass ||
           ctx->Stencil.FailFunc[0] != sfail){
-         FLUSH_VERTICES(ctx, _NEW_STENCIL);
+         FLUSH_VERTICES(ctx, ctx->DriverFlags.NewStencil ? 0 : _NEW_STENCIL);
+         ctx->NewDriverState |= ctx->DriverFlags.NewStencil;
          ctx->Stencil.ZFailFunc[0] = zfail;
          ctx->Stencil.ZPassFunc[0] = zpass;
          ctx->Stencil.FailFunc[0] = sfail;
@@ -448,7 +456,8 @@ stencil_op_separate(struct gl_context *ctx, GLenum face, GLenum sfail,
       if (ctx->Stencil.ZFailFunc[1] != zfail ||
           ctx->Stencil.ZPassFunc[1] != zpass ||
           ctx->Stencil.FailFunc[1] != sfail) {
-         FLUSH_VERTICES(ctx, _NEW_STENCIL);
+         FLUSH_VERTICES(ctx, ctx->DriverFlags.NewStencil ? 0 : _NEW_STENCIL);
+         ctx->NewDriverState |= ctx->DriverFlags.NewStencil;
          ctx->Stencil.ZFailFunc[1] = zfail;
          ctx->Stencil.ZPassFunc[1] = zpass;
          ctx->Stencil.FailFunc[1] = sfail;
@@ -507,7 +516,8 @@ static void
 stencil_func_separate(struct gl_context *ctx, GLenum face, GLenum func,
                       GLint ref, GLuint mask)
 {
-   FLUSH_VERTICES(ctx, _NEW_STENCIL);
+   FLUSH_VERTICES(ctx, ctx->DriverFlags.NewStencil ? 0 : _NEW_STENCIL);
+   ctx->NewDriverState |= ctx->DriverFlags.NewStencil;
 
    if (face != GL_BACK) {
       /* set front */
@@ -564,7 +574,8 @@ _mesa_StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
 static void
 stencil_mask_separate(struct gl_context *ctx, GLenum face, GLuint mask)
 {
-   FLUSH_VERTICES(ctx, _NEW_STENCIL);
+   FLUSH_VERTICES(ctx, ctx->DriverFlags.NewStencil ? 0 : _NEW_STENCIL);
+   ctx->NewDriverState |= ctx->DriverFlags.NewStencil;
 
    if (face != GL_BACK) {
       ctx->Stencil.WriteMask[0] = mask;
index a0bd9ea7e38282f0010b49ff623415b522fe607a..b7bdc47bd5389d25304843c7afcf7027b3f3e0cb 100644 (file)
@@ -193,8 +193,7 @@ st_invalidate_state(struct gl_context * ctx)
       /* These set a subset of flags set by _NEW_BUFFERS, so we only have to
        * check them when _NEW_BUFFERS isn't set.
        */
-      if (new_state & (_NEW_DEPTH |
-                       _NEW_STENCIL))
+      if (new_state & _NEW_DEPTH)
          st->dirty |= ST_NEW_DSA;
 
       if (new_state & _NEW_PROGRAM)
@@ -523,6 +522,7 @@ static void st_init_driver_flags(struct st_context *st)
    f->NewFramebufferSRGB = ST_NEW_FB_STATE;
    f->NewScissorRect = ST_NEW_SCISSOR;
    f->NewScissorTest = ST_NEW_SCISSOR | ST_NEW_RASTERIZER;
+   f->NewStencil = ST_NEW_DSA;
 }
 
 struct st_context *st_create_context(gl_api api, struct pipe_context *pipe,