diff options
author | Jordan Justen <jordan.l.justen@intel.com> | 2014-12-30 08:41:29 +0000 |
---|---|---|
committer | Jordan Justen <jordan.l.justen@intel.com> | 2015-01-06 11:11:55 -0800 |
commit | 0da086c64e3a962a3e470e2e9fed421d97b148e4 (patch) | |
tree | 955bfc19aa3efadaafcfe89ff3bbd5d8fafad919 | |
parent | 934e41c0b31cffa4efc08f61cff2389e3149b3f3 (diff) |
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_state_upload.c | 57 |
1 files changed, 49 insertions, 8 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c index 7a25ef541b..b5d3f08702 100644 --- a/src/mesa/drivers/dri/i965/brw_state_upload.c +++ b/src/mesa/drivers/dri/i965/brw_state_upload.c @@ -37,6 +37,9 @@ #include "intel_batchbuffer.h" #include "intel_buffers.h" +static uint64_t mesa_flag_to_atoms[64] = { 0 }; +static uint64_t brw_flag_to_atoms[64] = { 0 }; + static const struct brw_tracked_state *gen4_atoms[] = { &brw_vs_prog, /* must do before GS prog, state base address. */ @@ -373,6 +376,7 @@ void brw_init_state( struct brw_context *brw ) num_atoms = ARRAY_SIZE(gen4_atoms); } + assert(num_atoms < 64); brw->atoms = atoms; brw->num_atoms = num_atoms; @@ -382,6 +386,20 @@ void brw_init_state( struct brw_context *brw ) atoms++; } + for (int i = 0; i < brw->num_atoms; i++) { + const struct brw_tracked_state *atom = brw->atoms[i]; + int f; + for (GLuint flags = atom->dirty.mesa; flags; flags &= ~(1ull << f)) { + f = ffs(flags) - 1; + mesa_flag_to_atoms[f] |= 1ull << i; + } + + for (uint64_t flags = atom->dirty.brw; flags; flags &= ~(1ull << f)) { + f = ffsll(flags) - 1; + brw_flag_to_atoms[f] |= 1ull << i; + } + } + brw_upload_initial_gpu_state(brw); brw->state.dirty.mesa = ~0; @@ -549,6 +567,25 @@ brw_print_dirty_count(struct dirty_bit_map *bit_map) } } +static uint64_t +get_dirty_atoms(struct brw_context *brw) +{ + struct brw_state_flags *state = &brw->state.dirty; + int f; + uint64_t dirty_atoms = 0; + for (GLuint flags = state->mesa; flags; flags &= ~(1ull << f)) { + f = ffs(flags) - 1; + dirty_atoms |= mesa_flag_to_atoms[f]; + } + + for (uint64_t flags = state->brw; flags; flags &= ~(1ull << f)) { + f = ffsll(flags) - 1; + dirty_atoms |= brw_flag_to_atoms[f]; + } + + return dirty_atoms; +} + /*********************************************************************** * Emit all state: */ @@ -626,14 +663,18 @@ void brw_upload_state(struct brw_context *brw) assert(!check_state(&examined, &generated)); prev = *state; } - } - else { - for (i = 0; i < brw->num_atoms; i++) { - const struct brw_tracked_state *atom = brw->atoms[i]; - - if (check_state(state, &atom->dirty)) { - atom->emit(brw); - } + } else { + uint64_t dirty_atoms = get_dirty_atoms(brw); + uint64_t emitted_atoms_mask = ~0ull; + struct brw_state_flags flags = *state; + while (dirty_atoms & emitted_atoms_mask) { + int a = ffsll(dirty_atoms & emitted_atoms_mask) - 1; + brw->atoms[a]->emit(brw); + emitted_atoms_mask &= ~(1ull << a); + if (unlikely(state->mesa != flags.mesa || state->brw != flags.brw)) { + dirty_atoms |= get_dirty_atoms(brw); + flags = *state; + } } } |