From: Marek Olšák Date: Wed, 14 Jun 2017 21:09:24 +0000 (+0200) Subject: st/mesa: don't set 16 scissors and 16 viewports if they're unused X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=743ad599a97d09b119d26b99f6b79e41b567e421;p=mesa.git st/mesa: don't set 16 scissors and 16 viewports if they're unused Only do so if there is a shader writing gl_ViewportIndex. This removes a lot of CPU overhead for the most common case. Reviewed-by: Nicolai Hähnle --- diff --git a/src/mesa/state_tracker/st_atom.c b/src/mesa/state_tracker/st_atom.c index bcfbcf878f0..253b5081640 100644 --- a/src/mesa/state_tracker/st_atom.c +++ b/src/mesa/state_tracker/st_atom.c @@ -76,6 +76,7 @@ static void check_program_state( struct st_context *st ) struct gl_program *new_gp = ctx->GeometryProgram._Current; struct gl_program *new_fp = ctx->FragmentProgram._Current; uint64_t dirty = 0; + unsigned num_viewports = 1; /* Flag states used by both new and old shaders to unbind shader resources * properly when transitioning to shaders that don't use them. @@ -115,6 +116,23 @@ static void check_program_state( struct st_context *st ) dirty |= st_fragment_program(new_fp)->affected_states; } + /* Find out the number of viewports. This determines how many scissors + * and viewport states we need to update. + */ + struct gl_program *last_prim_shader = new_gp ? new_gp : + new_tep ? new_tep : new_vp; + if (last_prim_shader && + last_prim_shader->info.outputs_written & VARYING_BIT_VIEWPORT) + num_viewports = ctx->Const.MaxViewports; + + if (st->state.num_viewports != num_viewports) { + st->state.num_viewports = num_viewports; + dirty |= ST_NEW_VIEWPORT; + + if (ctx->Scissor.EnableFlags & u_bit_consecutive(0, num_viewports)) + dirty |= ST_NEW_SCISSOR; + } + st->dirty |= dirty; } diff --git a/src/mesa/state_tracker/st_atom_scissor.c b/src/mesa/state_tracker/st_atom_scissor.c index ccd6e8ebd35..a87d02941ca 100644 --- a/src/mesa/state_tracker/st_atom_scissor.c +++ b/src/mesa/state_tracker/st_atom_scissor.c @@ -53,7 +53,7 @@ st_update_scissor( struct st_context *st ) unsigned i; bool changed = false; - for (i = 0 ; i < ctx->Const.MaxViewports; i++) { + for (i = 0 ; i < st->state.num_viewports; i++) { scissor[i].minx = 0; scissor[i].miny = 0; scissor[i].maxx = fb_width; @@ -95,8 +95,12 @@ st_update_scissor( struct st_context *st ) changed = true; } } - if (changed) - st->pipe->set_scissor_states(st->pipe, 0, ctx->Const.MaxViewports, scissor); /* activate */ + + if (changed) { + struct pipe_context *pipe = st->pipe; + + pipe->set_scissor_states(pipe, 0, st->state.num_viewports, scissor); + } } void diff --git a/src/mesa/state_tracker/st_atom_viewport.c b/src/mesa/state_tracker/st_atom_viewport.c index abf5faa0bc3..6e3347e7cfa 100644 --- a/src/mesa/state_tracker/st_atom_viewport.c +++ b/src/mesa/state_tracker/st_atom_viewport.c @@ -47,7 +47,7 @@ st_update_viewport( struct st_context *st ) /* _NEW_VIEWPORT */ - for (i = 0; i < ctx->Const.MaxViewports; i++) { + for (i = 0; i < st->state.num_viewports; i++) { float *scale = st->state.viewport[i].scale; float *translate = st->state.viewport[i].translate; @@ -62,6 +62,11 @@ st_update_viewport( struct st_context *st ) } cso_set_viewport(st->cso_context, &st->state.viewport[0]); - if (ctx->Const.MaxViewports > 1) - st->pipe->set_viewport_states(st->pipe, 1, ctx->Const.MaxViewports - 1, &st->state.viewport[1]); + + if (st->state.num_viewports > 1) { + struct pipe_context *pipe = st->pipe; + + pipe->set_viewport_states(pipe, 1, st->state.num_viewports - 1, + &st->state.viewport[1]); + } } diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index 2fe9d92e8bc..5c7c58d73f7 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -149,6 +149,7 @@ struct st_context unsigned fb_height; unsigned fb_num_samples; unsigned fb_num_layers; + unsigned num_viewports; struct pipe_scissor_state scissor[PIPE_MAX_VIEWPORTS]; struct pipe_viewport_state viewport[PIPE_MAX_VIEWPORTS]; struct {