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

Timothy Arceri tarceri at itsqueeze.com
Tue Apr 11 01:05:22 UTC 2017


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



More information about the mesa-dev mailing list