From 79dcd69afae4ada47fd4e746e9eec87c6d8028f0 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Sun, 17 Jul 2016 20:37:58 +0200 Subject: [PATCH] st/mesa: remove excessive shader state dirtying MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This just needs to be done by st_validate_state. v2: add "shaders_may_be_dirty" flags for not skipping st_validate_state on _NEW_PROGRAM to detect real shader changes Reviewed-by: Nicolai Hähnle --- src/mesa/state_tracker/st_atom.c | 13 +++++++++ src/mesa/state_tracker/st_cb_bitmap.c | 3 +- src/mesa/state_tracker/st_cb_compute.c | 3 +- src/mesa/state_tracker/st_cb_program.c | 53 ---------------------------------- src/mesa/state_tracker/st_context.c | 6 ++++ src/mesa/state_tracker/st_context.h | 6 ++++ src/mesa/state_tracker/st_draw.c | 6 ++-- 7 files changed, 33 insertions(+), 57 deletions(-) diff --git a/src/mesa/state_tracker/st_atom.c b/src/mesa/state_tracker/st_atom.c index ef50ef9..06c523e 100644 --- a/src/mesa/state_tracker/st_atom.c +++ b/src/mesa/state_tracker/st_atom.c @@ -72,6 +72,14 @@ static void check_program_state( struct st_context *st ) if (ctx->GeometryProgram._Current != &st->gp->Base) st->dirty |= ST_NEW_GEOMETRY_PROGRAM; + + if (ctx->TessCtrlProgram._Current != &st->tcp->Base) + st->dirty |= ST_NEW_TESSCTRL_PROGRAM; + + if (ctx->TessEvalProgram._Current != &st->tep->Base) + st->dirty |= ST_NEW_TESSEVAL_PROGRAM; + + st->gfx_shaders_may_be_dirty = false; } static void check_attrib_edgeflag(struct st_context *st) @@ -135,8 +143,13 @@ void st_validate_state( struct st_context *st, enum st_pipeline pipeline ) pipeline_mask &= ~ST_NEW_GS_RESOURCES; if (!ctx->Transform.ClipPlanesEnabled) pipeline_mask &= ~ST_NEW_CLIP_STATE; + break; case ST_PIPELINE_COMPUTE: + if (ctx->ComputeProgram._Current != &st->cp->Base) + st->dirty |= ST_NEW_COMPUTE_PROGRAM; + + st->compute_shader_may_be_dirty = false; pipeline_mask = ST_PIPELINE_COMPUTE_STATE_MASK; break; default: diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c index 5765ed2..0ee19fd 100644 --- a/src/mesa/state_tracker/st_cb_bitmap.c +++ b/src/mesa/state_tracker/st_cb_bitmap.c @@ -647,7 +647,8 @@ st_Bitmap(struct gl_context *ctx, GLint x, GLint y, * explicitly uploaded in the draw_bitmap_quad() function. */ if ((st->dirty | ctx->NewDriverState) & ~ST_NEW_CONSTANTS & - ST_PIPELINE_RENDER_STATE_MASK) { + ST_PIPELINE_RENDER_STATE_MASK || + st->gfx_shaders_may_be_dirty) { st_validate_state(st, ST_PIPELINE_RENDER); } diff --git a/src/mesa/state_tracker/st_cb_compute.c b/src/mesa/state_tracker/st_cb_compute.c index 677507d..88c1ee2 100644 --- a/src/mesa/state_tracker/st_cb_compute.c +++ b/src/mesa/state_tracker/st_cb_compute.c @@ -51,7 +51,8 @@ static void st_dispatch_compute_common(struct gl_context *ctx, if (ctx->NewState) _mesa_update_state(ctx); - if ((st->dirty | ctx->NewDriverState) & ST_PIPELINE_COMPUTE_STATE_MASK) + if ((st->dirty | ctx->NewDriverState) & ST_PIPELINE_COMPUTE_STATE_MASK || + st->compute_shader_may_be_dirty) st_validate_state(st, ST_PIPELINE_COMPUTE); for (unsigned i = 0; i < 3; i++) { diff --git a/src/mesa/state_tracker/st_cb_program.c b/src/mesa/state_tracker/st_cb_program.c index 6264896..8291edb 100644 --- a/src/mesa/state_tracker/st_cb_program.c +++ b/src/mesa/state_tracker/st_cb_program.c @@ -49,57 +49,6 @@ #include "st_atifs_to_tgsi.h" - -/** - * Called via ctx->Driver.BindProgram() to bind an ARB vertex or - * fragment program. - */ -static void -st_bind_program(struct gl_context *ctx, GLenum target, struct gl_program *prog) -{ - struct st_context *st = st_context(ctx); - - switch (target) { - case GL_VERTEX_PROGRAM_ARB: - st->dirty |= ST_NEW_VERTEX_PROGRAM; - break; - case GL_FRAGMENT_PROGRAM_ARB: - st->dirty |= ST_NEW_FRAGMENT_PROGRAM; - break; - case GL_GEOMETRY_PROGRAM_NV: - st->dirty |= ST_NEW_GEOMETRY_PROGRAM; - break; - case GL_TESS_CONTROL_PROGRAM_NV: - st->dirty |= ST_NEW_TESSCTRL_PROGRAM; - break; - case GL_TESS_EVALUATION_PROGRAM_NV: - st->dirty |= ST_NEW_TESSEVAL_PROGRAM; - break; - case GL_COMPUTE_PROGRAM_NV: - st->dirty |= ST_NEW_COMPUTE_PROGRAM; - break; - } -} - - -/** - * Called via ctx->Driver.UseProgram() to bind a linked GLSL program - * (vertex shader + fragment shader). - */ -static void -st_use_program(struct gl_context *ctx, struct gl_shader_program *shProg) -{ - struct st_context *st = st_context(ctx); - - st->dirty |= ST_NEW_FRAGMENT_PROGRAM; - st->dirty |= ST_NEW_VERTEX_PROGRAM; - st->dirty |= ST_NEW_GEOMETRY_PROGRAM; - st->dirty |= ST_NEW_TESSCTRL_PROGRAM; - st->dirty |= ST_NEW_TESSEVAL_PROGRAM; - st->dirty |= ST_NEW_COMPUTE_PROGRAM; -} - - /** * Called via ctx->Driver.NewProgram() to allocate a new vertex or * fragment program. @@ -347,8 +296,6 @@ st_new_ati_fs(struct gl_context *ctx, struct ati_fragment_shader *curProg) void st_init_program_functions(struct dd_function_table *functions) { - functions->BindProgram = st_bind_program; - functions->UseProgram = st_use_program; functions->NewProgram = st_new_program; functions->DeleteProgram = st_delete_program; functions->ProgramStringNotify = st_program_string_notify; diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index 911bec6..2ba6efe 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -219,6 +219,12 @@ void st_invalidate_state(struct gl_context * ctx, GLbitfield new_state) if (st->clamp_vert_color_in_shader && (new_state & _NEW_LIGHT)) st->dirty |= ST_NEW_VS_STATE; + /* Which shaders are dirty will be determined manually. */ + if (new_state & _NEW_PROGRAM) { + st->gfx_shaders_may_be_dirty = true; + st->compute_shader_may_be_dirty = true; + } + /* This is the only core Mesa module we depend upon. * No longer use swrast, swsetup, tnl. */ diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index b9ad2a9..e0f29e3 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -140,6 +140,12 @@ struct st_context uint64_t dirty; /**< dirty states */ + /* If true, further analysis of states is required to know if something + * has changed. Used mainly for shaders. + */ + bool gfx_shaders_may_be_dirty; + bool compute_shader_may_be_dirty; + GLboolean vertdata_edgeflags; GLboolean edgeflag_culls_prims; diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index 92eb4a3..b248daf 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -173,7 +173,8 @@ st_draw_vbo(struct gl_context *ctx, st_invalidate_readpix_cache(st); /* Validate state. */ - if ((st->dirty | ctx->NewDriverState) & ST_PIPELINE_RENDER_STATE_MASK) { + if ((st->dirty | ctx->NewDriverState) & ST_PIPELINE_RENDER_STATE_MASK || + st->gfx_shaders_may_be_dirty) { st_validate_state(st, ST_PIPELINE_RENDER); } @@ -278,7 +279,8 @@ st_indirect_draw_vbo(struct gl_context *ctx, assert(stride); /* Validate state. */ - if ((st->dirty | ctx->NewDriverState) & ST_PIPELINE_RENDER_STATE_MASK) { + if ((st->dirty | ctx->NewDriverState) & ST_PIPELINE_RENDER_STATE_MASK || + st->gfx_shaders_may_be_dirty) { st_validate_state(st, ST_PIPELINE_RENDER); } -- 2.7.4