[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