summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2017-06-10 23:12:25 +0200
committerMarek Olšák <[email protected]>2017-06-22 01:51:02 +0200
commit4d6fab245eec3880e2a59424a579851f44857ce8 (patch)
tree28bc3a24c0db8b436b8356f949db3156387cf18e
parentc8459846905bf7adfb6b5010a77aee9269228bdb (diff)
cso: don't track the number of sampler states bound
This removes 2 loops from hot codepaths and adds 1 loop to a rare codepath (restore_sampler_states), and makes sanitize_hash() slightly worse. Sampler states, when bound, are not unbound for draw calls that don't need them. That's OK, because bound sampler states don't add any overhead. This results in lower CPU overhead in most cases. Reviewed-by: Nicolai Hähnle <[email protected]>
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_context.c59
1 files changed, 23 insertions, 36 deletions
diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c
index 5558385e4c2..4947b8e1624 100644
--- a/src/gallium/auxiliary/cso_cache/cso_context.c
+++ b/src/gallium/auxiliary/cso_cache/cso_context.c
@@ -57,7 +57,6 @@ struct sampler_info
{
struct cso_sampler *cso_samplers[PIPE_MAX_SAMPLERS];
void *samplers[PIPE_MAX_SAMPLERS];
- unsigned nr_samplers;
};
@@ -83,6 +82,11 @@ struct cso_context {
struct sampler_info fragment_samplers_saved;
struct sampler_info samplers[PIPE_SHADER_TYPES];
+ /* Temporary number until cso_single_sampler_done is called.
+ * It tracks the highest sampler seen in cso_single_sampler.
+ */
+ int max_sampler_seen;
+
struct pipe_vertex_buffer aux_vertex_buffer_current;
struct pipe_vertex_buffer aux_vertex_buffer_saved;
unsigned aux_vertex_buffer_index;
@@ -240,7 +244,7 @@ sanitize_hash(struct cso_hash *hash, enum cso_cache_type type,
* table, to prevent them from being deleted
*/
for (i = 0; i < PIPE_SHADER_TYPES; i++) {
- for (j = 0; j < ctx->samplers[i].nr_samplers; j++) {
+ for (j = 0; j < PIPE_MAX_SAMPLERS; j++) {
struct cso_sampler *sampler = ctx->samplers[i].cso_samplers[j];
if (sampler && cso_hash_take(hash, sampler->hash_key))
@@ -334,6 +338,7 @@ cso_create_context(struct pipe_context *pipe, unsigned u_vbuf_flags)
ctx->has_streamout = TRUE;
}
+ ctx->max_sampler_seen = -1;
return ctx;
out:
@@ -1230,9 +1235,7 @@ cso_single_sampler(struct cso_context *ctx, enum pipe_shader_type shader_stage,
ctx->samplers[shader_stage].cso_samplers[idx] = cso;
ctx->samplers[shader_stage].samplers[idx] = cso->data;
- } else {
- ctx->samplers[shader_stage].cso_samplers[idx] = NULL;
- ctx->samplers[shader_stage].samplers[idx] = NULL;
+ ctx->max_sampler_seen = MAX2(ctx->max_sampler_seen, (int)idx);
}
return PIPE_OK;
@@ -1247,19 +1250,14 @@ cso_single_sampler_done(struct cso_context *ctx,
enum pipe_shader_type shader_stage)
{
struct sampler_info *info = &ctx->samplers[shader_stage];
- const unsigned old_nr_samplers = info->nr_samplers;
- unsigned i;
- /* find highest non-null sampler */
- for (i = PIPE_MAX_SAMPLERS; i > 0; i--) {
- if (info->samplers[i - 1] != NULL)
- break;
- }
+ if (ctx->max_sampler_seen == -1)
+ return;
- info->nr_samplers = i;
ctx->pipe->bind_sampler_states(ctx->pipe, shader_stage, 0,
- MAX2(old_nr_samplers, info->nr_samplers),
+ ctx->max_sampler_seen + 1,
info->samplers);
+ ctx->max_sampler_seen = -1;
}
@@ -1274,7 +1272,6 @@ cso_set_samplers(struct cso_context *ctx,
unsigned nr,
const struct pipe_sampler_state **templates)
{
- struct sampler_info *info = &ctx->samplers[shader_stage];
unsigned i;
enum pipe_error temp, error = PIPE_OK;
@@ -1284,12 +1281,6 @@ cso_set_samplers(struct cso_context *ctx,
error = temp;
}
- for ( ; i < info->nr_samplers; i++) {
- temp = cso_single_sampler(ctx, shader_stage, i, NULL);
- if (temp != PIPE_OK)
- error = temp;
- }
-
cso_single_sampler_done(ctx, shader_stage);
return error;
@@ -1301,11 +1292,9 @@ cso_save_fragment_samplers(struct cso_context *ctx)
struct sampler_info *info = &ctx->samplers[PIPE_SHADER_FRAGMENT];
struct sampler_info *saved = &ctx->fragment_samplers_saved;
- saved->nr_samplers = info->nr_samplers;
- memcpy(saved->cso_samplers, info->cso_samplers, info->nr_samplers *
- sizeof(*info->cso_samplers));
- memcpy(saved->samplers, info->samplers, info->nr_samplers *
- sizeof(*info->samplers));
+ memcpy(saved->cso_samplers, info->cso_samplers,
+ sizeof(info->cso_samplers));
+ memcpy(saved->samplers, info->samplers, sizeof(info->samplers));
}
@@ -1314,18 +1303,16 @@ cso_restore_fragment_samplers(struct cso_context *ctx)
{
struct sampler_info *info = &ctx->samplers[PIPE_SHADER_FRAGMENT];
struct sampler_info *saved = &ctx->fragment_samplers_saved;
- int delta = (int)info->nr_samplers - saved->nr_samplers;
memcpy(info->cso_samplers, saved->cso_samplers,
- saved->nr_samplers * sizeof(*info->cso_samplers));
- memcpy(info->samplers, saved->samplers,
- saved->nr_samplers * sizeof(*info->samplers));
-
- if (delta > 0) {
- memset(&info->cso_samplers[saved->nr_samplers], 0,
- delta * sizeof(*info->cso_samplers));
- memset(&info->samplers[saved->nr_samplers], 0,
- delta * sizeof(*info->samplers));
+ sizeof(info->cso_samplers));
+ memcpy(info->samplers, saved->samplers, sizeof(info->samplers));
+
+ for (int i = PIPE_MAX_SAMPLERS - 1; i >= 0; i--) {
+ if (info->samplers[i]) {
+ ctx->max_sampler_seen = i;
+ break;
+ }
}
cso_single_sampler_done(ctx, PIPE_SHADER_FRAGMENT);