diff options
author | Marek Olšák <[email protected]> | 2012-09-10 04:06:20 +0200 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2012-09-13 20:18:44 +0200 |
commit | 3fe78594b1221358f4ba96072d952e33a7e54a76 (patch) | |
tree | cc693127cb02513bca3c205b1a1cb95755a46a0c /src/gallium/drivers/r600/r600_state.c | |
parent | 6c86124157da86ced9f9574ec49480f4abbd7e8c (diff) |
r600g: do fine-grained sampler state updates
Update only those sampler states which are changed in a shader stage,
instead of always updating all sampler states in the shader stage.
That requires keeping a bitmask of those states which are enabled, and those
states which are dirty at a given point (subset of enabled states).
This is similar to how sampler views, constant buffers, and vertex buffers
are handled.
Reviewed-by: Jerome Glisse <[email protected]>
Diffstat (limited to 'src/gallium/drivers/r600/r600_state.c')
-rw-r--r-- | src/gallium/drivers/r600/r600_state.c | 35 |
1 files changed, 20 insertions, 15 deletions
diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index a802d935aa2..1e2e43e3081 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -1932,42 +1932,47 @@ static void r600_emit_sampler_states(struct r600_context *rctx, unsigned border_color_reg) { struct radeon_winsys_cs *cs = rctx->cs; - unsigned i; + uint32_t dirty_mask = texinfo->states.dirty_mask; - for (i = 0; i < texinfo->n_samplers; i++) { + while (dirty_mask) { + struct r600_pipe_sampler_state *rstate; + struct r600_pipe_sampler_view *rview; + unsigned i = u_bit_scan(&dirty_mask); - if (texinfo->samplers[i] == NULL) { - continue; - } + rstate = texinfo->states.states[i]; + assert(rstate); + rview = texinfo->views.views[i]; /* TEX_ARRAY_OVERRIDE must be set for array textures to disable * filtering between layers. * Don't update TEX_ARRAY_OVERRIDE if we don't have the sampler view. */ - if (texinfo->views.views[i]) { - if (texinfo->views.views[i]->base.texture->target == PIPE_TEXTURE_1D_ARRAY || - texinfo->views.views[i]->base.texture->target == PIPE_TEXTURE_2D_ARRAY) { - texinfo->samplers[i]->tex_sampler_words[0] |= S_03C000_TEX_ARRAY_OVERRIDE(1); + if (rview) { + enum pipe_texture_target target = rview->base.texture->target; + if (target == PIPE_TEXTURE_1D_ARRAY || + target == PIPE_TEXTURE_2D_ARRAY) { + rstate->tex_sampler_words[0] |= S_03C000_TEX_ARRAY_OVERRIDE(1); texinfo->is_array_sampler[i] = true; } else { - texinfo->samplers[i]->tex_sampler_words[0] &= C_03C000_TEX_ARRAY_OVERRIDE; + rstate->tex_sampler_words[0] &= C_03C000_TEX_ARRAY_OVERRIDE; texinfo->is_array_sampler[i] = false; } } r600_write_value(cs, PKT3(PKT3_SET_SAMPLER, 3, 0)); r600_write_value(cs, (resource_id_base + i) * 3); - r600_write_array(cs, 3, texinfo->samplers[i]->tex_sampler_words); + r600_write_array(cs, 3, rstate->tex_sampler_words); - if (texinfo->samplers[i]->border_color_use) { + if (rstate->border_color_use) { unsigned offset; offset = border_color_reg; offset += i * 16; r600_write_config_reg_seq(cs, offset, 4); - r600_write_array(cs, 4, texinfo->samplers[i]->border_color); + r600_write_array(cs, 4, rstate->border_color); } } + texinfo->states.dirty_mask = 0; } static void r600_emit_vs_sampler_states(struct r600_context *rctx, struct r600_atom *atom) @@ -2025,8 +2030,8 @@ void r600_init_state_functions(struct r600_context *rctx) /* sampler must be emited before TA_CNTL_AUX otherwise DISABLE_CUBE_WRAP change * does not take effect (TA_CNTL_AUX emited by r600_emit_seamless_cube_map) */ - r600_init_atom(rctx, &rctx->vs_samplers.atom_sampler, id++, r600_emit_vs_sampler_states, 0); - r600_init_atom(rctx, &rctx->ps_samplers.atom_sampler, id++, r600_emit_ps_sampler_states, 0); + r600_init_atom(rctx, &rctx->vs_samplers.states.atom, id++, r600_emit_vs_sampler_states, 0); + r600_init_atom(rctx, &rctx->ps_samplers.states.atom, id++, r600_emit_ps_sampler_states, 0); /* resource */ r600_init_atom(rctx, &rctx->vs_samplers.views.atom, id++, r600_emit_vs_sampler_views, 0); r600_init_atom(rctx, &rctx->ps_samplers.views.atom, id++, r600_emit_ps_sampler_views, 0); |