[Mesa-dev] [PATCH 2/3] cso: don't send redundant sampler state changes to drivers

Brian Paul brianp at vmware.com
Thu Dec 10 13:08:35 PST 2015


One of the purposes of the CSO module is to filter out redundant
state changes from reaching the driver.  This was done for things
like blend state, depth/stencil state, shaders, etc, but not texture
samplers.

This eliminates a lot of redundant driver calls in some apps.
---
 src/gallium/auxiliary/cso_cache/cso_context.c | 38 +++++++++++++++++++++++++--
 1 file changed, 36 insertions(+), 2 deletions(-)

diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c
index 5db3d20..06089ad 100644
--- a/src/gallium/auxiliary/cso_cache/cso_context.c
+++ b/src/gallium/auxiliary/cso_cache/cso_context.c
@@ -89,7 +89,10 @@ struct cso_context {
    void *fragment_samplers_saved[PIPE_MAX_SAMPLERS];
    unsigned nr_fragment_samplers_saved;
 
+   /** Staged samplers not yet sent to driver */
    struct sampler_info samplers[PIPE_SHADER_TYPES];
+   /** Samplers last sent to the driver */
+   struct sampler_info hw_samplers[PIPE_SHADER_TYPES];
 
    struct pipe_vertex_buffer aux_vertex_buffer_current;
    struct pipe_vertex_buffer aux_vertex_buffer_saved;
@@ -160,6 +163,17 @@ static boolean delete_depth_stencil_state(struct cso_context *ctx, void *state)
 static boolean delete_sampler_state(struct cso_context *ctx, void *state)
 {
    struct cso_sampler *cso = (struct cso_sampler *)state;
+   unsigned sh, i;
+
+   /* Check that the sampler we're about to delete is not currently
+    * referenced anywhere.
+    */
+   for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
+      for (i = 0; i < ctx->samplers[sh].nr_samplers; i++) {
+         assert(ctx->samplers[sh].samplers[i] != state);
+      }
+   }
+
    if (cso->delete_state)
       cso->delete_state(cso->context, cso->data);
    FREE(state);
@@ -1130,6 +1144,7 @@ void
 cso_single_sampler_done(struct cso_context *ctx, unsigned shader_stage)
 {
    struct sampler_info *info = &ctx->samplers[shader_stage];
+   struct sampler_info *hw_info = &ctx->hw_samplers[shader_stage];
    unsigned i;
 
    /* find highest non-null sampler */
@@ -1139,8 +1154,27 @@ cso_single_sampler_done(struct cso_context *ctx, unsigned shader_stage)
    }
 
    info->nr_samplers = i;
-   ctx->pipe->bind_sampler_states(ctx->pipe, shader_stage, 0, i,
-                                  info->samplers);
+
+   /* check if there's really a change to send to the driver */
+   if (info->nr_samplers != hw_info->nr_samplers ||
+       memcmp(info->samplers, hw_info->samplers,
+              info->nr_samplers * sizeof(info->samplers[0]))) {
+      unsigned max_nr = MAX2(info->nr_samplers, hw_info->nr_samplers);
+
+      assert(max_nr > 0);
+
+      /* Null-out old sampler slots */
+      while (i < max_nr)
+         info->samplers[i++] = NULL;
+
+      /* send state change to driver */
+      ctx->pipe->bind_sampler_states(ctx->pipe, shader_stage, 0,
+                                     max_nr, info->samplers);
+
+      hw_info->nr_samplers = info->nr_samplers;
+      memcpy(hw_info->samplers, info->samplers,
+             info->nr_samplers * sizeof(info->samplers[0]));
+   }
 }
 
 
-- 
1.9.1



More information about the mesa-dev mailing list