[Mesa-dev] [PATCH 02/31] mesa: stop using _NEW_STENCIL with st/mesa, use DriverFlags.NewStencil instead
Marek Olšák
maraeo at gmail.com
Mon Jun 12 16:55:27 UTC 2017
From: Marek Olšák <marek.olsak at amd.com>
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.
---
src/mesa/main/enable.c | 6 ++++--
src/mesa/main/mtypes.h | 3 +++
src/mesa/main/stencil.c | 33 ++++++++++++++++++++++-----------
src/mesa/state_tracker/st_context.c | 4 ++--
4 files changed, 31 insertions(+), 15 deletions(-)
diff --git a/src/mesa/main/enable.c b/src/mesa/main/enable.c
index 91c1f0d..128b5a9 100644
--- a/src/mesa/main/enable.c
+++ b/src/mesa/main/enable.c
@@ -672,21 +672,22 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state)
if (newEnabled != ctx->Scissor.EnableFlags) {
FLUSH_VERTICES(ctx, _NEW_SCISSOR);
ctx->NewDriverState |= ctx->DriverFlags.NewScissorTest;
ctx->Scissor.EnableFlags = newEnabled;
}
}
break;
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:
if (ctx->API != API_OPENGL_COMPAT)
goto invalid_enum_error;
if (!enable_texture(ctx, state, TEXTURE_1D_BIT)) {
return;
}
break;
case GL_TEXTURE_2D:
@@ -898,21 +899,22 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state)
}
break;
/* GL_EXT_stencil_two_side */
case GL_STENCIL_TEST_TWO_SIDE_EXT:
if (ctx->API != API_OPENGL_COMPAT)
goto invalid_enum_error;
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;
} else {
ctx->Stencil._BackFace = 1;
}
break;
case GL_FRAGMENT_PROGRAM_ARB:
if (ctx->API != API_OPENGL_COMPAT)
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 1e02ff0..283215f 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -4402,20 +4402,23 @@ struct gl_driver_flags
uint64_t NewWindowRectangles;
/** gl_context::Color::sRGBEnabled */
uint64_t NewFramebufferSRGB;
/** gl_context::Scissor::EnableFlags */
uint64_t NewScissorTest;
/** gl_context::Scissor::ScissorArray */
uint64_t NewScissorRect;
+
+ /** gl_context::Stencil */
+ uint64_t NewStencil;
};
struct gl_uniform_buffer_binding
{
struct gl_buffer_object *BufferObject;
/** Start of uniform block data in the buffer */
GLintptr Offset;
/** Size of data allowed to be referenced from the buffer (in bytes) */
GLsizeiptr Size;
/**
diff --git a/src/mesa/main/stencil.c b/src/mesa/main/stencil.c
index 2547f45..ea04f2e 100644
--- a/src/mesa/main/stencil.c
+++ b/src/mesa/main/stencil.c
@@ -150,21 +150,22 @@ _mesa_StencilFuncSeparateATI( GLenum frontfunc, GLenum backfunc, GLint ref, GLui
}
/* set both front and back state */
if (ctx->Stencil.Function[0] == frontfunc &&
ctx->Stencil.Function[1] == backfunc &&
ctx->Stencil.ValueMask[0] == mask &&
ctx->Stencil.ValueMask[1] == 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] = frontfunc;
ctx->Stencil.Function[1] = backfunc;
ctx->Stencil.Ref[0] = ctx->Stencil.Ref[1] = ref;
ctx->Stencil.ValueMask[0] = ctx->Stencil.ValueMask[1] = mask;
if (ctx->Driver.StencilFuncSeparate) {
ctx->Driver.StencilFuncSeparate(ctx, GL_FRONT,
frontfunc, ref, mask);
ctx->Driver.StencilFuncSeparate(ctx, GL_BACK,
backfunc, ref, mask);
}
@@ -196,42 +197,44 @@ _mesa_StencilFunc( GLenum func, GLint ref, GLuint mask )
if (!validate_stencil_func(ctx, func)) {
_mesa_error(ctx, GL_INVALID_ENUM, "glStencilFunc(func)");
return;
}
if (face != 0) {
if (ctx->Stencil.Function[face] == func &&
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;
/* Only propagate the change to the driver if EXT_stencil_two_side
* is enabled.
*/
if (ctx->Driver.StencilFuncSeparate && ctx->Stencil.TestTwoSide) {
ctx->Driver.StencilFuncSeparate(ctx, GL_BACK, func, ref, mask);
}
}
else {
/* set both front and back state */
if (ctx->Stencil.Function[0] == func &&
ctx->Stencil.Function[1] == func &&
ctx->Stencil.ValueMask[0] == mask &&
ctx->Stencil.ValueMask[1] == 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;
if (ctx->Driver.StencilFuncSeparate) {
ctx->Driver.StencilFuncSeparate(ctx,
((ctx->Stencil.TestTwoSide)
? GL_FRONT : GL_FRONT_AND_BACK),
func, ref, mask);
}
}
@@ -256,36 +259,38 @@ _mesa_StencilMask( GLuint mask )
const GLint face = ctx->Stencil.ActiveFace;
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "glStencilMask()\n");
if (face != 0) {
/* Only modify the EXT_stencil_two_side back-face state.
*/
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
* is enabled.
*/
if (ctx->Driver.StencilMaskSeparate && ctx->Stencil.TestTwoSide) {
ctx->Driver.StencilMaskSeparate(ctx, GL_BACK, mask);
}
}
else {
/* set both front and back state */
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,
((ctx->Stencil.TestTwoSide)
? GL_FRONT : GL_FRONT_AND_BACK),
mask);
}
}
}
@@ -325,42 +330,44 @@ _mesa_StencilOp(GLenum fail, GLenum zfail, GLenum zpass)
_mesa_error(ctx, GL_INVALID_ENUM, "glStencilOp(zpass)");
return;
}
if (face != 0) {
/* only set active face state */
if (ctx->Stencil.ZFailFunc[face] == zfail &&
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;
/* Only propagate the change to the driver if EXT_stencil_two_side
* is enabled.
*/
if (ctx->Driver.StencilOpSeparate && ctx->Stencil.TestTwoSide) {
ctx->Driver.StencilOpSeparate(ctx, GL_BACK, fail, zfail, zpass);
}
}
else {
/* set both front and back state */
if (ctx->Stencil.ZFailFunc[0] == zfail &&
ctx->Stencil.ZFailFunc[1] == zfail &&
ctx->Stencil.ZPassFunc[0] == zpass &&
ctx->Stencil.ZPassFunc[1] == 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;
if (ctx->Driver.StencilOpSeparate) {
ctx->Driver.StencilOpSeparate(ctx,
((ctx->Stencil.TestTwoSide)
? GL_FRONT : GL_FRONT_AND_BACK),
fail, zfail, zpass);
}
}
@@ -416,33 +423,35 @@ _mesa_StencilOpSeparate(GLenum face, GLenum sfail, GLenum zfail, GLenum zpass)
if (face != GL_FRONT && face != GL_BACK && face != GL_FRONT_AND_BACK) {
_mesa_error(ctx, GL_INVALID_ENUM, "glStencilOpSeparate(face)");
return;
}
if (face != GL_BACK) {
/* set front */
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;
set = GL_TRUE;
}
}
if (face != GL_FRONT) {
/* set back */
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;
set = GL_TRUE;
}
}
if (set && ctx->Driver.StencilOpSeparate) {
ctx->Driver.StencilOpSeparate(ctx, face, sfail, zfail, zpass);
}
}
@@ -459,21 +468,22 @@ _mesa_StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
if (face != GL_FRONT && face != GL_BACK && face != GL_FRONT_AND_BACK) {
_mesa_error(ctx, GL_INVALID_ENUM, "glStencilFuncSeparate(face)");
return;
}
if (!validate_stencil_func(ctx, func)) {
_mesa_error(ctx, GL_INVALID_ENUM, "glStencilFuncSeparate(func)");
return;
}
- 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 */
ctx->Stencil.Function[0] = func;
ctx->Stencil.Ref[0] = ref;
ctx->Stencil.ValueMask[0] = mask;
}
if (face != GL_FRONT) {
/* set back */
ctx->Stencil.Function[1] = func;
@@ -493,21 +503,22 @@ _mesa_StencilMaskSeparate(GLenum face, GLuint mask)
GET_CURRENT_CONTEXT(ctx);
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "glStencilMaskSeparate()\n");
if (face != GL_FRONT && face != GL_BACK && face != GL_FRONT_AND_BACK) {
_mesa_error(ctx, GL_INVALID_ENUM, "glStencilaMaskSeparate(face)");
return;
}
- 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;
}
if (face != GL_FRONT) {
ctx->Stencil.WriteMask[1] = mask;
}
if (ctx->Driver.StencilMaskSeparate) {
ctx->Driver.StencilMaskSeparate(ctx, face, mask);
}
diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c
index b99a53b..b9ebc38 100644
--- a/src/mesa/state_tracker/st_context.c
+++ b/src/mesa/state_tracker/st_context.c
@@ -186,22 +186,21 @@ st_invalidate_state(struct gl_context * ctx)
{
GLbitfield new_state = ctx->NewState;
struct st_context *st = st_context(ctx);
if (new_state & _NEW_BUFFERS) {
st_invalidate_buffers(st);
} else {
/* 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)
st->dirty |= ST_NEW_RASTERIZER;
if (new_state & _NEW_FOG)
st->dirty |= ST_NEW_FS_STATE;
if (new_state & _NEW_POLYGONSTIPPLE)
st->dirty |= ST_NEW_POLY_STIPPLE;
@@ -514,20 +513,21 @@ static void st_init_driver_flags(struct st_context *st)
f->NewUniformBuffer = ST_NEW_UNIFORM_BUFFER;
f->NewDefaultTessLevels = ST_NEW_TESS_STATE;
f->NewTextureBuffer = ST_NEW_SAMPLER_VIEWS;
f->NewAtomicBuffer = ST_NEW_ATOMIC_BUFFER;
f->NewShaderStorageBuffer = ST_NEW_STORAGE_BUFFER;
f->NewImageUnits = ST_NEW_IMAGE_UNITS;
f->NewWindowRectangles = ST_NEW_WINDOW_RECTANGLES;
f->NewFramebufferSRGB = ST_NEW_FRAMEBUFFER;
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,
const struct gl_config *visual,
struct st_context *share,
const struct st_config_options *options)
{
struct gl_context *ctx;
struct gl_context *shareCtx = share ? share->ctx : NULL;
struct dd_function_table funcs;
--
2.7.4
More information about the mesa-dev
mailing list