[Mesa-dev] [PATCH] mesa/st: only update samplers for stages that have changed

Marek Olšák maraeo at gmail.com
Wed Apr 12 16:08:13 UTC 2017


Reviewed-by: Marek Olšák <marek.olsak at amd.com>

Marek

On Tue, Apr 11, 2017 at 3:05 AM, Timothy Arceri <tarceri at itsqueeze.com> wrote:
> Might helper reduce cpu for some apps that use sso.
> ---
>  src/mesa/state_tracker/st_atom.h         |  6 +-
>  src/mesa/state_tracker/st_atom_list.h    |  8 ++-
>  src/mesa/state_tracker/st_atom_sampler.c | 94 ++++++++++++++++++++++++++------
>  src/mesa/state_tracker/st_program.c      | 14 ++---
>  4 files changed, 94 insertions(+), 28 deletions(-)
>
> diff --git a/src/mesa/state_tracker/st_atom.h b/src/mesa/state_tracker/st_atom.h
> index 45c3e48..0145cef 100644
> --- a/src/mesa/state_tracker/st_atom.h
> +++ b/src/mesa/state_tracker/st_atom.h
> @@ -76,21 +76,25 @@ enum {
>  #define ST_STATE(FLAG, st_update) static const uint64_t FLAG = 1llu << FLAG##_INDEX;
>  #include "st_atom_list.h"
>  #undef ST_STATE
>
>  /* Add extern struct declarations. */
>  #define ST_STATE(FLAG, st_update) extern const struct st_tracked_state st_update;
>  #include "st_atom_list.h"
>  #undef ST_STATE
>
>  /* Combined state flags. */
> -#define ST_NEW_SAMPLERS         (ST_NEW_RENDER_SAMPLERS | \
> +#define ST_NEW_SAMPLERS         (ST_NEW_VS_SAMPLERS | \
> +                                 ST_NEW_TCS_SAMPLERS | \
> +                                 ST_NEW_TES_SAMPLERS | \
> +                                 ST_NEW_GS_SAMPLERS | \
> +                                 ST_NEW_FS_SAMPLERS | \
>                                   ST_NEW_CS_SAMPLERS)
>
>  #define ST_NEW_FRAMEBUFFER      (ST_NEW_FB_STATE | \
>                                   ST_NEW_SAMPLE_MASK | \
>                                   ST_NEW_SAMPLE_SHADING)
>
>  #define ST_NEW_VERTEX_PROGRAM(st, p) (p->affected_states | \
>                                        (st_user_clip_planes_enabled(st->ctx) ? \
>                                         ST_NEW_CLIP_STATE : 0))
>
> diff --git a/src/mesa/state_tracker/st_atom_list.h b/src/mesa/state_tracker/st_atom_list.h
> index d0d5a05..4212dac 100644
> --- a/src/mesa/state_tracker/st_atom_list.h
> +++ b/src/mesa/state_tracker/st_atom_list.h
> @@ -15,21 +15,25 @@ ST_STATE(ST_NEW_SCISSOR, st_update_scissor)
>  ST_STATE(ST_NEW_WINDOW_RECTANGLES, st_update_window_rectangles)
>  ST_STATE(ST_NEW_BLEND, st_update_blend)
>
>  ST_STATE(ST_NEW_VS_SAMPLER_VIEWS, st_update_vertex_texture)
>  ST_STATE(ST_NEW_FS_SAMPLER_VIEWS, st_update_fragment_texture)
>  ST_STATE(ST_NEW_GS_SAMPLER_VIEWS, st_update_geometry_texture)
>  ST_STATE(ST_NEW_TCS_SAMPLER_VIEWS, st_update_tessctrl_texture)
>  ST_STATE(ST_NEW_TES_SAMPLER_VIEWS, st_update_tesseval_texture)
>
>  /* Non-compute samplers. */
> -ST_STATE(ST_NEW_RENDER_SAMPLERS, st_update_sampler) /* depends on update_*_texture for swizzle */
> +ST_STATE(ST_NEW_VS_SAMPLERS, st_update_vertex_sampler) /* depends on update_*_texture for swizzle */
> +ST_STATE(ST_NEW_TCS_SAMPLERS, st_update_tessctrl_sampler) /* depends on update_*_texture for swizzle */
> +ST_STATE(ST_NEW_TES_SAMPLERS, st_update_tesseval_sampler) /* depends on update_*_texture for swizzle */
> +ST_STATE(ST_NEW_GS_SAMPLERS, st_update_geometry_sampler) /* depends on update_*_texture for swizzle */
> +ST_STATE(ST_NEW_FS_SAMPLERS, st_update_fragment_sampler) /* depends on update_*_texture for swizzle */
>
>  ST_STATE(ST_NEW_VS_IMAGES, st_bind_vs_images)
>  ST_STATE(ST_NEW_TCS_IMAGES, st_bind_tcs_images)
>  ST_STATE(ST_NEW_TES_IMAGES, st_bind_tes_images)
>  ST_STATE(ST_NEW_GS_IMAGES, st_bind_gs_images)
>  ST_STATE(ST_NEW_FS_IMAGES, st_bind_fs_images)
>
>  ST_STATE(ST_NEW_FB_STATE, st_update_framebuffer) /* depends on update_*_texture and bind_*_images */
>  ST_STATE(ST_NEW_SAMPLE_MASK, st_update_msaa)
>  ST_STATE(ST_NEW_SAMPLE_SHADING, st_update_sample_shading)
> @@ -60,16 +64,16 @@ ST_STATE(ST_NEW_GS_SSBOS, st_bind_gs_ssbos)
>
>  ST_STATE(ST_NEW_PIXEL_TRANSFER, st_update_pixel_transfer)
>  ST_STATE(ST_NEW_TESS_STATE, st_update_tess)
>
>  /* this must be done after the vertex program update */
>  ST_STATE(ST_NEW_VERTEX_ARRAYS, st_update_array)
>
>  /* Compute states must be last. */
>  ST_STATE(ST_NEW_CS_STATE, st_update_cp)
>  ST_STATE(ST_NEW_CS_SAMPLER_VIEWS, st_update_compute_texture)
> -ST_STATE(ST_NEW_CS_SAMPLERS, st_update_sampler) /* depends on update_compute_texture for swizzle */
> +ST_STATE(ST_NEW_CS_SAMPLERS, st_update_compute_sampler) /* depends on update_compute_texture for swizzle */
>  ST_STATE(ST_NEW_CS_CONSTANTS, st_update_cs_constants)
>  ST_STATE(ST_NEW_CS_UBOS, st_bind_cs_ubos)
>  ST_STATE(ST_NEW_CS_ATOMICS, st_bind_cs_atomics)
>  ST_STATE(ST_NEW_CS_SSBOS, st_bind_cs_ssbos)
>  ST_STATE(ST_NEW_CS_IMAGES, st_bind_cs_images)
> diff --git a/src/mesa/state_tracker/st_atom_sampler.c b/src/mesa/state_tracker/st_atom_sampler.c
> index 661e0f2..9ddc704 100644
> --- a/src/mesa/state_tracker/st_atom_sampler.c
> +++ b/src/mesa/state_tracker/st_atom_sampler.c
> @@ -314,66 +314,124 @@ update_shader_samplers(struct st_context *st,
>        }
>
>        *num_samplers = MAX2(*num_samplers, extra + 1);
>     }
>
>     cso_set_samplers(st->cso_context, shader_stage, *num_samplers, states);
>  }
>
>
>  static void
> -update_samplers(struct st_context *st)
> +update_vertex_samplers(struct st_context *st)
>  {
>     const struct gl_context *ctx = st->ctx;
>
>     update_shader_samplers(st,
> -                          PIPE_SHADER_FRAGMENT,
> -                          ctx->FragmentProgram._Current,
> -                          ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits,
> -                          st->state.samplers[PIPE_SHADER_FRAGMENT],
> -                          &st->state.num_samplers[PIPE_SHADER_FRAGMENT]);
> -
> -   update_shader_samplers(st,
>                            PIPE_SHADER_VERTEX,
>                            ctx->VertexProgram._Current,
>                            ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits,
>                            st->state.samplers[PIPE_SHADER_VERTEX],
>                            &st->state.num_samplers[PIPE_SHADER_VERTEX]);
> +}
> +
> +
> +static void
> +update_tessctrl_samplers(struct st_context *st)
> +{
> +   const struct gl_context *ctx = st->ctx;
>
> -   if (ctx->GeometryProgram._Current) {
> -      update_shader_samplers(st,
> -                             PIPE_SHADER_GEOMETRY,
> -                             ctx->GeometryProgram._Current,
> -                             ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits,
> -                             st->state.samplers[PIPE_SHADER_GEOMETRY],
> -                             &st->state.num_samplers[PIPE_SHADER_GEOMETRY]);
> -   }
>     if (ctx->TessCtrlProgram._Current) {
>        update_shader_samplers(st,
>                               PIPE_SHADER_TESS_CTRL,
>                               ctx->TessCtrlProgram._Current,
>                               ctx->Const.Program[MESA_SHADER_TESS_CTRL].MaxTextureImageUnits,
>                               st->state.samplers[PIPE_SHADER_TESS_CTRL],
>                               &st->state.num_samplers[PIPE_SHADER_TESS_CTRL]);
>     }
> +}
> +
> +
> +static void
> +update_tesseval_samplers(struct st_context *st)
> +{
> +   const struct gl_context *ctx = st->ctx;
> +
>     if (ctx->TessEvalProgram._Current) {
>        update_shader_samplers(st,
>                               PIPE_SHADER_TESS_EVAL,
>                               ctx->TessEvalProgram._Current,
>                               ctx->Const.Program[MESA_SHADER_TESS_EVAL].MaxTextureImageUnits,
>                               st->state.samplers[PIPE_SHADER_TESS_EVAL],
>                               &st->state.num_samplers[PIPE_SHADER_TESS_EVAL]);
>     }
> +}
> +
> +
> +static void
> +update_geometry_samplers(struct st_context *st)
> +{
> +   const struct gl_context *ctx = st->ctx;
> +
> +   if (ctx->GeometryProgram._Current) {
> +      update_shader_samplers(st,
> +                             PIPE_SHADER_GEOMETRY,
> +                             ctx->GeometryProgram._Current,
> +                             ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits,
> +                             st->state.samplers[PIPE_SHADER_GEOMETRY],
> +                             &st->state.num_samplers[PIPE_SHADER_GEOMETRY]);
> +   }
> +}
> +
> +
> +static void
> +update_fragment_samplers(struct st_context *st)
> +{
> +   const struct gl_context *ctx = st->ctx;
> +
> +   update_shader_samplers(st,
> +                          PIPE_SHADER_FRAGMENT,
> +                          ctx->FragmentProgram._Current,
> +                          ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits,
> +                          st->state.samplers[PIPE_SHADER_FRAGMENT],
> +                          &st->state.num_samplers[PIPE_SHADER_FRAGMENT]);
> +}
> +
> +
> +static void
> +update_compute_samplers(struct st_context *st)
> +{
> +   const struct gl_context *ctx = st->ctx;
> +
>     if (ctx->ComputeProgram._Current) {
>        update_shader_samplers(st,
>                               PIPE_SHADER_COMPUTE,
>                               ctx->ComputeProgram._Current,
>                               ctx->Const.Program[MESA_SHADER_COMPUTE].MaxTextureImageUnits,
>                               st->state.samplers[PIPE_SHADER_COMPUTE],
>                               &st->state.num_samplers[PIPE_SHADER_COMPUTE]);
>     }
>  }
>
>
> -const struct st_tracked_state st_update_sampler = {
> -   update_samplers                                     /* update */
> +const struct st_tracked_state st_update_vertex_sampler = {
> +   update_vertex_samplers                              /* update */
> +};
> +
> +const struct st_tracked_state st_update_tessctrl_sampler = {
> +   update_tessctrl_samplers                            /* update */
> +};
> +
> +const struct st_tracked_state st_update_tesseval_sampler = {
> +   update_tesseval_samplers                            /* update */
> +};
> +
> +const struct st_tracked_state st_update_geometry_sampler = {
> +   update_geometry_samplers                            /* update */
> +};
> +
> +const struct st_tracked_state st_update_fragment_sampler = {
> +   update_fragment_samplers                            /* update */
> +};
> +
> +const struct st_tracked_state st_update_compute_sampler = {
> +   update_compute_samplers                             /* update */
>  };
> diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c
> index 4d9250b..0dc3b1e 100644
> --- a/src/mesa/state_tracker/st_program.c
> +++ b/src/mesa/state_tracker/st_program.c
> @@ -105,86 +105,86 @@ st_set_prog_affected_state_flags(struct gl_program *prog)
>     case MESA_SHADER_VERTEX:
>        states = &((struct st_vertex_program*)prog)->affected_states;
>
>        *states = ST_NEW_VS_STATE |
>                  ST_NEW_RASTERIZER |
>                  ST_NEW_VERTEX_ARRAYS;
>
>        set_affected_state_flags(states, prog,
>                                 ST_NEW_VS_CONSTANTS,
>                                 ST_NEW_VS_SAMPLER_VIEWS,
> -                               ST_NEW_RENDER_SAMPLERS,
> +                               ST_NEW_VS_SAMPLERS,
>                                 ST_NEW_VS_IMAGES,
>                                 ST_NEW_VS_UBOS,
>                                 ST_NEW_VS_SSBOS,
>                                 ST_NEW_VS_ATOMICS);
>        break;
>
>     case MESA_SHADER_TESS_CTRL:
>        states = &((struct st_tessctrl_program*)prog)->affected_states;
>
>        *states = ST_NEW_TCS_STATE;
>
>        set_affected_state_flags(states, prog,
>                                 ST_NEW_TCS_CONSTANTS,
>                                 ST_NEW_TCS_SAMPLER_VIEWS,
> -                               ST_NEW_RENDER_SAMPLERS,
> +                               ST_NEW_TCS_SAMPLERS,
>                                 ST_NEW_TCS_IMAGES,
>                                 ST_NEW_TCS_UBOS,
>                                 ST_NEW_TCS_SSBOS,
>                                 ST_NEW_TCS_ATOMICS);
>        break;
>
>     case MESA_SHADER_TESS_EVAL:
>        states = &((struct st_tesseval_program*)prog)->affected_states;
>
>        *states = ST_NEW_TES_STATE |
>                  ST_NEW_RASTERIZER;
>
>        set_affected_state_flags(states, prog,
>                                 ST_NEW_TES_CONSTANTS,
>                                 ST_NEW_TES_SAMPLER_VIEWS,
> -                               ST_NEW_RENDER_SAMPLERS,
> +                               ST_NEW_TES_SAMPLERS,
>                                 ST_NEW_TES_IMAGES,
>                                 ST_NEW_TES_UBOS,
>                                 ST_NEW_TES_SSBOS,
>                                 ST_NEW_TES_ATOMICS);
>        break;
>
>     case MESA_SHADER_GEOMETRY:
>        states = &((struct st_geometry_program*)prog)->affected_states;
>
>        *states = ST_NEW_GS_STATE |
>                  ST_NEW_RASTERIZER;
>
>        set_affected_state_flags(states, prog,
>                                 ST_NEW_GS_CONSTANTS,
>                                 ST_NEW_GS_SAMPLER_VIEWS,
> -                               ST_NEW_RENDER_SAMPLERS,
> +                               ST_NEW_GS_SAMPLERS,
>                                 ST_NEW_GS_IMAGES,
>                                 ST_NEW_GS_UBOS,
>                                 ST_NEW_GS_SSBOS,
>                                 ST_NEW_GS_ATOMICS);
>        break;
>
>     case MESA_SHADER_FRAGMENT:
>        states = &((struct st_fragment_program*)prog)->affected_states;
>
>        /* gl_FragCoord and glDrawPixels always use constants. */
>        *states = ST_NEW_FS_STATE |
>                  ST_NEW_SAMPLE_SHADING |
>                  ST_NEW_FS_CONSTANTS;
>
>        set_affected_state_flags(states, prog,
>                                 ST_NEW_FS_CONSTANTS,
>                                 ST_NEW_FS_SAMPLER_VIEWS,
> -                               ST_NEW_RENDER_SAMPLERS,
> +                               ST_NEW_FS_SAMPLERS,
>                                 ST_NEW_FS_IMAGES,
>                                 ST_NEW_FS_UBOS,
>                                 ST_NEW_FS_SSBOS,
>                                 ST_NEW_FS_ATOMICS);
>        break;
>
>     case MESA_SHADER_COMPUTE:
>        states = &((struct st_compute_program*)prog)->affected_states;
>
>        *states = ST_NEW_CS_STATE;
> @@ -747,26 +747,26 @@ st_translate_fragment_program(struct st_context *st,
>         *
>         * fragment.position and glDrawPixels always use constants.
>         */
>        stfp->affected_states = ST_NEW_FS_STATE |
>                                ST_NEW_SAMPLE_SHADING |
>                                ST_NEW_FS_CONSTANTS;
>
>        if (stfp->ati_fs) {
>           /* Just set them for ATI_fs unconditionally. */
>           stfp->affected_states |= ST_NEW_FS_SAMPLER_VIEWS |
> -                                  ST_NEW_RENDER_SAMPLERS;
> +                                  ST_NEW_FS_SAMPLERS;
>        } else {
>           /* ARB_fp */
>           if (stfp->Base.SamplersUsed)
>              stfp->affected_states |= ST_NEW_FS_SAMPLER_VIEWS |
> -                                     ST_NEW_RENDER_SAMPLERS;
> +                                     ST_NEW_FS_SAMPLERS;
>        }
>     }
>
>     /*
>      * Convert Mesa program inputs to TGSI input register semantics.
>      */
>     inputsRead = stfp->Base.info.inputs_read;
>     for (attr = 0; attr < VARYING_SLOT_MAX; attr++) {
>        if ((inputsRead & BITFIELD64_BIT(attr)) != 0) {
>           const GLuint slot = fs_num_inputs++;
> --
> 2.9.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