summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2016-03-08 10:12:52 +1000
committerDave Airlie <airlied@redhat.com>2016-03-08 10:12:52 +1000
commit51e483830addb1ae870b30f4ebd2d0595ad404bf (patch)
treef203f7ecd42cd53b67feb5eb762ce8541b7c0a25
parent8aa342721d3f996dd1c31ec9e0802c58ea0ddfa0 (diff)
renderer: avoid looking up the same shader on every draw.
If we have a lot of draws we end up traversing the linked list looking for the same shader on each draw call even if the shader is the same one we used the last time. This removes a chunk of CPU overhead in the draw path.
-rw-r--r--src/vrend_renderer.c33
1 files changed, 25 insertions, 8 deletions
diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c
index ee45c23..247acd5 100644
--- a/src/vrend_renderer.c
+++ b/src/vrend_renderer.c
@@ -311,6 +311,7 @@ struct vrend_sub_context {
struct vrend_shader_selector *shaders[PIPE_SHADER_TYPES];
struct vrend_linked_shader_program *prog;
+ int prog_ids[PIPE_SHADER_TYPES];
struct vrend_shader_view views[PIPE_SHADER_TYPES];
struct vrend_constants consts[PIPE_SHADER_TYPES];
@@ -2733,6 +2734,7 @@ void vrend_draw_vbo(struct vrend_context *ctx,
struct vrend_linked_shader_program *prog;
bool fs_dirty, vs_dirty, gs_dirty;
bool dual_src = util_blend_state_is_dual(&ctx->sub->blend_state, 0);
+ bool same_prog;
if (!ctx->sub->shaders[PIPE_SHADER_VERTEX] || !ctx->sub->shaders[PIPE_SHADER_FRAGMENT]) {
fprintf(stderr,"dropping rendering due to missing shaders: %s\n", ctx->debug_name);
return;
@@ -2747,16 +2749,31 @@ void vrend_draw_vbo(struct vrend_context *ctx,
fprintf(stderr, "failure to compile shader variants: %s\n", ctx->debug_name);
return;
}
- prog = lookup_shader_program(ctx, ctx->sub->shaders[PIPE_SHADER_VERTEX]->current->id, ctx->sub->shaders[PIPE_SHADER_FRAGMENT]->current->id, ctx->sub->shaders[PIPE_SHADER_GEOMETRY] ? ctx->sub->shaders[PIPE_SHADER_GEOMETRY]->current->id : 0, dual_src);
- if (!prog) {
- prog = add_shader_program(ctx,
- ctx->sub->shaders[PIPE_SHADER_VERTEX]->current,
- ctx->sub->shaders[PIPE_SHADER_FRAGMENT]->current, ctx->sub->shaders[PIPE_SHADER_GEOMETRY] ? ctx->sub->shaders[PIPE_SHADER_GEOMETRY]->current : NULL);
- if (!prog)
- return;
- }
+ same_prog = true;
+ if (ctx->sub->shaders[PIPE_SHADER_VERTEX]->current->id != ctx->sub->prog_ids[PIPE_SHADER_VERTEX])
+ same_prog = false;
+ if (ctx->sub->shaders[PIPE_SHADER_FRAGMENT]->current->id != ctx->sub->prog_ids[PIPE_SHADER_FRAGMENT])
+ same_prog = false;
+ if (ctx->sub->shaders[PIPE_SHADER_GEOMETRY] && ctx->sub->shaders[PIPE_SHADER_FRAGMENT]->current->id != ctx->sub->prog_ids[PIPE_SHADER_FRAGMENT])
+ same_prog = false;
+
+ if (!same_prog) {
+ prog = lookup_shader_program(ctx, ctx->sub->shaders[PIPE_SHADER_VERTEX]->current->id, ctx->sub->shaders[PIPE_SHADER_FRAGMENT]->current->id, ctx->sub->shaders[PIPE_SHADER_GEOMETRY] ? ctx->sub->shaders[PIPE_SHADER_GEOMETRY]->current->id : 0, dual_src);
+ if (!prog) {
+ prog = add_shader_program(ctx,
+ ctx->sub->shaders[PIPE_SHADER_VERTEX]->current,
+ ctx->sub->shaders[PIPE_SHADER_FRAGMENT]->current, ctx->sub->shaders[PIPE_SHADER_GEOMETRY] ? ctx->sub->shaders[PIPE_SHADER_GEOMETRY]->current : NULL);
+ if (!prog)
+ return;
+ }
+ } else
+ prog = ctx->sub->prog;
if (ctx->sub->prog != prog) {
new_program = true;
+ ctx->sub->prog_ids[PIPE_SHADER_VERTEX] = ctx->sub->shaders[PIPE_SHADER_VERTEX]->current->id;
+ ctx->sub->prog_ids[PIPE_SHADER_FRAGMENT] = ctx->sub->shaders[PIPE_SHADER_FRAGMENT]->current->id;
+ if (ctx->sub->shaders[PIPE_SHADER_GEOMETRY])
+ ctx->sub->prog_ids[PIPE_SHADER_GEOMETRY] = ctx->sub->shaders[PIPE_SHADER_GEOMETRY]->current->id;
ctx->sub->prog = prog;
}
}